diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index 1713016ae3c..b4ded396bc9 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -24,6 +24,7 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { KeyboardLayoutMonitor } from 'vs/code/electron-main/keyboard'; import { isLinux, isMacintosh, isWindows } from 'vs/base/common/platform'; import { ICodeWindow } from "vs/platform/windows/electron-main/windows"; +import { IWorkspace } from "vs/platform/workspaces/common/workspaces"; export interface IWindowState { width?: number; @@ -264,8 +265,8 @@ export class CodeWindow implements ICodeWindow { return this.currentConfig ? this.currentConfig.backupPath : void 0; } - public get openedWorkspaceConfigPath(): string { - return this.currentConfig ? this.currentConfig.workspaceConfigPath : void 0; + public get openedWorkspace(): IWorkspace { + return this.currentConfig ? this.currentConfig.workspace : void 0; } public get openedFolderPath(): string { diff --git a/src/vs/code/electron-main/windows.ts b/src/vs/code/electron-main/windows.ts index 6e37c92ae77..6c537a5027f 100644 --- a/src/vs/code/electron-main/windows.ts +++ b/src/vs/code/electron-main/windows.ts @@ -29,7 +29,7 @@ import { IWindowsMainService, IOpenConfiguration } from "vs/platform/windows/ele import { IHistoryMainService } from "vs/platform/history/electron-main/historyMainService"; import { IProcessEnvironment, isLinux, isMacintosh, isWindows } from 'vs/base/common/platform'; import { TPromise } from "vs/base/common/winjs.base"; -import { IWorkspacesMainService } from "vs/platform/workspaces/common/workspaces"; +import { IWorkspacesMainService, IWorkspace } from "vs/platform/workspaces/common/workspaces"; enum WindowError { UNRESPONSIVE, @@ -45,7 +45,7 @@ interface ILegacyWindowState extends IWindowState { } interface IWindowState { - workspaceConfigPath?: string; + workspace?: IWorkspace; folderPath?: string; backupPath: string; uiState: ISingleWindowState; @@ -67,7 +67,7 @@ interface IOpenBrowserWindowOptions { userEnv?: IProcessEnvironment; cli?: ParsedArgs; - workspaceConfigPath?: string; + workspace?: IWorkspace; folderPath?: string; initialStartup?: boolean; @@ -84,8 +84,8 @@ interface IOpenBrowserWindowOptions { interface IWindowToOpen extends IPath { - // the workspace config path for a Code instance to open - workspaceConfigPath?: string; + // the workspace for a Code instance to open + workspace?: IWorkspace; // the folder path for a Code instance to open folderPath?: string; @@ -261,9 +261,9 @@ export class WindowsManager implements IWindowsMainService { } // Any non extension host window with same workspace or folder - else if (!win.isExtensionDevelopmentHost && (!!win.openedWorkspaceConfigPath || !!win.openedFolderPath)) { + else if (!win.isExtensionDevelopmentHost && (!!win.openedWorkspace || !!win.openedFolderPath)) { this.windowsState.openedWindows.forEach(o => { - const sameWorkspace = win.openedWorkspaceConfigPath && isEqual(o.workspaceConfigPath, win.openedWorkspaceConfigPath, !isLinux /* ignorecase */); + const sameWorkspace = win.openedWorkspace && o.workspace.id === win.openedWorkspace.id; const sameFolder = win.openedFolderPath && isEqual(o.folderPath, win.openedFolderPath, !isLinux /* ignorecase */); if (sameWorkspace || sameFolder) { @@ -283,7 +283,7 @@ export class WindowsManager implements IWindowsMainService { private toWindowState(win: CodeWindow): IWindowState { return { - workspaceConfigPath: win.openedWorkspaceConfigPath, + workspace: win.openedWorkspace, folderPath: win.openedFolderPath, backupPath: win.backupPath, uiState: win.serializeWindowState() @@ -307,7 +307,7 @@ export class WindowsManager implements IWindowsMainService { // // These are windows to open to show workspaces // - const workspacesToOpen = arrays.distinct(windowsToOpen.filter(win => !!win.workspaceConfigPath).map(win => win.workspaceConfigPath), workspaceConfigPath => isLinux ? workspaceConfigPath : workspaceConfigPath.toLowerCase()); // prevent duplicates + const workspacesToOpen = arrays.distinct(windowsToOpen.filter(win => !!win.workspace).map(win => win.workspace), workspace => workspace.id); // prevent duplicates // // These are windows to open to show either folders or files (including diffing files or creating them) @@ -319,15 +319,15 @@ export class WindowsManager implements IWindowsMainService { // const hotExitRestore = (openConfig.initialStartup && !openConfig.cli.extensionDevelopmentPath); const foldersToRestore = hotExitRestore ? this.backupService.getFolderBackupPaths() : []; - const workspacesToRestore = hotExitRestore ? this.backupService.getWorkspaceBackupPaths() : []; + const workspacesToRestore = hotExitRestore ? this.backupService.getWorkspaceBackups() : []; let emptyToRestore = hotExitRestore ? this.backupService.getEmptyWindowBackupPaths() : []; - emptyToRestore.push(...windowsToOpen.filter(w => !w.workspaceConfigPath && !w.folderPath && w.backupPath).map(w => path.basename(w.backupPath))); // add empty windows with backupPath + emptyToRestore.push(...windowsToOpen.filter(w => !w.workspace && !w.folderPath && w.backupPath).map(w => path.basename(w.backupPath))); // add empty windows with backupPath emptyToRestore = arrays.distinct(emptyToRestore); // prevent duplicates // // These are empty windows to open // - const emptyToOpen = windowsToOpen.filter(win => !win.workspaceConfigPath && !win.folderPath && !win.filePath && !win.backupPath).length; + const emptyToOpen = windowsToOpen.filter(win => !win.workspace && !win.folderPath && !win.filePath && !win.backupPath).length; // Open based on config const usedWindows = this.doOpen(openConfig, workspacesToOpen, workspacesToRestore, foldersToOpen, foldersToRestore, emptyToRestore, emptyToOpen, filesToOpen, filesToCreate, filesToDiff); @@ -373,8 +373,8 @@ export class WindowsManager implements IWindowsMainService { private doOpen( openConfig: IOpenConfiguration, - workspacesToOpen: string[], - workspacesToRestore: string[], + workspacesToOpen: IWorkspace[], + workspacesToRestore: IWorkspace[], foldersToOpen: string[], foldersToRestore: string[], emptyToRestore: string[], @@ -433,7 +433,7 @@ export class WindowsManager implements IWindowsMainService { } // Handle workspaces to open (instructed and to restore) - const allWorkspacesToOpen = arrays.distinct([...workspacesToOpen, ...workspacesToRestore], workspace => isLinux ? workspace : workspace.toLowerCase()); // prevent duplicates + const allWorkspacesToOpen = arrays.distinct([...workspacesToOpen, ...workspacesToRestore], workspace => workspace.id); // prevent duplicates if (allWorkspacesToOpen.length > 0) { // Check for existing instances @@ -454,12 +454,12 @@ export class WindowsManager implements IWindowsMainService { // Open remaining ones allWorkspacesToOpen.forEach(workspaceToOpen => { - if (windowsOnWorkspace.some(win => isEqual(win.openedWorkspaceConfigPath, workspaceToOpen, !isLinux /* ignorecase */))) { + if (windowsOnWorkspace.some(win => win.openedWorkspace.id === workspaceToOpen.id)) { return; // ignore folders that are already open } // Do open folder - usedWindows.push(this.doOpenFolderOrWorkspace(openConfig, { workspaceConfigPath: workspaceToOpen }, openFolderInNewWindow, filesToOpen, filesToCreate, filesToDiff)); + usedWindows.push(this.doOpenFolderOrWorkspace(openConfig, { workspace: workspaceToOpen }, openFolderInNewWindow, filesToOpen, filesToCreate, filesToDiff)); // Reset these because we handled them filesToOpen = []; @@ -564,7 +564,7 @@ export class WindowsManager implements IWindowsMainService { userEnv: openConfig.userEnv, cli: openConfig.cli, initialStartup: openConfig.initialStartup, - workspaceConfigPath: folderOrWorkspace.workspaceConfigPath, + workspace: folderOrWorkspace.workspace, folderPath: folderOrWorkspace.folderPath, filesToOpen, filesToCreate, @@ -658,12 +658,16 @@ export class WindowsManager implements IWindowsMainService { case 'one': if (lastActiveWindow) { - // return workspace/folder path if it is valid - const workspaceOrFolder = lastActiveWindow.workspaceConfigPath || lastActiveWindow.folderPath; - if (workspaceOrFolder) { - const validatedWorkspaceOrFolder = this.parsePath(workspaceOrFolder); - if (validatedWorkspaceOrFolder) { - return [validatedWorkspaceOrFolder]; + // workspace + if (lastActiveWindow.workspace) { + return [{ workspace: lastActiveWindow.workspace }]; + } + + // folder (if path is valid) + else if (lastActiveWindow.folderPath) { + const validatedFolder = this.parsePath(lastActiveWindow.folderPath); + if (validatedFolder) { + return [validatedFolder]; } } @@ -678,20 +682,26 @@ export class WindowsManager implements IWindowsMainService { // folders: restore last opened folders only case 'all': case 'folders': + const windowsToOpen: IWindowToOpen[] = []; - // Windows with Workspaces/Folders - const lastOpenedWorkspacesOrFolders = this.windowsState.openedWindows.filter(w => !!w.workspaceConfigPath || !!w.folderPath).map(o => o.workspaceConfigPath || o.folderPath); - const lastActiveWorkspaceOrFolder = lastActiveWindow && (lastActiveWindow.workspaceConfigPath || lastActiveWindow.folderPath); - if (lastActiveWorkspaceOrFolder) { - lastOpenedWorkspacesOrFolders.push(lastActiveWorkspaceOrFolder); + // Workspaces + const workspaces = this.windowsState.openedWindows.filter(w => !!w.workspace).map(w => w.workspace); + if (lastActiveWindow && lastActiveWindow.workspace) { + workspaces.push(lastActiveWindow.workspace); } + windowsToOpen.push(...workspaces.map(workspace => ({ workspace }))); - const windowsToOpen = lastOpenedWorkspacesOrFolders.map(candidate => this.parsePath(candidate)).filter(path => !!path); + // Folders + const folders = this.windowsState.openedWindows.filter(w => !!w.folderPath).map(w => w.folderPath); + if (lastActiveWindow && lastActiveWindow.folderPath) { + folders.push(lastActiveWindow.folderPath); + } + windowsToOpen.push(...folders.map(candidate => this.parsePath(candidate)).filter(path => !!path)); // Windows that were Empty if (restoreWindows === 'all') { - const lastOpenedEmpty = this.windowsState.openedWindows.filter(w => !w.workspaceConfigPath && !w.folderPath && w.backupPath).map(w => w.backupPath); - const lastActiveEmpty = lastActiveWindow && !lastActiveWindow.workspaceConfigPath && !lastActiveWindow.folderPath && lastActiveWindow.backupPath; + const lastOpenedEmpty = this.windowsState.openedWindows.filter(w => !w.workspace && !w.folderPath && w.backupPath).map(w => w.backupPath); + const lastActiveEmpty = lastActiveWindow && !lastActiveWindow.workspace && !lastActiveWindow.folderPath && lastActiveWindow.backupPath; if (lastActiveEmpty) { lastOpenedEmpty.push(lastActiveEmpty); } @@ -745,13 +755,17 @@ export class WindowsManager implements IWindowsMainService { try { const candidateStat = fs.statSync(candidate); if (candidateStat) { - - // File / Workspace if (candidateStat.isFile()) { - const isWorkspaceConfig = this.workspacesService.isWorkspace(candidate); + + // Workspace + const workspace = this.workspacesService.resolveWorkspaceSync(candidate); + if (workspace) { + return { workspace }; + } + + // File return { - workspaceConfigPath: isWorkspaceConfig ? candidate : void 0, - filePath: !isWorkspaceConfig ? candidate : void 0, + filePath: candidate, lineNumber: gotoLineMode ? parsedPath.line : void 0, columnNumber: gotoLineMode ? parsedPath.column : void 0 }; @@ -843,7 +857,7 @@ export class WindowsManager implements IWindowsMainService { configuration.execPath = process.execPath; configuration.userEnv = assign({}, this.initialUserEnv, options.userEnv || {}); configuration.isInitialStartup = options.initialStartup; - configuration.workspaceConfigPath = options.workspaceConfigPath; + configuration.workspace = options.workspace; configuration.folderPath = options.folderPath; configuration.filesToOpen = options.filesToOpen; configuration.filesToCreate = options.filesToCreate; @@ -932,8 +946,8 @@ export class WindowsManager implements IWindowsMainService { // Register window for backups if (!configuration.extensionDevelopmentPath) { - if (configuration.workspaceConfigPath) { - configuration.backupPath = this.backupService.registerWorkspaceBackupSync(configuration.workspaceConfigPath); + if (configuration.workspace) { + configuration.backupPath = this.backupService.registerWorkspaceBackupSync(configuration.workspace); } else if (configuration.folderPath) { configuration.backupPath = this.backupService.registerFolderBackupSync(configuration.folderPath); } else { @@ -957,8 +971,8 @@ export class WindowsManager implements IWindowsMainService { } // Known Workspace - load from stored settings - if (configuration.workspaceConfigPath) { - const stateForWorkspace = this.windowsState.openedWindows.filter(o => isEqual(o.workspaceConfigPath, configuration.workspaceConfigPath, !isLinux /* ignorecase */)).map(o => o.uiState); + if (configuration.workspace) { + const stateForWorkspace = this.windowsState.openedWindows.filter(o => o.workspace && o.workspace.id === configuration.workspace.id).map(o => o.uiState); if (stateForWorkspace.length) { return stateForWorkspace[0]; } diff --git a/src/vs/code/node/windowsFinder.ts b/src/vs/code/node/windowsFinder.ts index 6537b863f05..5b08b76aab8 100644 --- a/src/vs/code/node/windowsFinder.ts +++ b/src/vs/code/node/windowsFinder.ts @@ -10,9 +10,10 @@ import * as fs from 'fs'; import * as platform from 'vs/base/common/platform'; import * as paths from 'vs/base/common/paths'; import { OpenContext } from 'vs/platform/windows/common/windows'; +import { IWorkspace } from "vs/platform/workspaces/common/workspaces"; export interface ISimpleWindow { - openedWorkspaceConfigPath?: string; + openedWorkspace?: IWorkspace; openedFolderPath?: string; openedFilePath?: string; extensionDevelopmentPath?: string; @@ -126,12 +127,12 @@ export function findWindowOnFolder(windows: W[], folder return null; } -export function findWindowOnWorkspace(windows: W[], workspaceConfigPath: string): W { +export function findWindowOnWorkspace(windows: W[], workspace: IWorkspace): W { if (windows.length) { const res = windows.filter(w => { // match on workspace - if (typeof w.openedWorkspaceConfigPath === 'string' && (paths.isEqual(w.openedWorkspaceConfigPath, workspaceConfigPath, !platform.isLinux /* ignorecase */))) { + if (w.openedWorkspace && w.openedWorkspace.id === workspace.id) { return true; } diff --git a/src/vs/platform/backup/common/backup.ts b/src/vs/platform/backup/common/backup.ts index 008cb66b0e3..8cac70ab77b 100644 --- a/src/vs/platform/backup/common/backup.ts +++ b/src/vs/platform/backup/common/backup.ts @@ -4,9 +4,10 @@ *--------------------------------------------------------------------------------------------*/ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { IWorkspace } from "vs/platform/workspaces/common/workspaces"; export interface IBackupWorkspacesFormat { - rootWorkspaces: string[]; + rootWorkspaces: IWorkspace[]; folderWorkspaces: string[]; emptyWorkspaces: string[]; } @@ -16,11 +17,11 @@ export const IBackupMainService = createDecorator('backupMai export interface IBackupMainService { _serviceBrand: any; - getWorkspaceBackupPaths(): string[]; + getWorkspaceBackups(): IWorkspace[]; getFolderBackupPaths(): string[]; getEmptyWindowBackupPaths(): string[]; - registerWorkspaceBackupSync(workspaceConfigPath: string): string; + registerWorkspaceBackupSync(workspace: IWorkspace): string; registerFolderBackupSync(folderPath: string): string; registerEmptyWindowBackupSync(backupFolder?: string): string; } \ No newline at end of file diff --git a/src/vs/platform/backup/electron-main/backupMainService.ts b/src/vs/platform/backup/electron-main/backupMainService.ts index 717d46625f6..c84e5487b01 100644 --- a/src/vs/platform/backup/electron-main/backupMainService.ts +++ b/src/vs/platform/backup/electron-main/backupMainService.ts @@ -14,6 +14,7 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment' import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IFilesConfiguration, HotExitConfiguration } from 'vs/platform/files/common/files'; import { ILogService } from "vs/platform/log/common/log"; +import { IWorkspace } from "vs/platform/workspaces/common/workspaces"; export class BackupMainService implements IBackupMainService { @@ -35,7 +36,7 @@ export class BackupMainService implements IBackupMainService { this.loadSync(); } - public getWorkspaceBackupPaths(): string[] { + public getWorkspaceBackups(): IWorkspace[] { if (this.isHotExitOnExitAndWindowClose()) { // Only non-folder windows are restored on main process launch when // hot exit is configured as onExitAndWindowClose. @@ -63,16 +64,16 @@ export class BackupMainService implements IBackupMainService { return this.backups.emptyWorkspaces.slice(0); // return a copy } - public registerWorkspaceBackupSync(workspaceConfigPath: string): string { - this.pushBackupPathsSync(workspaceConfigPath, this.backups.rootWorkspaces); + public registerWorkspaceBackupSync(workspace: IWorkspace): string { + this.pushBackupPathsSync(workspace, this.backups.rootWorkspaces); - return path.join(this.backupHome, this.getWorkspaceHash(workspaceConfigPath)); + return path.join(this.backupHome, workspace.id); } public registerFolderBackupSync(folderPath: string): string { this.pushBackupPathsSync(folderPath, this.backups.folderWorkspaces); - return path.join(this.backupHome, this.getWorkspaceHash(folderPath)); + return path.join(this.backupHome, this.getFolderHash(folderPath)); } public registerEmptyWindowBackupSync(backupFolder?: string): string { @@ -87,16 +88,14 @@ export class BackupMainService implements IBackupMainService { return path.join(this.backupHome, backupFolder); } - private pushBackupPathsSync(workspaceIdentifier: string, target: string[]): string { + private pushBackupPathsSync(workspaceIdentifier: string | IWorkspace, target: (string | IWorkspace)[]): void { if (this.indexOf(workspaceIdentifier, target) === -1) { target.push(workspaceIdentifier); this.saveSync(); } - - return workspaceIdentifier; } - protected removeBackupPathSync(workspaceIdentifier: string, target: string[]): void { + protected removeBackupPathSync(workspaceIdentifier: string | IWorkspace, target: (string | IWorkspace)[]): void { if (!target) { return; } @@ -108,14 +107,22 @@ export class BackupMainService implements IBackupMainService { this.saveSync(); } - private indexOf(workspaceIdentifier: string, target: string[]): number { + private indexOf(workspaceIdentifier: string | IWorkspace, target: (string | IWorkspace)[]): number { if (!target) { return -1; } - const sanitizedWorkspaceIdentifier = this.sanitizePath(workspaceIdentifier); + const sanitizedWorkspaceIdentifier = this.sanitizeId(workspaceIdentifier); - return arrays.firstIndex(target, id => this.sanitizePath(id) === sanitizedWorkspaceIdentifier); + return arrays.firstIndex(target, id => this.sanitizeId(id) === sanitizedWorkspaceIdentifier); + } + + private sanitizeId(workspaceIdentifier: string | IWorkspace): string { + if (typeof workspaceIdentifier === 'string') { + return this.sanitizePath(workspaceIdentifier); + } + + return workspaceIdentifier.id; } protected loadSync(): void { @@ -126,10 +133,10 @@ export class BackupMainService implements IBackupMainService { backups = Object.create(null); } - // Ensure rootWorkspaces is a string[] + // Ensure rootWorkspaces is a object[] if (backups.rootWorkspaces) { const rws = backups.rootWorkspaces; - if (!Array.isArray(rws) || rws.some(r => typeof r !== 'string')) { + if (!Array.isArray(rws) || rws.some(r => typeof r !== 'object')) { backups.rootWorkspaces = []; } } else { @@ -167,31 +174,34 @@ export class BackupMainService implements IBackupMainService { // De-duplicate folder/workspace backups. don't worry about cleaning them up any duplicates as // they will be removed when there are no backups. backups.folderWorkspaces = arrays.distinct(backups.folderWorkspaces, ws => this.sanitizePath(ws)); - backups.rootWorkspaces = arrays.distinct(backups.rootWorkspaces, ws => this.sanitizePath(ws)); + backups.rootWorkspaces = arrays.distinct(backups.rootWorkspaces, ws => this.sanitizePath(ws.id)); return backups; } private validateBackupWorkspaces(backups: IBackupWorkspacesFormat): void { - const staleBackupWorkspaces: { workspaceIdentifier: string; backupPath: string; target: string[] }[] = []; + const staleBackupWorkspaces: { workspaceIdentifier: string | IWorkspace; backupPath: string; target: (string | IWorkspace)[] }[] = []; - const workspaceAndFolders: { path: string, target: string[] }[] = []; - workspaceAndFolders.push(...backups.rootWorkspaces.map(r => ({ path: r, target: backups.rootWorkspaces }))); - workspaceAndFolders.push(...backups.folderWorkspaces.map(f => ({ path: f, target: backups.folderWorkspaces }))); + const workspaceAndFolders: { workspaceIdentifier: string | IWorkspace, target: (string | IWorkspace)[] }[] = []; + workspaceAndFolders.push(...backups.rootWorkspaces.map(r => ({ workspaceIdentifier: r, target: backups.rootWorkspaces }))); + workspaceAndFolders.push(...backups.folderWorkspaces.map(f => ({ workspaceIdentifier: f, target: backups.folderWorkspaces }))); // Validate Workspace and Folder Backups workspaceAndFolders.forEach(workspaceOrFolder => { - const backupPath = path.join(this.backupHome, this.getWorkspaceHash(workspaceOrFolder.path)); + const workspaceId = workspaceOrFolder.workspaceIdentifier; + const workspacePath = typeof workspaceId === 'string' ? workspaceId : workspaceId.configPath; + const backupPath = path.join(this.backupHome, typeof workspaceId === 'string' ? this.getFolderHash(workspaceId) : workspaceId.id); const hasBackups = this.hasBackupsSync(backupPath); - const missingWorkspace = hasBackups && !fs.existsSync(workspaceOrFolder.path); + const missingWorkspace = hasBackups && !fs.existsSync(workspacePath); // If the workspace/folder has no backups, make sure to delete it // If the workspace/folder has backups, but the target workspace is missing, convert backups to empty ones if (!hasBackups || missingWorkspace) { - staleBackupWorkspaces.push({ workspaceIdentifier: workspaceOrFolder.path, backupPath, target: workspaceOrFolder.target }); + staleBackupWorkspaces.push({ workspaceIdentifier: workspaceId, backupPath, target: workspaceOrFolder.target }); if (missingWorkspace) { - const identifier = this.pushBackupPathsSync(this.getRandomEmptyWindowId(), this.backups.emptyWorkspaces); + const identifier = this.getRandomEmptyWindowId(); + this.pushBackupPathsSync(identifier, this.backups.emptyWorkspaces); const newEmptyWindowBackupPath = path.join(path.dirname(backupPath), identifier); try { fs.renameSync(backupPath, newEmptyWindowBackupPath); @@ -265,7 +275,7 @@ export class BackupMainService implements IBackupMainService { return platform.isLinux ? p : p.toLowerCase(); } - protected getWorkspaceHash(workspacePath: string): string { - return crypto.createHash('md5').update(this.sanitizePath(workspacePath)).digest('hex'); + protected getFolderHash(folderPath: string): string { + return crypto.createHash('md5').update(this.sanitizePath(folderPath)).digest('hex'); } } diff --git a/src/vs/platform/backup/test/electron-main/backupMainService.test.ts b/src/vs/platform/backup/test/electron-main/backupMainService.test.ts index 83ff3e7599e..36675695023 100644 --- a/src/vs/platform/backup/test/electron-main/backupMainService.test.ts +++ b/src/vs/platform/backup/test/electron-main/backupMainService.test.ts @@ -20,6 +20,8 @@ import { IBackupWorkspacesFormat } from 'vs/platform/backup/common/backup'; import { HotExitConfiguration } from 'vs/platform/files/common/files'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { LogMainService } from "vs/platform/log/common/log"; +import { IWorkspace } from "vs/platform/workspaces/common/workspaces"; +import { createHash } from "crypto"; class TestBackupMainService extends BackupMainService { @@ -37,8 +39,8 @@ class TestBackupMainService extends BackupMainService { return this.backups; } - public removeBackupPathSync(workspaceIdenfitier: string, target: string[]): void { - return super.removeBackupPathSync(workspaceIdenfitier, target); + public removeBackupPathSync(workspaceIdentifier: string | IWorkspace, target: (string | IWorkspace)[]): void { + return super.removeBackupPathSync(workspaceIdentifier, target); } public loadSync(): void { @@ -50,14 +52,26 @@ class TestBackupMainService extends BackupMainService { } public toBackupPath(workspacePath: string): string { - return path.join(this.backupHome, super.getWorkspaceHash(workspacePath)); + return path.join(this.backupHome, super.getFolderHash(workspacePath)); } - public getWorkspaceHash(workspacePath: string): string { - return super.getWorkspaceHash(workspacePath); + public getFolderHash(folderPath: string): string { + return super.getFolderHash(folderPath); } } +function toWorkspace(path: string): IWorkspace { + return { + id: createHash('md5').update(sanitizePath(path)).digest('hex'), + configPath: path, + folders: [] + }; +} + +function sanitizePath(p: string): string { + return platform.isLinux ? p : p.toLowerCase(); +} + suite('BackupMainService', () => { const parentDir = path.join(os.tmpdir(), 'vsctests', 'service'); const backupHome = path.join(parentDir, 'Backups'); @@ -135,18 +149,18 @@ suite('BackupMainService', () => { test('service validates backup workspaces on startup and cleans up (root workspaces)', done => { // 1) backup workspace path does not exist - service.registerWorkspaceBackupSync(fooFile.fsPath); - service.registerWorkspaceBackupSync(barFile.fsPath); + service.registerWorkspaceBackupSync(toWorkspace(fooFile.fsPath)); + service.registerWorkspaceBackupSync(toWorkspace(barFile.fsPath)); service.loadSync(); - assert.deepEqual(service.getWorkspaceBackupPaths(), []); + assert.deepEqual(service.getWorkspaceBackups(), []); // 2) backup workspace path exists with empty contents within fs.mkdirSync(service.toBackupPath(fooFile.fsPath)); fs.mkdirSync(service.toBackupPath(barFile.fsPath)); - service.registerWorkspaceBackupSync(fooFile.fsPath); - service.registerWorkspaceBackupSync(barFile.fsPath); + service.registerWorkspaceBackupSync(toWorkspace(fooFile.fsPath)); + service.registerWorkspaceBackupSync(toWorkspace(barFile.fsPath)); service.loadSync(); - assert.deepEqual(service.getWorkspaceBackupPaths(), []); + assert.deepEqual(service.getWorkspaceBackups(), []); assert.ok(!fs.exists(service.toBackupPath(fooFile.fsPath))); assert.ok(!fs.exists(service.toBackupPath(barFile.fsPath))); @@ -155,10 +169,10 @@ suite('BackupMainService', () => { fs.mkdirSync(service.toBackupPath(barFile.fsPath)); fs.mkdirSync(path.join(service.toBackupPath(fooFile.fsPath), 'file')); fs.mkdirSync(path.join(service.toBackupPath(barFile.fsPath), 'untitled')); - service.registerWorkspaceBackupSync(fooFile.fsPath); - service.registerWorkspaceBackupSync(barFile.fsPath); + service.registerWorkspaceBackupSync(toWorkspace(fooFile.fsPath)); + service.registerWorkspaceBackupSync(toWorkspace(barFile.fsPath)); service.loadSync(); - assert.deepEqual(service.getWorkspaceBackupPaths(), []); + assert.deepEqual(service.getWorkspaceBackups(), []); assert.ok(!fs.exists(service.toBackupPath(fooFile.fsPath))); assert.ok(!fs.exists(service.toBackupPath(barFile.fsPath))); @@ -168,12 +182,12 @@ suite('BackupMainService', () => { fs.mkdirSync(service.toBackupPath(fooFile.fsPath)); fs.mkdirSync(service.toBackupPath(barFile.fsPath)); fs.mkdirSync(fileBackups); - service.registerWorkspaceBackupSync(fooFile.fsPath); - assert.equal(service.getWorkspaceBackupPaths().length, 1); + service.registerWorkspaceBackupSync(toWorkspace(fooFile.fsPath)); + assert.equal(service.getWorkspaceBackups().length, 1); assert.equal(service.getEmptyWindowBackupPaths().length, 0); fs.writeFileSync(path.join(fileBackups, 'backup.txt'), ''); service.loadSync(); - assert.equal(service.getWorkspaceBackupPaths().length, 0); + assert.equal(service.getWorkspaceBackups().length, 0); assert.equal(service.getEmptyWindowBackupPaths().length, 1); done(); @@ -231,55 +245,56 @@ suite('BackupMainService', () => { assert.deepEqual(service.getFolderBackupPaths(), []); }); - test('getWorkspaceBackupPaths() should return [] when workspaces.json doesn\'t exist', () => { - assert.deepEqual(service.getWorkspaceBackupPaths(), []); + test('getWorkspaceBackups() should return [] when workspaces.json doesn\'t exist', () => { + assert.deepEqual(service.getWorkspaceBackups(), []); }); - test('getWorkspaceBackupPaths() should return [] when workspaces.json is not properly formed JSON', () => { + test('getWorkspaceBackups() should return [] when workspaces.json is not properly formed JSON', () => { fs.writeFileSync(backupWorkspacesPath, ''); service.loadSync(); - assert.deepEqual(service.getWorkspaceBackupPaths(), []); + assert.deepEqual(service.getWorkspaceBackups(), []); fs.writeFileSync(backupWorkspacesPath, '{]'); service.loadSync(); - assert.deepEqual(service.getWorkspaceBackupPaths(), []); + assert.deepEqual(service.getWorkspaceBackups(), []); fs.writeFileSync(backupWorkspacesPath, 'foo'); service.loadSync(); - assert.deepEqual(service.getWorkspaceBackupPaths(), []); + assert.deepEqual(service.getWorkspaceBackups(), []); }); - test('getWorkspaceBackupPaths() should return [] when folderWorkspaces in workspaces.json is absent', () => { + test('getWorkspaceBackups() should return [] when folderWorkspaces in workspaces.json is absent', () => { fs.writeFileSync(backupWorkspacesPath, '{}'); service.loadSync(); - assert.deepEqual(service.getWorkspaceBackupPaths(), []); + assert.deepEqual(service.getWorkspaceBackups(), []); }); - test('getWorkspaceBackupPaths() should return [] when rootWorkspaces in workspaces.json is not a string array', () => { + test('getWorkspaceBackups() should return [] when rootWorkspaces in workspaces.json is not a object array', () => { fs.writeFileSync(backupWorkspacesPath, '{"rootWorkspaces":{}}'); service.loadSync(); - assert.deepEqual(service.getWorkspaceBackupPaths(), []); + assert.deepEqual(service.getWorkspaceBackups(), []); fs.writeFileSync(backupWorkspacesPath, '{"rootWorkspaces":{"foo": ["bar"]}}'); service.loadSync(); - assert.deepEqual(service.getWorkspaceBackupPaths(), []); + assert.deepEqual(service.getWorkspaceBackups(), []); fs.writeFileSync(backupWorkspacesPath, '{"rootWorkspaces":{"foo": []}}'); service.loadSync(); - assert.deepEqual(service.getWorkspaceBackupPaths(), []); + assert.deepEqual(service.getWorkspaceBackups(), []); fs.writeFileSync(backupWorkspacesPath, '{"rootWorkspaces":{"foo": "bar"}}'); service.loadSync(); - assert.deepEqual(service.getWorkspaceBackupPaths(), []); + assert.deepEqual(service.getWorkspaceBackups(), []); fs.writeFileSync(backupWorkspacesPath, '{"rootWorkspaces":"foo"}'); service.loadSync(); - assert.deepEqual(service.getWorkspaceBackupPaths(), []); + assert.deepEqual(service.getWorkspaceBackups(), []); fs.writeFileSync(backupWorkspacesPath, '{"rootWorkspaces":1}'); service.loadSync(); - assert.deepEqual(service.getWorkspaceBackupPaths(), []); + assert.deepEqual(service.getWorkspaceBackups(), []); }); - test('getWorkspaceBackupPaths() should return [] when files.hotExit = "onExitAndWindowClose"', () => { - service.registerWorkspaceBackupSync(fooFile.fsPath.toUpperCase()); - assert.deepEqual(service.getWorkspaceBackupPaths(), [fooFile.fsPath.toUpperCase()]); + test('getWorkspaceBackups() should return [] when files.hotExit = "onExitAndWindowClose"', () => { + service.registerWorkspaceBackupSync(toWorkspace(fooFile.fsPath.toUpperCase())); + assert.equal(service.getWorkspaceBackups().length, 1); + assert.deepEqual(service.getWorkspaceBackups().map(r => r.configPath), [fooFile.fsPath.toUpperCase()]); configService.setUserConfiguration('files.hotExit', HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE); service.loadSync(); - assert.deepEqual(service.getWorkspaceBackupPaths(), []); + assert.deepEqual(service.getWorkspaceBackups(), []); }); test('getEmptyWorkspaceBackupPaths() should return [] when workspaces.json doesn\'t exist', () => { @@ -356,7 +371,7 @@ suite('BackupMainService', () => { } const backups: IBackupWorkspacesFormat = { - rootWorkspaces: platform.isWindows ? ['c:\\FOO', 'C:\\FOO', 'c:\\foo'] : ['/FOO', '/foo'], + rootWorkspaces: platform.isWindows ? [toWorkspace('c:\\FOO'), toWorkspace('C:\\FOO'), toWorkspace('c:\\foo')] : [toWorkspace('/FOO'), toWorkspace('/foo')], folderWorkspaces: [], emptyWorkspaces: [] }; @@ -365,9 +380,9 @@ suite('BackupMainService', () => { assert.equal(backups.rootWorkspaces.length, 1); if (platform.isWindows) { - assert.deepEqual(backups.rootWorkspaces, ['c:\\FOO'], 'should return the first duplicated entry'); + assert.deepEqual(backups.rootWorkspaces.map(r => r.configPath), ['c:\\FOO'], 'should return the first duplicated entry'); } else { - assert.deepEqual(backups.rootWorkspaces, ['/FOO'], 'should return the first duplicated entry'); + assert.deepEqual(backups.rootWorkspaces.map(r => r.configPath), ['/FOO'], 'should return the first duplicated entry'); } }); }); @@ -385,12 +400,22 @@ suite('BackupMainService', () => { }); test('should persist paths to workspaces.json (root workspace)', done => { - service.registerWorkspaceBackupSync(fooFile.fsPath); - service.registerWorkspaceBackupSync(barFile.fsPath); - assert.deepEqual(service.getWorkspaceBackupPaths(), [fooFile.fsPath, barFile.fsPath]); + const ws1 = toWorkspace(fooFile.fsPath); + service.registerWorkspaceBackupSync(ws1); + const ws2 = toWorkspace(barFile.fsPath); + service.registerWorkspaceBackupSync(ws2); + + assert.deepEqual(service.getWorkspaceBackups().map(b => b.configPath), [fooFile.fsPath, barFile.fsPath]); + assert.equal(ws1.id, service.getWorkspaceBackups()[0].id); + assert.equal(ws2.id, service.getWorkspaceBackups()[1].id); + pfs.readFile(backupWorkspacesPath, 'utf-8').then(buffer => { const json = JSON.parse(buffer); - assert.deepEqual(json.rootWorkspaces, [fooFile.fsPath, barFile.fsPath]); + + assert.deepEqual(json.rootWorkspaces.map(b => b.configPath), [fooFile.fsPath, barFile.fsPath]); + assert.equal(ws1.id, json.rootWorkspaces[0].id); + assert.equal(ws2.id, json.rootWorkspaces[1].id); + done(); }); }); @@ -406,11 +431,11 @@ suite('BackupMainService', () => { }); test('should always store the workspace path in workspaces.json using the case given, regardless of whether the file system is case-sensitive (root workspace)', done => { - service.registerWorkspaceBackupSync(fooFile.fsPath.toUpperCase()); - assert.deepEqual(service.getWorkspaceBackupPaths(), [fooFile.fsPath.toUpperCase()]); + service.registerWorkspaceBackupSync(toWorkspace(fooFile.fsPath.toUpperCase())); + assert.deepEqual(service.getWorkspaceBackups().map(b => b.configPath), [fooFile.fsPath.toUpperCase()]); pfs.readFile(backupWorkspacesPath, 'utf-8').then(buffer => { const json = JSON.parse(buffer); - assert.deepEqual(json.rootWorkspaces, [fooFile.fsPath.toUpperCase()]); + assert.deepEqual(json.rootWorkspaces.map(b => b.configPath), [fooFile.fsPath.toUpperCase()]); done(); }); }); @@ -434,13 +459,15 @@ suite('BackupMainService', () => { }); test('should remove folder workspaces from workspaces.json (root workspace)', done => { - service.registerWorkspaceBackupSync(fooFile.fsPath); - service.registerWorkspaceBackupSync(barFile.fsPath); - service.removeBackupPathSync(fooFile.fsPath, service.backupsData.rootWorkspaces); + const ws1 = toWorkspace(fooFile.fsPath); + service.registerWorkspaceBackupSync(ws1); + const ws2 = toWorkspace(barFile.fsPath); + service.registerWorkspaceBackupSync(ws2); + service.removeBackupPathSync(ws1, service.backupsData.rootWorkspaces); pfs.readFile(backupWorkspacesPath, 'utf-8').then(buffer => { const json = JSON.parse(buffer); - assert.deepEqual(json.rootWorkspaces, [barFile.fsPath]); - service.removeBackupPathSync(barFile.fsPath, service.backupsData.rootWorkspaces); + assert.deepEqual(json.rootWorkspaces.map(r => r.configPath), [barFile.fsPath]); + service.removeBackupPathSync(ws2, service.backupsData.rootWorkspaces); pfs.readFile(backupWorkspacesPath, 'utf-8').then(content => { const json2 = JSON.parse(content); assert.deepEqual(json2.rootWorkspaces, []); @@ -481,7 +508,7 @@ suite('BackupMainService', () => { suite('getWorkspaceHash', () => { test('should perform an md5 hash on the path', () => { - assert.equal(service.getWorkspaceHash('/foo'), '1effb2475fcfba4f9e8b8a1dbc8f3caf'); + assert.equal(service.getFolderHash('/foo'), '1effb2475fcfba4f9e8b8a1dbc8f3caf'); }); test('should ignore case on Windows and Mac', () => { @@ -491,11 +518,11 @@ suite('BackupMainService', () => { } if (platform.isMacintosh) { - assert.equal(service.getWorkspaceHash('/foo'), service.getWorkspaceHash('/FOO')); + assert.equal(service.getFolderHash('/foo'), service.getFolderHash('/FOO')); } if (platform.isWindows) { - assert.equal(service.getWorkspaceHash('c:\\foo'), service.getWorkspaceHash('C:\\FOO')); + assert.equal(service.getFolderHash('c:\\foo'), service.getFolderHash('C:\\FOO')); } }); }); @@ -515,13 +542,13 @@ suite('BackupMainService', () => { }); test('should handle case insensitive paths properly (registerWindowForBackupsSync) (root workspace)', done => { - service.registerWorkspaceBackupSync(fooFile.fsPath); - service.registerWorkspaceBackupSync(fooFile.fsPath.toUpperCase()); + service.registerWorkspaceBackupSync(toWorkspace(fooFile.fsPath)); + service.registerWorkspaceBackupSync(toWorkspace(fooFile.fsPath.toUpperCase())); if (platform.isLinux) { - assert.equal(service.getWorkspaceBackupPaths().length, 2); + assert.equal(service.getWorkspaceBackups().length, 2); } else { - assert.equal(service.getWorkspaceBackupPaths().length, 1); + assert.equal(service.getWorkspaceBackups().length, 1); } done(); @@ -546,25 +573,5 @@ suite('BackupMainService', () => { done(); }); - - test('should handle case insensitive paths properly (removeBackupPathSync) (root workspace)', done => { - - // same case - service.registerWorkspaceBackupSync(fooFile.fsPath); - service.removeBackupPathSync(fooFile.fsPath, service.backupsData.rootWorkspaces); - assert.equal(service.getWorkspaceBackupPaths().length, 0); - - // mixed case - service.registerWorkspaceBackupSync(fooFile.fsPath); - service.removeBackupPathSync(fooFile.fsPath.toUpperCase(), service.backupsData.rootWorkspaces); - - if (platform.isLinux) { - assert.equal(service.getWorkspaceBackupPaths().length, 1); - } else { - assert.equal(service.getWorkspaceBackupPaths().length, 0); - } - - done(); - }); }); }); \ No newline at end of file diff --git a/src/vs/platform/windows/common/windows.ts b/src/vs/platform/windows/common/windows.ts index cb90ac2c704..8981f22a798 100644 --- a/src/vs/platform/windows/common/windows.ts +++ b/src/vs/platform/windows/common/windows.ts @@ -207,7 +207,7 @@ export interface IWindowConfiguration extends ParsedArgs, IOpenFileRequest { perfAppReady?: number; perfWindowLoadTime?: number; - workspaceConfigPath?: string; + workspace?: IWorkspace; folderPath?: string; backupPath?: string; diff --git a/src/vs/platform/windows/electron-main/windows.ts b/src/vs/platform/windows/electron-main/windows.ts index 23d190fb03c..07465e87b3a 100644 --- a/src/vs/platform/windows/electron-main/windows.ts +++ b/src/vs/platform/windows/electron-main/windows.ts @@ -12,6 +12,7 @@ import Event from 'vs/base/common/event'; import { ITelemetryData } from 'vs/platform/telemetry/common/telemetry'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IProcessEnvironment } from 'vs/base/common/platform'; +import { IWorkspace } from "vs/platform/workspaces/common/workspaces"; export interface ICodeWindow { id: number; @@ -19,7 +20,7 @@ export interface ICodeWindow { config: IWindowConfiguration; openedFolderPath: string; - openedWorkspaceConfigPath: string; + openedWorkspace: IWorkspace; lastFocusTime: number; diff --git a/src/vs/platform/windows/electron-main/windowsService.ts b/src/vs/platform/windows/electron-main/windowsService.ts index 69940525eac..1aa73b3769b 100644 --- a/src/vs/platform/windows/electron-main/windowsService.ts +++ b/src/vs/platform/windows/electron-main/windowsService.ts @@ -327,7 +327,7 @@ export class WindowsService implements IWindowsService, IDisposable { const codeWindow = this.windowsMainService.getWindowById(windowId); if (codeWindow) { - this.windowsMainService.open({ context: OpenContext.API, cli: this.environmentService.args, pathsToOpen: [workspace.workspaceConfigPath], windowToUse: codeWindow }); + this.windowsMainService.open({ context: OpenContext.API, cli: this.environmentService.args, pathsToOpen: [workspace.configPath], windowToUse: codeWindow }); } return TPromise.as(null); diff --git a/src/vs/platform/workspaces/common/workspaces.ts b/src/vs/platform/workspaces/common/workspaces.ts index 8ee9f7f0293..e16854b9c9c 100644 --- a/src/vs/platform/workspaces/common/workspaces.ts +++ b/src/vs/platform/workspaces/common/workspaces.ts @@ -12,7 +12,7 @@ export const IWorkspacesMainService = createDecorator('w export const IWorkspacesService = createDecorator('workspacesService'); export interface IWorkspace extends IStoredWorkspace { - workspaceConfigPath: string; + configPath: string; } export interface IStoredWorkspace { @@ -23,7 +23,7 @@ export interface IStoredWorkspace { export interface IWorkspacesMainService extends IWorkspacesService { _serviceBrand: any; - isWorkspace(path: string): boolean; + resolveWorkspaceSync(path: string): IWorkspace; } export interface IWorkspacesService { diff --git a/src/vs/platform/workspaces/electron-main/workspacesMainService.ts b/src/vs/platform/workspaces/electron-main/workspacesMainService.ts index 7a99f9094f3..d6d71ba67af 100644 --- a/src/vs/platform/workspaces/electron-main/workspacesMainService.ts +++ b/src/vs/platform/workspaces/electron-main/workspacesMainService.ts @@ -11,6 +11,8 @@ import { isParent } from "vs/platform/files/common/files"; import { IEnvironmentService } from "vs/platform/environment/common/environment"; import { extname, join } from "path"; import { mkdirp, writeFile } from "vs/base/node/pfs"; +import { readFileSync } from "fs"; +import { isLinux } from "vs/base/common/platform"; export class WorkspacesMainService implements IWorkspacesMainService { @@ -22,8 +24,26 @@ export class WorkspacesMainService implements IWorkspacesMainService { this.workspacesHome = environmentService.workspacesHome; } - public isWorkspace(path: string): boolean { - return isParent(path, this.environmentService.workspacesHome) || extname(path) === '.vscode'; + public resolveWorkspaceSync(path: string): IWorkspace { + const isWorkspace = isParent(path, this.environmentService.workspacesHome, !isLinux /* ignore case */) || extname(path) === '.code'; + if (!isWorkspace) { + return null; // does not look like a valid workspace config file + } + + try { + const workspace = JSON.parse(readFileSync(path, 'utf8')) as IStoredWorkspace; + if (typeof workspace.id !== 'string' || !Array.isArray(workspace.folders)) { + return null; // looks like an invalid workspace file + } + + return { + id: workspace.id, + folders: workspace.folders, + configPath: path + }; + } catch (error) { + return null; // unable to read or parse as workspace file + } } public createWorkspace(folders: string[] = []): TPromise { @@ -40,7 +60,7 @@ export class WorkspacesMainService implements IWorkspacesMainService { return writeFile(workspaceConfigPath, JSON.stringify(storedWorkspace, null, '\t')).then(() => ({ id: workspaceId, folders, - workspaceConfigPath + configPath: workspaceConfigPath })); }); } diff --git a/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts b/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts index 6eaf6e953a5..00bc286ebc4 100644 --- a/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts +++ b/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts @@ -48,10 +48,10 @@ suite('WorkspacesMainService', () => { test('createWorkspace (no folders)', done => { return service.createWorkspace().then(workspace => { assert.ok(workspace); - assert.ok(fs.existsSync(workspace.workspaceConfigPath)); + assert.ok(fs.existsSync(workspace.configPath)); assert.equal(workspace.folders.length, 0); - const ws = JSON.parse(fs.readFileSync(workspace.workspaceConfigPath).toString()) as IStoredWorkspace; + const ws = JSON.parse(fs.readFileSync(workspace.configPath).toString()) as IStoredWorkspace; assert.equal(ws.id, workspace.id); assert.deepEqual(ws.folders, workspace.folders); @@ -62,16 +62,34 @@ suite('WorkspacesMainService', () => { test('createWorkspace (folders)', done => { return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => { assert.ok(workspace); - assert.ok(fs.existsSync(workspace.workspaceConfigPath)); + assert.ok(fs.existsSync(workspace.configPath)); assert.equal(workspace.folders.length, 2); assert.equal(workspace.folders[0], process.cwd()); assert.equal(workspace.folders[1], os.tmpdir()); - const ws = JSON.parse(fs.readFileSync(workspace.workspaceConfigPath).toString()) as IStoredWorkspace; + const ws = JSON.parse(fs.readFileSync(workspace.configPath).toString()) as IStoredWorkspace; assert.equal(ws.id, workspace.id); assert.deepEqual(ws.folders, workspace.folders); done(); }); }); + + test('resolveWorkspace', done => { + return service.createWorkspace().then(workspace => { + + // is not resolved because config path is no in workspaces home + assert.ok(!service.resolveWorkspaceSync(workspace.configPath)); + + // make it a valid workspace path + const newPath = path.join(path.dirname(workspace.configPath), 'workspace.code'); + fs.renameSync(workspace.configPath, newPath); + workspace.configPath = newPath; + + const resolved = service.resolveWorkspaceSync(workspace.configPath); + assert.deepEqual(resolved, workspace); + + done(); + }); + }); }); \ No newline at end of file diff --git a/src/vs/workbench/electron-browser/main.ts b/src/vs/workbench/electron-browser/main.ts index 67efb4a4787..fc0fae751bc 100644 --- a/src/vs/workbench/electron-browser/main.ts +++ b/src/vs/workbench/electron-browser/main.ts @@ -169,7 +169,7 @@ interface IMultiRootWorkspaceData { } function resolveWorkspaceData(configuration: IWindowConfiguration): TPromise { - if (configuration.workspaceConfigPath) { + if (configuration.workspace) { return resolveMultiRootWorkspaceData(configuration); } @@ -209,7 +209,7 @@ function resolveSingleFolderWorkspaceData(configuration: IWindowConfiguration): } function resolveMultiRootWorkspaceData(configuration: IWindowConfiguration): TPromise { - return readFile(configuration.workspaceConfigPath).then(buffer => { + return readFile(configuration.workspace.configPath).then(buffer => { const contents = buffer.toString('utf8'); return JSON.parse(contents) as IMultiRootWorkspaceData;