Merge from vscode 2f984aad710215f4e4684a035bb02f55d1a9e2cc (#9819)

This commit is contained in:
Anthony Dresser
2020-04-01 00:44:39 -07:00
committed by GitHub
parent 0e27aaa61f
commit 0bfbdc62ed
247 changed files with 5402 additions and 3311 deletions

View File

@@ -8,7 +8,7 @@ import { localize } from 'vs/nls';
import { IWorkspaceFolder, IWorkspace } from 'vs/platform/workspace/common/workspace';
import { URI, UriComponents } from 'vs/base/common/uri';
import { isWindows, isLinux, isMacintosh } from 'vs/base/common/platform';
import { extname } from 'vs/base/common/path';
import { extname, isAbsolute } from 'vs/base/common/path';
import { dirname, resolvePath, isEqualAuthority, isEqualOrParent, relativePath, extname as resourceExtname } from 'vs/base/common/resources';
import * as jsonEdit from 'vs/base/common/jsonEdit';
import * as json from 'vs/base/common/json';
@@ -18,7 +18,7 @@ import { toSlashes } from 'vs/base/common/extpath';
import { FormattingOptions } from 'vs/base/common/jsonFormatter';
import { getRemoteAuthority } from 'vs/platform/remote/common/remoteHosts';
import { ILogService } from 'vs/platform/log/common/log';
import { Event as CommonEvent } from 'vs/base/common/event';
import { Event } from 'vs/base/common/event';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
export const WORKSPACE_EXTENSION = 'code-workspace';
@@ -31,18 +31,21 @@ export interface IWorkspacesService {
_serviceBrand: undefined;
// Management
// Workspaces Management
enterWorkspace(path: URI): Promise<IEnterWorkspaceResult | null>;
createUntitledWorkspace(folders?: IWorkspaceFolderCreationData[], remoteAuthority?: string): Promise<IWorkspaceIdentifier>;
deleteUntitledWorkspace(workspace: IWorkspaceIdentifier): Promise<void>;
getWorkspaceIdentifier(workspacePath: URI): Promise<IWorkspaceIdentifier>;
// History
readonly onRecentlyOpenedChange: CommonEvent<void>;
// Workspaces History
readonly onRecentlyOpenedChange: Event<void>;
addRecentlyOpened(recents: IRecent[]): Promise<void>;
removeRecentlyOpened(workspaces: URI[]): Promise<void>;
clearRecentlyOpened(): Promise<void>;
getRecentlyOpened(): Promise<IRecentlyOpened>;
// Dirty Workspaces
getDirtyWorkspaces(): Promise<Array<IWorkspaceIdentifier | URI>>;
}
export interface IRecentlyOpened {
@@ -203,21 +206,22 @@ const SLASH = '/';
* Undefined is returned if the folderURI and the targetConfigFolderURI don't have the same schema or authority
*
* @param folderURI a workspace folder
* @param forceAbsolute if set, keep the path absolute
* @param folderName a workspace name
* @param targetConfigFolderURI the folder where the workspace is living in
* @param useSlashForPath if set, use forward slashes for file paths on windows
*/
export function getStoredWorkspaceFolder(folderURI: URI, folderName: string | undefined, targetConfigFolderURI: URI, useSlashForPath = !isWindows): IStoredWorkspaceFolder {
export function getStoredWorkspaceFolder(folderURI: URI, forceAbsolute: boolean, folderName: string | undefined, targetConfigFolderURI: URI, useSlashForPath = !isWindows): IStoredWorkspaceFolder {
if (folderURI.scheme !== targetConfigFolderURI.scheme) {
return { name: folderName, uri: folderURI.toString(true) };
}
let folderPath: string | undefined;
if (isEqualOrParent(folderURI, targetConfigFolderURI)) {
// use relative path
folderPath = relativePath(targetConfigFolderURI, folderURI) || '.'; // always uses forward slashes
if (isWindows && folderURI.scheme === Schemas.file && !useSlashForPath) {
let folderPath = !forceAbsolute ? relativePath(targetConfigFolderURI, folderURI) : undefined;
if (folderPath !== undefined) {
if (folderPath.length === 0) {
folderPath = '.';
} else if (isWindows && folderURI.scheme === Schemas.file && !useSlashForPath) {
// Windows gets special treatment:
// - use backslahes unless slash is used by other existing folders
folderPath = folderPath.replace(/\//g, '\\');
@@ -249,7 +253,7 @@ export function getStoredWorkspaceFolder(folderURI: URI, folderName: string | un
* Rewrites the content of a workspace file to be saved at a new location.
* Throws an exception if file is not a valid workspace file
*/
export function rewriteWorkspaceFileForNewLocation(rawWorkspaceContents: string, configPathURI: URI, targetConfigPathURI: URI) {
export function rewriteWorkspaceFileForNewLocation(rawWorkspaceContents: string, configPathURI: URI, isFromUntitledWorkspace: boolean, targetConfigPathURI: URI) {
let storedWorkspace = doParseStoredWorkspace(configPathURI, rawWorkspaceContents);
const sourceConfigFolder = dirname(configPathURI);
@@ -258,12 +262,17 @@ export function rewriteWorkspaceFileForNewLocation(rawWorkspaceContents: string,
const rewrittenFolders: IStoredWorkspaceFolder[] = [];
const slashForPath = useSlashForPath(storedWorkspace.folders);
// Rewrite absolute paths to relative paths if the target workspace folder
// is a parent of the location of the workspace file itself. Otherwise keep
// using absolute paths.
for (const folder of storedWorkspace.folders) {
let folderURI = isRawFileWorkspaceFolder(folder) ? resolvePath(sourceConfigFolder, folder.path) : URI.parse(folder.uri);
rewrittenFolders.push(getStoredWorkspaceFolder(folderURI, folder.name, targetConfigFolder, slashForPath));
const folderURI = isRawFileWorkspaceFolder(folder) ? resolvePath(sourceConfigFolder, folder.path) : URI.parse(folder.uri);
let absolute;
if (isFromUntitledWorkspace) {
// if it was an untitled workspace, try to make paths relative
absolute = false;
} else {
// for existing workspaces, preserve whether a path was absolute or relative
absolute = !isRawFileWorkspaceFolder(folder) || isAbsolute(folder.path);
}
rewrittenFolders.push(getStoredWorkspaceFolder(folderURI, absolute, folder.name, targetConfigFolder, slashForPath));
}
// Preserve as much of the existing workspace as possible by using jsonEdit

View File

@@ -9,7 +9,6 @@ import { IStateService } from 'vs/platform/state/node/state';
import { app, JumpListCategory } from 'electron';
import { ILogService } from 'vs/platform/log/common/log';
import { getBaseLabel, getPathLabel, splitName } from 'vs/base/common/labels';
import { IPath } from 'vs/platform/windows/common/windows';
import { Event as CommonEvent, Emitter } from 'vs/base/common/event';
import { isWindows, isMacintosh } from 'vs/base/common/platform';
import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, IRecentlyOpened, isRecentWorkspace, isRecentFolder, IRecent, isRecentFile, IRecentFolder, IRecentWorkspace, IRecentFile, toStoreData, restoreRecentlyOpened, RecentlyOpenedStorageData } from 'vs/platform/workspaces/common/workspaces';
@@ -24,6 +23,7 @@ import { exists } from 'vs/base/node/pfs';
import { ILifecycleMainService, LifecycleMainPhase } from 'vs/platform/lifecycle/electron-main/lifecycleMainService';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { Disposable } from 'vs/base/common/lifecycle';
import { ICodeWindow } from 'vs/platform/windows/electron-main/windows';
export const IWorkspacesHistoryMainService = createDecorator<IWorkspacesHistoryMainService>('workspacesHistoryMainService');
@@ -34,7 +34,7 @@ export interface IWorkspacesHistoryMainService {
readonly onRecentlyOpenedChange: CommonEvent<void>;
addRecentlyOpened(recents: IRecent[]): void;
getRecentlyOpened(currentWorkspace?: IWorkspaceIdentifier, currentFolder?: ISingleFolderWorkspaceIdentifier, currentFiles?: IPath[]): IRecentlyOpened;
getRecentlyOpened(include?: ICodeWindow): IRecentlyOpened;
removeRecentlyOpened(paths: URI[]): void;
clearRecentlyOpened(): void;
@@ -241,20 +241,23 @@ export class WorkspacesHistoryMainService extends Disposable implements IWorkspa
this._onRecentlyOpenedChange.fire();
}
getRecentlyOpened(currentWorkspace?: IWorkspaceIdentifier, currentFolder?: ISingleFolderWorkspaceIdentifier, currentFiles?: IPath[]): IRecentlyOpened {
getRecentlyOpened(include?: ICodeWindow): IRecentlyOpened {
const workspaces: Array<IRecentFolder | IRecentWorkspace> = [];
const files: IRecentFile[] = [];
// Add current workspace to beginning if set
const currentWorkspace = include?.config?.workspace;
if (currentWorkspace && !this.workspacesMainService.isUntitledWorkspace(currentWorkspace)) {
workspaces.push({ workspace: currentWorkspace });
}
const currentFolder = include?.config?.folderUri;
if (currentFolder) {
workspaces.push({ folderUri: currentFolder });
}
// Add currently files to open to the beginning if any
const currentFiles = include?.config?.filesToOpenOrCreate;
if (currentFiles) {
for (let currentFile of currentFiles) {
const fileUri = currentFile.fileUri;
@@ -402,14 +405,14 @@ function location(recent: IRecent): URI {
return recent.workspace.configPath;
}
function indexOfWorkspace(arr: IRecent[], workspace: IWorkspaceIdentifier): number {
return arrays.firstIndex(arr, w => isRecentWorkspace(w) && w.workspace.id === workspace.id);
function indexOfWorkspace(arr: IRecent[], candidate: IWorkspaceIdentifier): number {
return arr.findIndex(workspace => isRecentWorkspace(workspace) && workspace.workspace.id === candidate.id);
}
function indexOfFolder(arr: IRecent[], folderURI: ISingleFolderWorkspaceIdentifier): number {
return arrays.firstIndex(arr, f => isRecentFolder(f) && areResourcesEqual(f.folderUri, folderURI));
function indexOfFolder(arr: IRecent[], candidate: ISingleFolderWorkspaceIdentifier): number {
return arr.findIndex(folder => isRecentFolder(folder) && areResourcesEqual(folder.folderUri, candidate));
}
function indexOfFile(arr: IRecentFile[], fileURI: URI): number {
return arrays.firstIndex(arr, f => areResourcesEqual(f.fileUri, fileURI));
function indexOfFile(arr: IRecentFile[], candidate: URI): number {
return arr.findIndex(file => areResourcesEqual(file.fileUri, candidate));
}

View File

@@ -175,7 +175,7 @@ export class WorkspacesMainService extends Disposable implements IWorkspacesMain
const storedWorkspaceFolder: IStoredWorkspaceFolder[] = [];
for (const folder of folders) {
storedWorkspaceFolder.push(getStoredWorkspaceFolder(folder.uri, folder.name, untitledWorkspaceConfigFolder));
storedWorkspaceFolder.push(getStoredWorkspaceFolder(folder.uri, true, folder.name, untitledWorkspaceConfigFolder));
}
return {

View File

@@ -9,6 +9,7 @@ import { URI } from 'vs/base/common/uri';
import { IWorkspacesMainService } from 'vs/platform/workspaces/electron-main/workspacesMainService';
import { IWindowsMainService } from 'vs/platform/windows/electron-main/windows';
import { IWorkspacesHistoryMainService } from 'vs/platform/workspaces/electron-main/workspacesHistoryMainService';
import { IBackupMainService } from 'vs/platform/backup/electron-main/backup';
export class WorkspacesService implements AddFirstParameterToFunctions<IWorkspacesService, Promise<unknown> /* only methods, not events */, number /* window ID */> {
@@ -17,7 +18,8 @@ export class WorkspacesService implements AddFirstParameterToFunctions<IWorkspac
constructor(
@IWorkspacesMainService private readonly workspacesMainService: IWorkspacesMainService,
@IWindowsMainService private readonly windowsMainService: IWindowsMainService,
@IWorkspacesHistoryMainService private readonly workspacesHistoryMainService: IWorkspacesHistoryMainService
@IWorkspacesHistoryMainService private readonly workspacesHistoryMainService: IWorkspacesHistoryMainService,
@IBackupMainService private readonly backupMainService: IBackupMainService
) {
}
@@ -51,12 +53,7 @@ export class WorkspacesService implements AddFirstParameterToFunctions<IWorkspac
readonly onRecentlyOpenedChange = this.workspacesHistoryMainService.onRecentlyOpenedChange;
async getRecentlyOpened(windowId: number): Promise<IRecentlyOpened> {
const window = this.windowsMainService.getWindowById(windowId);
if (window?.config) {
return this.workspacesHistoryMainService.getRecentlyOpened(window.config.workspace, window.config.folderUri, window.config.filesToOpenOrCreate);
}
return this.workspacesHistoryMainService.getRecentlyOpened();
return this.workspacesHistoryMainService.getRecentlyOpened(this.windowsMainService.getWindowById(windowId));
}
async addRecentlyOpened(windowId: number, recents: IRecent[]): Promise<void> {
@@ -72,4 +69,13 @@ export class WorkspacesService implements AddFirstParameterToFunctions<IWorkspac
}
//#endregion
//#region Dirty Workspaces
async getDirtyWorkspaces(): Promise<Array<IWorkspaceIdentifier | URI>> {
return this.backupMainService.getDirtyWorkspaces();
}
//#endregion
}

View File

@@ -11,7 +11,7 @@ import * as pfs from 'vs/base/node/pfs';
import { EnvironmentService } from 'vs/platform/environment/node/environmentService';
import { parseArgs, OPTIONS } from 'vs/platform/environment/node/argv';
import { WorkspacesMainService, IStoredWorkspace } from 'vs/platform/workspaces/electron-main/workspacesMainService';
import { WORKSPACE_EXTENSION, IRawFileWorkspaceFolder, IWorkspaceFolderCreationData, IRawUriWorkspaceFolder, rewriteWorkspaceFileForNewLocation, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { WORKSPACE_EXTENSION, IRawFileWorkspaceFolder, IWorkspaceFolderCreationData, IRawUriWorkspaceFolder, rewriteWorkspaceFileForNewLocation, IWorkspaceIdentifier, IStoredWorkspaceFolder } from 'vs/platform/workspaces/common/workspaces';
import { NullLogService } from 'vs/platform/log/common/log';
import { URI } from 'vs/base/common/uri';
import { getRandomTestPath } from 'vs/base/test/node/testUtils';
@@ -56,6 +56,7 @@ export class TestDialogMainService implements IDialogMainService {
}
export class TestBackupMainService implements IBackupMainService {
_serviceBrand: undefined;
isHotExitEnabled(): boolean {
@@ -97,6 +98,10 @@ export class TestBackupMainService implements IBackupMainService {
unregisterEmptyWindowBackupSync(backupFolder: string): void {
throw new Error('Method not implemented.');
}
async getDirtyWorkspaces(): Promise<(IWorkspaceIdentifier | URI)[]> {
return [];
}
}
suite('WorkspacesMainService', () => {
@@ -109,11 +114,27 @@ suite('WorkspacesMainService', () => {
}
}
function createWorkspace(folders: string[], names?: string[]) {
function createUntitledWorkspace(folders: string[], names?: string[]) {
return service.createUntitledWorkspace(folders.map((folder, index) => ({ uri: URI.file(folder), name: names ? names[index] : undefined } as IWorkspaceFolderCreationData)));
}
function createWorkspaceSync(folders: string[], names?: string[]) {
function createWorkspace(workspaceConfigPath: string, folders: (string | URI)[], names?: string[]): void {
const ws: IStoredWorkspace = {
folders: []
};
for (let i = 0; i < folders.length; i++) {
const f = folders[i];
const s: IStoredWorkspaceFolder = f instanceof URI ? { uri: f.toString() } : { path: f };
if (names) {
s.name = names[i];
}
ws.folders.push(s);
}
fs.writeFileSync(workspaceConfigPath, JSON.stringify(ws));
}
function createUntitledWorkspaceSync(folders: string[], names?: string[]) {
return service.createUntitledWorkspaceSync(folders.map((folder, index) => ({ uri: URI.file(folder), name: names ? names[index] : undefined } as IWorkspaceFolderCreationData)));
}
@@ -149,7 +170,7 @@ suite('WorkspacesMainService', () => {
}
test('createWorkspace (folders)', async () => {
const workspace = await createWorkspace([process.cwd(), os.tmpdir()]);
const workspace = await createUntitledWorkspace([process.cwd(), os.tmpdir()]);
assert.ok(workspace);
assert.ok(fs.existsSync(workspace.configPath.fsPath));
assert.ok(service.isUntitledWorkspace(workspace));
@@ -163,7 +184,7 @@ suite('WorkspacesMainService', () => {
});
test('createWorkspace (folders with name)', async () => {
const workspace = await createWorkspace([process.cwd(), os.tmpdir()], ['currentworkingdirectory', 'tempdir']);
const workspace = await createUntitledWorkspace([process.cwd(), os.tmpdir()], ['currentworkingdirectory', 'tempdir']);
assert.ok(workspace);
assert.ok(fs.existsSync(workspace.configPath.fsPath));
assert.ok(service.isUntitledWorkspace(workspace));
@@ -195,7 +216,7 @@ suite('WorkspacesMainService', () => {
});
test('createWorkspaceSync (folders)', () => {
const workspace = createWorkspaceSync([process.cwd(), os.tmpdir()]);
const workspace = createUntitledWorkspaceSync([process.cwd(), os.tmpdir()]);
assert.ok(workspace);
assert.ok(fs.existsSync(workspace.configPath.fsPath));
assert.ok(service.isUntitledWorkspace(workspace));
@@ -210,7 +231,7 @@ suite('WorkspacesMainService', () => {
});
test('createWorkspaceSync (folders with names)', () => {
const workspace = createWorkspaceSync([process.cwd(), os.tmpdir()], ['currentworkingdirectory', 'tempdir']);
const workspace = createUntitledWorkspaceSync([process.cwd(), os.tmpdir()], ['currentworkingdirectory', 'tempdir']);
assert.ok(workspace);
assert.ok(fs.existsSync(workspace.configPath.fsPath));
assert.ok(service.isUntitledWorkspace(workspace));
@@ -243,7 +264,7 @@ suite('WorkspacesMainService', () => {
});
test('resolveWorkspaceSync', async () => {
const workspace = await createWorkspace([process.cwd(), os.tmpdir()]);
const workspace = await createUntitledWorkspace([process.cwd(), os.tmpdir()]);
assert.ok(service.resolveLocalWorkspaceSync(workspace.configPath));
// make it a valid workspace path
@@ -262,7 +283,7 @@ suite('WorkspacesMainService', () => {
});
test('resolveWorkspaceSync (support relative paths)', async () => {
const workspace = await createWorkspace([process.cwd(), os.tmpdir()]);
const workspace = await createUntitledWorkspace([process.cwd(), os.tmpdir()]);
fs.writeFileSync(workspace.configPath.fsPath, JSON.stringify({ folders: [{ path: './ticino-playground/lib' }] }));
const resolved = service.resolveLocalWorkspaceSync(workspace.configPath);
@@ -270,7 +291,7 @@ suite('WorkspacesMainService', () => {
});
test('resolveWorkspaceSync (support relative paths #2)', async () => {
const workspace = await createWorkspace([process.cwd(), os.tmpdir()]);
const workspace = await createUntitledWorkspace([process.cwd(), os.tmpdir()]);
fs.writeFileSync(workspace.configPath.fsPath, JSON.stringify({ folders: [{ path: './ticino-playground/lib/../other' }] }));
const resolved = service.resolveLocalWorkspaceSync(workspace.configPath);
@@ -278,7 +299,7 @@ suite('WorkspacesMainService', () => {
});
test('resolveWorkspaceSync (support relative paths #3)', async () => {
const workspace = await createWorkspace([process.cwd(), os.tmpdir()]);
const workspace = await createUntitledWorkspace([process.cwd(), os.tmpdir()]);
fs.writeFileSync(workspace.configPath.fsPath, JSON.stringify({ folders: [{ path: 'ticino-playground/lib' }] }));
const resolved = service.resolveLocalWorkspaceSync(workspace.configPath);
@@ -286,7 +307,7 @@ suite('WorkspacesMainService', () => {
});
test('resolveWorkspaceSync (support invalid JSON via fault tolerant parsing)', async () => {
const workspace = await createWorkspace([process.cwd(), os.tmpdir()]);
const workspace = await createUntitledWorkspace([process.cwd(), os.tmpdir()]);
fs.writeFileSync(workspace.configPath.fsPath, '{ "folders": [ { "path": "./ticino-playground/lib" } , ] }'); // trailing comma
const resolved = service.resolveLocalWorkspaceSync(workspace.configPath);
@@ -296,14 +317,15 @@ suite('WorkspacesMainService', () => {
test('rewriteWorkspaceFileForNewLocation', async () => {
const folder1 = process.cwd(); // absolute path because outside of tmpDir
const tmpDir = os.tmpdir();
const tmpInsideDir = path.join(os.tmpdir(), 'inside');
const tmpInsideDir = path.join(tmpDir, 'inside');
const workspace = await createWorkspace([folder1, tmpInsideDir, path.join(tmpInsideDir, 'somefolder')]);
const origContent = fs.readFileSync(workspace.configPath.fsPath).toString();
const firstConfigPath = path.join(tmpDir, 'myworkspace0.code-workspace');
createWorkspace(firstConfigPath, [folder1, 'inside', path.join('inside', 'somefolder')]);
const origContent = fs.readFileSync(firstConfigPath).toString();
let origConfigPath = workspace.configPath;
let origConfigPath = URI.file(firstConfigPath);
let workspaceConfigPath = URI.file(path.join(tmpDir, 'inside', 'myworkspace1.code-workspace'));
let newContent = rewriteWorkspaceFileForNewLocation(origContent, origConfigPath, workspaceConfigPath);
let newContent = rewriteWorkspaceFileForNewLocation(origContent, origConfigPath, false, workspaceConfigPath);
let ws = (JSON.parse(newContent) as IStoredWorkspace);
assert.equal(ws.folders.length, 3);
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[0]).path, folder1); // absolute path because outside of tmpdir
@@ -312,7 +334,7 @@ suite('WorkspacesMainService', () => {
origConfigPath = workspaceConfigPath;
workspaceConfigPath = URI.file(path.join(tmpDir, 'myworkspace2.code-workspace'));
newContent = rewriteWorkspaceFileForNewLocation(newContent, origConfigPath, workspaceConfigPath);
newContent = rewriteWorkspaceFileForNewLocation(newContent, origConfigPath, false, workspaceConfigPath);
ws = (JSON.parse(newContent) as IStoredWorkspace);
assert.equal(ws.folders.length, 3);
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[0]).path, folder1);
@@ -321,51 +343,51 @@ suite('WorkspacesMainService', () => {
origConfigPath = workspaceConfigPath;
workspaceConfigPath = URI.file(path.join(tmpDir, 'other', 'myworkspace2.code-workspace'));
newContent = rewriteWorkspaceFileForNewLocation(newContent, origConfigPath, workspaceConfigPath);
newContent = rewriteWorkspaceFileForNewLocation(newContent, origConfigPath, false, workspaceConfigPath);
ws = (JSON.parse(newContent) as IStoredWorkspace);
assert.equal(ws.folders.length, 3);
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[0]).path, folder1);
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[1]).path, tmpInsideDir);
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[2]).path, path.join(tmpInsideDir, 'somefolder'));
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[1]).path, isWindows ? '..\\inside' : '../inside');
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[2]).path, isWindows ? '..\\inside\\somefolder' : '../inside/somefolder');
origConfigPath = workspaceConfigPath;
workspaceConfigPath = URI.parse('foo://foo/bar/myworkspace2.code-workspace');
newContent = rewriteWorkspaceFileForNewLocation(newContent, origConfigPath, workspaceConfigPath);
newContent = rewriteWorkspaceFileForNewLocation(newContent, origConfigPath, false, workspaceConfigPath);
ws = (JSON.parse(newContent) as IStoredWorkspace);
assert.equal(ws.folders.length, 3);
assert.equal((<IRawUriWorkspaceFolder>ws.folders[0]).uri, URI.file(folder1).toString(true));
assert.equal((<IRawUriWorkspaceFolder>ws.folders[1]).uri, URI.file(tmpInsideDir).toString(true));
assert.equal((<IRawUriWorkspaceFolder>ws.folders[2]).uri, URI.file(path.join(tmpInsideDir, 'somefolder')).toString(true));
service.deleteUntitledWorkspaceSync(workspace);
fs.unlinkSync(firstConfigPath);
});
test('rewriteWorkspaceFileForNewLocation (preserves comments)', async () => {
const workspace = await createWorkspace([process.cwd(), os.tmpdir(), path.join(os.tmpdir(), 'somefolder')]);
const workspace = await createUntitledWorkspace([process.cwd(), os.tmpdir(), path.join(os.tmpdir(), 'somefolder')]);
const workspaceConfigPath = URI.file(path.join(os.tmpdir(), `myworkspace.${Date.now()}.${WORKSPACE_EXTENSION}`));
let origContent = fs.readFileSync(workspace.configPath.fsPath).toString();
origContent = `// this is a comment\n${origContent}`;
let newContent = rewriteWorkspaceFileForNewLocation(origContent, workspace.configPath, workspaceConfigPath);
let newContent = rewriteWorkspaceFileForNewLocation(origContent, workspace.configPath, false, workspaceConfigPath);
assert.equal(0, newContent.indexOf('// this is a comment'));
service.deleteUntitledWorkspaceSync(workspace);
});
test('rewriteWorkspaceFileForNewLocation (preserves forward slashes)', async () => {
const workspace = await createWorkspace([process.cwd(), os.tmpdir(), path.join(os.tmpdir(), 'somefolder')]);
const workspace = await createUntitledWorkspace([process.cwd(), os.tmpdir(), path.join(os.tmpdir(), 'somefolder')]);
const workspaceConfigPath = URI.file(path.join(os.tmpdir(), `myworkspace.${Date.now()}.${WORKSPACE_EXTENSION}`));
let origContent = fs.readFileSync(workspace.configPath.fsPath).toString();
origContent = origContent.replace(/[\\]/g, '/'); // convert backslash to slash
const newContent = rewriteWorkspaceFileForNewLocation(origContent, workspace.configPath, workspaceConfigPath);
const newContent = rewriteWorkspaceFileForNewLocation(origContent, workspace.configPath, false, workspaceConfigPath);
const ws = (JSON.parse(newContent) as IStoredWorkspace);
assert.ok(ws.folders.every(f => (<IRawFileWorkspaceFolder>f).path.indexOf('\\') < 0));
service.deleteUntitledWorkspaceSync(workspace);
});
test('rewriteWorkspaceFileForNewLocation (unc paths)', async () => {
test.skip('rewriteWorkspaceFileForNewLocation (unc paths)', async () => {
if (!isWindows) {
return Promise.resolve();
}
@@ -375,10 +397,10 @@ suite('WorkspacesMainService', () => {
const folder2Location = '\\\\server\\share2\\some\\path';
const folder3Location = path.join(os.tmpdir(), 'wsloc', 'inner', 'more');
const workspace = await createWorkspace([folder1Location, folder2Location, folder3Location]);
const workspace = await createUntitledWorkspace([folder1Location, folder2Location, folder3Location]);
const workspaceConfigPath = URI.file(path.join(workspaceLocation, `myworkspace.${Date.now()}.${WORKSPACE_EXTENSION}`));
let origContent = fs.readFileSync(workspace.configPath.fsPath).toString();
const newContent = rewriteWorkspaceFileForNewLocation(origContent, workspace.configPath, workspaceConfigPath);
const newContent = rewriteWorkspaceFileForNewLocation(origContent, workspace.configPath, false, workspaceConfigPath);
const ws = (JSON.parse(newContent) as IStoredWorkspace);
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[0]).path, folder1Location);
assertPathEquals((<IRawFileWorkspaceFolder>ws.folders[1]).path, folder2Location);
@@ -388,14 +410,14 @@ suite('WorkspacesMainService', () => {
});
test('deleteUntitledWorkspaceSync (untitled)', async () => {
const workspace = await createWorkspace([process.cwd(), os.tmpdir()]);
const workspace = await createUntitledWorkspace([process.cwd(), os.tmpdir()]);
assert.ok(fs.existsSync(workspace.configPath.fsPath));
service.deleteUntitledWorkspaceSync(workspace);
assert.ok(!fs.existsSync(workspace.configPath.fsPath));
});
test('deleteUntitledWorkspaceSync (saved)', async () => {
const workspace = await createWorkspace([process.cwd(), os.tmpdir()]);
const workspace = await createUntitledWorkspace([process.cwd(), os.tmpdir()]);
service.deleteUntitledWorkspaceSync(workspace);
});
@@ -405,14 +427,14 @@ suite('WorkspacesMainService', () => {
let untitled = service.getUntitledWorkspacesSync();
assert.equal(untitled.length, 0);
const untitledOne = await createWorkspace([process.cwd(), os.tmpdir()]);
const untitledOne = await createUntitledWorkspace([process.cwd(), os.tmpdir()]);
assert.ok(fs.existsSync(untitledOne.configPath.fsPath));
untitled = service.getUntitledWorkspacesSync();
assert.equal(1, untitled.length);
assert.equal(untitledOne.id, untitled[0].workspace.id);
const untitledTwo = await createWorkspace([os.tmpdir(), process.cwd()]);
const untitledTwo = await createUntitledWorkspace([os.tmpdir(), process.cwd()]);
assert.ok(fs.existsSync(untitledTwo.configPath.fsPath));
assert.ok(fs.existsSync(untitledOne.configPath.fsPath), `Unexpected workspaces count of 1 (expected 2): ${untitledOne.configPath.fsPath} does not exist anymore?`);
const untitledHome = dirname(dirname(untitledTwo.configPath));