diff --git a/src/vs/platform/workspaces/electron-main/workspacesMainService.ts b/src/vs/platform/workspaces/electron-main/workspacesMainService.ts index f6c6ab6035ab8d9c40453b598ce34e6e128791f6..2428e572c5e3a008e4871e97df0f0ea94c47843c 100644 --- a/src/vs/platform/workspaces/electron-main/workspacesMainService.ts +++ b/src/vs/platform/workspaces/electron-main/workspacesMainService.ts @@ -5,7 +5,7 @@ 'use strict'; -import { IWorkspacesMainService, IWorkspaceIdentifier, IStoredWorkspace, WORKSPACE_EXTENSION, IWorkspaceSavedEvent, UNTITLED_WORKSPACE_NAME, IResolvedWorkspace, IStoredWorkspaceFolder } from 'vs/platform/workspaces/common/workspaces'; +import { IWorkspacesMainService, IWorkspaceIdentifier, IStoredWorkspace, WORKSPACE_EXTENSION, IWorkspaceSavedEvent, UNTITLED_WORKSPACE_NAME, IResolvedWorkspace } from 'vs/platform/workspaces/common/workspaces'; import { TPromise } from 'vs/base/common/winjs.base'; import { isParent } from 'vs/platform/files/common/files'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; @@ -85,21 +85,17 @@ export class WorkspacesMainService implements IWorkspacesMainService { writeFileSync(path, JSON.stringify(workspace, null, '\t')); } - let absoluteFolders: IStoredWorkspaceFolder[] = []; + // relative paths get resolved against the workspace location workspace.folders.forEach(folder => { - if (isAbsolute(folder.path)) { - absoluteFolders.push(folder); - } else { - absoluteFolders.push({ - path: resolve(dirname(path), folder.path) // relative paths get resolved against the workspace location - }); + if (folder.path && !isAbsolute(folder.path)) { + folder.path = resolve(dirname(path), folder.path); } }); return { id: this.getWorkspaceId(path), configPath: path, - folders: absoluteFolders + folders: workspace.folders }; } catch (error) { this.logService.log(error.toString()); @@ -205,12 +201,14 @@ export class WorkspacesMainService implements IWorkspacesMainService { // is a parent of the location of the workspace file itself. Otherwise keep // using absolute paths. storedWorkspace.folders.forEach(folder => { - if (!isAbsolute(folder.path)) { - folder.path = resolve(sourceConfigFolder, folder.path); // relative paths get resolved against the workspace location - } - - if (isEqualOrParent(folder.path, targetConfigFolder, !isLinux)) { - folder.path = relative(targetConfigFolder, folder.path); // absolute paths get converted to relative ones to workspace location if possible + if (folder.path) { + if (!isAbsolute(folder.path)) { + folder.path = resolve(sourceConfigFolder, folder.path); // relative paths get resolved against the workspace location + } + + if (isEqualOrParent(folder.path, targetConfigFolder, !isLinux)) { + folder.path = relative(targetConfigFolder, folder.path); // absolute paths get converted to relative ones to workspace location if possible + } } }); diff --git a/src/vs/workbench/services/configuration/common/configurationModels.ts b/src/vs/workbench/services/configuration/common/configurationModels.ts index a29928f2402b628cbe54c55a6da29eb20eb984bd..dd7f73103ed60c1d88478106156434af30ba1ebe 100644 --- a/src/vs/workbench/services/configuration/common/configurationModels.ts +++ b/src/vs/workbench/services/configuration/common/configurationModels.ts @@ -15,7 +15,7 @@ import { IStoredWorkspaceFolder } from 'vs/platform/workspaces/common/workspaces export class WorkspaceConfigurationModel extends CustomConfigurationModel { private _raw: T; - private _folders: string[]; + private _folders: IStoredWorkspaceFolder[]; private _worksapaceSettings: ConfigurationModel; private _tasksConfiguration: ConfigurationModel; private _launchConfiguration: ConfigurationModel; @@ -27,7 +27,7 @@ export class WorkspaceConfigurationModel extends CustomConfigurationModel this._workspaceConfiguration = this.consolidate(); } - get folders(): string[] { + get folders(): IStoredWorkspaceFolder[] { return this._folders; } @@ -38,7 +38,7 @@ export class WorkspaceConfigurationModel extends CustomConfigurationModel protected processRaw(raw: T): void { this._raw = raw; - this._folders = ((this._raw['folders'] || []) as IStoredWorkspaceFolder[]).map(folder => folder.path); + this._folders = (this._raw['folders'] || []) as IStoredWorkspaceFolder[]; this._worksapaceSettings = this.parseConfigurationModel('settings'); this._tasksConfiguration = this.parseConfigurationModel('tasks'); this._launchConfiguration = this.parseConfigurationModel('launch'); diff --git a/src/vs/workbench/services/configuration/node/configuration.ts b/src/vs/workbench/services/configuration/node/configuration.ts index 7f445cf4f768c09b14e046cda241c5367f01336f..0f45a64cd69a5bc3689dbbbae9fc7ff6efa54143 100644 --- a/src/vs/workbench/services/configuration/node/configuration.ts +++ b/src/vs/workbench/services/configuration/node/configuration.ts @@ -9,7 +9,7 @@ import * as paths from 'vs/base/common/paths'; import { TPromise } from 'vs/base/common/winjs.base'; import Event, { Emitter } from 'vs/base/common/event'; import { StrictResourceMap } from 'vs/base/common/map'; -import { equals } from 'vs/base/common/arrays'; +import { equals, coalesce } from 'vs/base/common/arrays'; import * as objects from 'vs/base/common/objects'; import * as errors from 'vs/base/common/errors'; import * as collections from 'vs/base/common/collections'; @@ -33,7 +33,7 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { ExtensionsRegistry, ExtensionMessageCollector } from 'vs/platform/extensions/common/extensionsRegistry'; import { IConfigurationNode, IConfigurationRegistry, Extensions, editorConfigurationSchemaId, IDefaultConfigurationExtension, validateProperty, ConfigurationScope, schemaId } from 'vs/platform/configuration/common/configurationRegistry'; import { createHash } from 'crypto'; -import { getWorkspaceLabel, IWorkspacesService, IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; +import { getWorkspaceLabel, IWorkspacesService, IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, IStoredWorkspaceFolder } from 'vs/platform/workspaces/common/workspaces'; interface IStat { resource: URI; @@ -436,26 +436,32 @@ export class WorkspaceServiceImpl extends WorkspaceService { return this.workspaceConfiguration.load(this.workspaceConfigPath) .then(() => { const workspaceConfigurationModel = this.workspaceConfiguration.workspaceConfigurationModel; - if (!workspaceConfigurationModel.folders.length) { + const workspaceFolders = this.parseWorkspaceFolders(workspaceConfigurationModel.folders); + if (!workspaceFolders.length) { return TPromise.wrapError(new Error('Invalid workspace configuraton file ' + this.workspaceConfigPath)); } const workspaceId = (this.workspaceIdentifier as IWorkspaceIdentifier).id; const workspaceName = getWorkspaceLabel({ id: workspaceId, configPath: this.workspaceConfigPath.fsPath }, this.environmentService); - this.workspace = new Workspace(workspaceId, workspaceName, this.parseWorkspaceFolders(workspaceConfigurationModel.folders), this.workspaceConfigPath); + this.workspace = new Workspace(workspaceId, workspaceName, workspaceFolders, this.workspaceConfigPath); this.legacyWorkspace = new LegacyWorkspace(this.workspace.roots[0]); this._register(this.workspaceConfiguration.onDidUpdateConfiguration(() => this.onWorkspaceConfigurationChanged())); return null; }); } - private parseWorkspaceFolders(configuredFolders: string[]): URI[] { - return configuredFolders.map(configuredFolder => { - if (paths.isAbsolute(configuredFolder)) { - return URI.file(configuredFolder); + private parseWorkspaceFolders(configuredFolders: IStoredWorkspaceFolder[]): URI[] { + return coalesce(configuredFolders.map(configuredFolder => { + const path = configuredFolder.path; + if (!path) { + return void 0; } - return URI.file(paths.join(paths.dirname(this.workspaceConfigPath.fsPath), configuredFolder)); - }); + if (paths.isAbsolute(path)) { + return URI.file(path); + } + + return URI.file(paths.join(paths.dirname(this.workspaceConfigPath.fsPath), path)); + })); } private registerWorkspaceConfigSchema(): void {