diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 2ddff64f2dd..92310b76a73 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -3869,6 +3869,21 @@ declare module 'vscode' { options?: ShellExecutionOptions; } + /** + * The scope of a task. + */ + export enum TaskScope { + /** + * The task is a global task + */ + Global = 1, + + /** + * The task is a workspace task + */ + Workspace = 2 + } + /** * A task to execute */ @@ -3877,8 +3892,10 @@ declare module 'vscode' { /** * Creates a new task. * + * @deprecated: Use the new constructors that allow specifying a target for the task. + * * @param definition The task definition as defined in the taskDefinitions extension point. - * @param name The task's name. Is presented in the user interface. + * @param scope The task's name. Is presented in the user interface. * @param source The task's source (e.g. 'gulp', 'npm', ...). Is presented in the user interface. * @param execution The process or shell execution. * @param problemMatchers the names of problem matchers to use, like '$tsc' @@ -3891,6 +3908,7 @@ declare module 'vscode' { * Creates a new task. * * @param definition The task definition as defined in the taskDefinitions extension point. + * @param scope Specifies the task's scope. It is either a global or a workspace task or a task for a specific workspace folder. * @param workspaceFolder The workspace folder this task is created for. * @param name The task's name. Is presented in the user interface. * @param source The task's source (e.g. 'gulp', 'npm', ...). Is presented in the user interface. @@ -3899,7 +3917,7 @@ declare module 'vscode' { * or '$eslint'. Problem matchers can be contributed by an extension using * the `problemMatchers` extension point. */ - constructor(taskDefinition: TaskDefinition, workspaceFolder: WorkspaceFolder, name: string, source: string, execution?: ProcessExecution | ShellExecution, problemMatchers?: string | string[]); + constructor(taskDefinition: TaskDefinition, target: TaskScope.Global | TaskScope.Workspace | WorkspaceFolder, name: string, source: string, execution?: ProcessExecution | ShellExecution, problemMatchers?: string | string[]); /** * The task's definition. @@ -3907,10 +3925,9 @@ declare module 'vscode' { definition: TaskDefinition; /** - * The workspace folder this task is associated with. Can be undefined if - * the task is not associated with any workspace folder. + * The task's scope. */ - workspaceFolder?: WorkspaceFolder; + scope?: TaskScope.Global | TaskScope.Workspace | WorkspaceFolder; /** * The task's name diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index b1829b9387f..4c9ed5a511f 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -97,7 +97,7 @@ export function createApiFactory( const extHostQuickOpen = threadService.set(ExtHostContext.ExtHostQuickOpen, new ExtHostQuickOpen(threadService)); const extHostTerminalService = threadService.set(ExtHostContext.ExtHostTerminalService, new ExtHostTerminalService(threadService)); const extHostSCM = threadService.set(ExtHostContext.ExtHostSCM, new ExtHostSCM(threadService, extHostCommands)); - const extHostTask = threadService.set(ExtHostContext.ExtHostTask, new ExtHostTask(threadService)); + const extHostTask = threadService.set(ExtHostContext.ExtHostTask, new ExtHostTask(threadService, extHostWorkspace)); const extHostCredentials = threadService.set(ExtHostContext.ExtHostCredentials, new ExtHostCredentials(threadService)); const extHostWindow = threadService.set(ExtHostContext.ExtHostWindow, new ExtHostWindow(threadService)); threadService.set(ExtHostContext.ExtHostExtensionService, extensionService); @@ -599,6 +599,7 @@ export function createApiFactory( TaskGroup: extHostTypes.TaskGroup, ProcessExecution: extHostTypes.ProcessExecution, ShellExecution: extHostTypes.ShellExecution, + TaskScope: extHostTypes.TaskScope, Task: extHostTypes.Task, ConfigurationTarget: extHostTypes.ConfigurationTarget }; diff --git a/src/vs/workbench/api/node/extHostTask.ts b/src/vs/workbench/api/node/extHostTask.ts index 34c441a635d..b644dfb2424 100644 --- a/src/vs/workbench/api/node/extHostTask.ts +++ b/src/vs/workbench/api/node/extHostTask.ts @@ -16,6 +16,7 @@ import * as TaskSystem from 'vs/workbench/parts/tasks/common/tasks'; import { MainContext, MainThreadTaskShape, ExtHostTaskShape, IMainContext } from 'vs/workbench/api/node/extHost.protocol'; import * as types from 'vs/workbench/api/node/extHostTypes'; +import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace'; import * as vscode from 'vscode'; interface StringMap { @@ -296,13 +297,13 @@ namespace ShellConfiguration { namespace Tasks { - export function from(tasks: vscode.Task[], extension: IExtensionDescription): TaskSystem.Task[] { + export function from(tasks: vscode.Task[], rootFolder: vscode.WorkspaceFolder, extension: IExtensionDescription): TaskSystem.Task[] { if (tasks === void 0 || tasks === null) { return []; } let result: TaskSystem.Task[] = []; for (let task of tasks) { - let converted = fromSingle(task, extension); + let converted = fromSingle(task, rootFolder, extension); if (converted) { result.push(converted); } @@ -310,7 +311,7 @@ namespace Tasks { return result; } - function fromSingle(task: vscode.Task, extension: IExtensionDescription): TaskSystem.ContributedTask { + function fromSingle(task: vscode.Task, rootFolder: vscode.WorkspaceFolder, extension: IExtensionDescription): TaskSystem.ContributedTask { if (typeof task.name !== 'string') { return undefined; } @@ -327,11 +328,27 @@ namespace Tasks { return undefined; } command.presentation = PresentationOptions.from(task.presentationOptions); + + let taskScope: types.TaskScope.Global | types.TaskScope.Workspace | vscode.WorkspaceFolder | undefined = task.scope; + let workspaceFolder: vscode.WorkspaceFolder | undefined; + let scope: TaskSystem.TaskScope; + // For backwards compatibility + if (taskScope === void 0) { + scope = TaskSystem.TaskScope.Folder; + workspaceFolder = rootFolder; + } else if (taskScope === types.TaskScope.Global) { + scope = TaskSystem.TaskScope.Global; + } else if (taskScope === types.TaskScope.Workspace) { + scope = TaskSystem.TaskScope.Workspace; + } else { + workspaceFolder = taskScope; + } let source: TaskSystem.ExtensionTaskSource = { kind: TaskSystem.TaskSourceKind.Extension, label: typeof task.source === 'string' ? task.source : extension.name, extension: extension.id, - workspaceFolder: task.workspaceFolder ? { uri: task.workspaceFolder.uri as URI } : undefined + scope: scope, + workspaceFolder: workspaceFolder ? { uri: workspaceFolder.uri as URI } : undefined }; let label = nls.localize('task.label', '{0}: {1}', source.label, task.name); let key = (task as types.Task).definitionKey; @@ -400,11 +417,13 @@ interface HandlerData { export class ExtHostTask implements ExtHostTaskShape { private _proxy: MainThreadTaskShape; + private _extHostWorkspace: ExtHostWorkspace; private _handleCounter: number; private _handlers: Map; - constructor(mainContext: IMainContext) { + constructor(mainContext: IMainContext, extHostWorkspace: ExtHostWorkspace) { this._proxy = mainContext.get(MainContext.MainThreadTask); + this._extHostWorkspace = extHostWorkspace; this._handleCounter = 0; this._handlers = new Map(); }; @@ -428,8 +447,9 @@ export class ExtHostTask implements ExtHostTaskShape { return TPromise.wrapError(new Error('no handler found')); } return asWinJsPromise(token => handler.provider.provideTasks(token)).then(value => { + let workspaceFolders = this._extHostWorkspace.getWorkspaceFolders(); return { - tasks: Tasks.from(value, handler.extension), + tasks: Tasks.from(value, workspaceFolders && workspaceFolders.length > 0 ? workspaceFolders[0] : undefined, handler.extension), extension: handler.extension }; }); diff --git a/src/vs/workbench/api/node/extHostTypes.ts b/src/vs/workbench/api/node/extHostTypes.ts index d198bae11a9..a9b213648b8 100644 --- a/src/vs/workbench/api/node/extHostTypes.ts +++ b/src/vs/workbench/api/node/extHostTypes.ts @@ -1214,11 +1214,16 @@ export class ShellExecution implements vscode.ShellExecution { } } +export enum TaskScope { + Global = 1, + Workspace = 2 +} + export class Task implements vscode.Task { private _definition: vscode.TaskDefinition; private _definitionKey: string; - private _workspaceFolder: vscode.WorkspaceFolder; + private _scope: vscode.TaskScope.Global | vscode.TaskScope.Workspace | vscode.WorkspaceFolder; private _name: string; private _execution: ProcessExecution | ShellExecution; private _problemMatchers: string[]; @@ -1229,8 +1234,8 @@ export class Task implements vscode.Task { private _presentationOptions: vscode.TaskPresentationOptions; constructor(definition: vscode.TaskDefinition, name: string, source: string, execution?: ProcessExecution | ShellExecution, problemMatchers?: string | string[]); - constructor(definition: vscode.TaskDefinition, workspaceFolder: vscode.WorkspaceFolder, name: string, source: string, execution?: ProcessExecution | ShellExecution, problemMatchers?: string | string[]); - constructor(definition: vscode.TaskDefinition, arg2: string | vscode.WorkspaceFolder, arg3: any, arg4?: any, arg5?: any, arg6?: any) { + constructor(definition: vscode.TaskDefinition, scope: vscode.TaskScope.Global | vscode.TaskScope.Workspace | vscode.WorkspaceFolder, name: string, source: string, execution?: ProcessExecution | ShellExecution, problemMatchers?: string | string[]); + constructor(definition: vscode.TaskDefinition, arg2: string | (vscode.TaskScope.Global | vscode.TaskScope.Workspace) | vscode.WorkspaceFolder, arg3: any, arg4?: any, arg5?: any, arg6?: any) { this.definition = definition; let problemMatchers: string | string[]; if (typeof arg2 === 'string') { @@ -1238,8 +1243,14 @@ export class Task implements vscode.Task { this.source = arg3; this.execution = arg4; problemMatchers = arg5; + } else if (arg2 === TaskScope.Global || arg2 === TaskScope.Workspace) { + this.target = arg2; + this.name = arg3; + this.source = arg4; + this.execution = arg5; + problemMatchers = arg6; } else { - this.workspaceFolder = arg2; + this.target = arg2; this.name = arg3; this.source = arg4; this.execution = arg5; @@ -1279,12 +1290,12 @@ export class Task implements vscode.Task { return this._definitionKey; } - get workspaceFolder(): vscode.WorkspaceFolder { - return this._workspaceFolder; + get scope(): vscode.TaskScope.Global | vscode.TaskScope.Workspace | vscode.WorkspaceFolder { + return this._scope; } - set workspaceFolder(value: vscode.WorkspaceFolder) { - this._workspaceFolder = value; + set target(value: vscode.TaskScope.Global | vscode.TaskScope.Workspace | vscode.WorkspaceFolder) { + this._scope = value; } get name(): string { diff --git a/src/vs/workbench/parts/tasks/browser/quickOpen.ts b/src/vs/workbench/parts/tasks/browser/quickOpen.ts index 2f64e812655..32a4d495b83 100644 --- a/src/vs/workbench/parts/tasks/browser/quickOpen.ts +++ b/src/vs/workbench/parts/tasks/browser/quickOpen.ts @@ -21,7 +21,7 @@ import { ActionBarContributor, ContributableActionProvider } from 'vs/workbench/ export class TaskEntry extends Model.QuickOpenEntry { - constructor(protected taskService: ITaskService, protected quickOpenService: IQuickOpenService, protected _task: CustomTask | ContributedTask, highlights: Model.IHighlight[] = []) { + constructor(protected quickOpenService: IQuickOpenService, protected taskService: ITaskService, protected _task: CustomTask | ContributedTask, highlights: Model.IHighlight[] = []) { super(highlights); } @@ -29,6 +29,17 @@ export class TaskEntry extends Model.QuickOpenEntry { return this.task._label; } + public getDescription(): string { + if (!this.taskService.hasMultipleFolders()) { + return null; + } + let workspaceFolder = Task.getWorkspaceFolder(this.task); + if (!workspaceFolder) { + return null; + } + return workspaceFolder.uri.fsPath; + } + public getAriaLabel(): string { return nls.localize('entryAriaLabel', "{0}, tasks", this.getLabel()); } diff --git a/src/vs/workbench/parts/tasks/browser/taskQuickOpen.ts b/src/vs/workbench/parts/tasks/browser/taskQuickOpen.ts index 46d3c023200..b7325389b2b 100644 --- a/src/vs/workbench/parts/tasks/browser/taskQuickOpen.ts +++ b/src/vs/workbench/parts/tasks/browser/taskQuickOpen.ts @@ -14,12 +14,11 @@ import { CustomTask, ContributedTask } from 'vs/workbench/parts/tasks/common/tas import { ITaskService } from 'vs/workbench/parts/tasks/common/taskService'; import { IExtensionService } from 'vs/platform/extensions/common/extensions'; - import * as base from './quickOpen'; class TaskEntry extends base.TaskEntry { - constructor(taskService: ITaskService, quickOpenService: IQuickOpenService, task: CustomTask | ContributedTask, highlights: Model.IHighlight[] = []) { - super(taskService, quickOpenService, task, highlights); + constructor(quickOpenService: IQuickOpenService, taskService: ITaskService, task: CustomTask | ContributedTask, highlights: Model.IHighlight[] = []) { + super(quickOpenService, taskService, task, highlights); } public run(mode: QuickOpen.Mode, context: Model.IContext): boolean { @@ -36,8 +35,8 @@ export class QuickOpenHandler extends base.QuickOpenHandler { constructor( @IQuickOpenService quickOpenService: IQuickOpenService, - @ITaskService taskService: ITaskService, - @IExtensionService extensionService: IExtensionService + @IExtensionService extensionService: IExtensionService, + @ITaskService taskService: ITaskService ) { super(quickOpenService, taskService); this.activationPromise = extensionService.activateByEvent('onCommand:workbench.action.tasks.runTask'); @@ -54,7 +53,7 @@ export class QuickOpenHandler extends base.QuickOpenHandler { } protected createEntry(task: CustomTask | ContributedTask, highlights: Model.IHighlight[]): base.TaskEntry { - return new TaskEntry(this.taskService, this.quickOpenService, task, highlights); + return new TaskEntry(this.quickOpenService, this.taskService, task, highlights); } public getEmptyLabel(searchString: string): string { diff --git a/src/vs/workbench/parts/tasks/common/taskService.ts b/src/vs/workbench/parts/tasks/common/taskService.ts index 7598b170398..d56ad59ce58 100644 --- a/src/vs/workbench/parts/tasks/common/taskService.ts +++ b/src/vs/workbench/parts/tasks/common/taskService.ts @@ -59,7 +59,8 @@ export interface ITaskService extends IEventEmitter { getTasksForGroup(group: string): TPromise; getRecentlyUsedTasks(): LinkedMap; - canCustomize(): boolean; + hasMultipleFolders(); + canCustomize(task: ContributedTask | CustomTask): boolean; customize(task: ContributedTask | CustomTask, properties?: {}, openConfig?: boolean): TPromise; openConfig(task: CustomTask): TPromise; diff --git a/src/vs/workbench/parts/tasks/common/tasks.ts b/src/vs/workbench/parts/tasks/common/tasks.ts index c14c121b4b0..9c15a51436b 100644 --- a/src/vs/workbench/parts/tasks/common/tasks.ts +++ b/src/vs/workbench/parts/tasks/common/tasks.ts @@ -216,6 +216,12 @@ export namespace TaskGroup { export type TaskGroup = 'clean' | 'build' | 'rebuild' | 'test'; +export enum TaskScope { + Global = 1, + Workspace = 2, + Folder = 3 +} + export namespace TaskSourceKind { export const Workspace: 'workspace' = 'workspace'; export const Extension: 'extension' = 'extension'; @@ -234,22 +240,23 @@ export interface TaskSourceConfigElement { } export interface WorkspaceTaskSource { - kind: 'workspace'; - label: string; - config: TaskSourceConfigElement; - customizes?: TaskIdentifier; + readonly kind: 'workspace'; + readonly label: string; + readonly config: TaskSourceConfigElement; + readonly customizes?: TaskIdentifier; } export interface ExtensionTaskSource { - kind: 'extension'; - label: string; - extension: string; - workspaceFolder: WorkspaceFolder | undefined; + readonly kind: 'extension'; + readonly label: string; + readonly extension: string; + readonly scope: TaskScope; + readonly workspaceFolder: WorkspaceFolder | undefined; } export interface CompositeTaskSource { - kind: 'composite'; - label: string; + readonly kind: 'composite'; + readonly label: string; } export type TaskSource = WorkspaceTaskSource | ExtensionTaskSource | CompositeTaskSource; diff --git a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts index 891859d782a..b66c93ce362 100644 --- a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts +++ b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts @@ -958,7 +958,7 @@ class TaskService extends EventEmitter implements ITaskService { } private shouldAttachProblemMatcher(task: Task): boolean { - if (!this.canCustomize()) { + if (!this.canCustomize(task)) { return false; } if (task.group !== void 0 && task.group !== TaskGroup.Build) { @@ -1047,8 +1047,21 @@ class TaskService extends EventEmitter implements ITaskService { }); } - public canCustomize(): boolean { - return this._schemaVersion === JsonSchemaVersion.V2_0_0; + public hasMultipleFolders(): boolean { + return this._workspaceFolders && this._workspaceFolders.length > 1; + } + + public canCustomize(task: Task): boolean { + if (this._schemaVersion !== JsonSchemaVersion.V2_0_0) { + return false; + } + if (CustomTask.is(task)) { + return true; + } + if (ContributedTask.is(task)) { + return !!Task.getWorkspaceFolder(task); + } + return false; } public customize(task: ContributedTask | CustomTask, properties?: CustomizationProperties, openConfig?: boolean): TPromise { @@ -1119,12 +1132,12 @@ class TaskService extends EventEmitter implements ITaskService { fileConfig.problemMatcher = properties.problemMatcher; value.key = 'tasks.problemMatchers'; value.value = fileConfig.problemMatcher; - promise = this.configurationEditingService.writeConfiguration(ConfigurationTarget.WORKSPACE, value); + promise = this.writeConfiguration(workspaceFolder, value); } else if (properties.group !== void 0) { fileConfig.group = properties.group; value.key = 'tasks.group'; value.value = fileConfig.group; - promise = this.configurationEditingService.writeConfiguration(ConfigurationTarget.WORKSPACE, value); + promise = this.writeConfiguration(workspaceFolder, value); } } else { if (!Array.isArray(fileConfig.tasks)) { @@ -1137,7 +1150,7 @@ class TaskService extends EventEmitter implements ITaskService { } else { fileConfig.tasks[index] = toCustomize; } - promise = this.configurationEditingService.writeConfiguration(ConfigurationTarget.WORKSPACE, value); + promise = this.writeConfiguration(workspaceFolder, value); } }; if (!promise) { @@ -1161,6 +1174,16 @@ class TaskService extends EventEmitter implements ITaskService { }); } + private writeConfiguration(workspaceFolder: WorkspaceFolder, value: IConfigurationValue): TPromise { + if (this.contextService.getWorkbenchState() === WorkbenchState.FOLDER) { + return this.configurationEditingService.writeConfiguration(ConfigurationTarget.WORKSPACE, value); + } else if (this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE) { + return this.configurationEditingService.writeConfiguration(ConfigurationTarget.FOLDER, value, { scopes: { resource: workspaceFolder.uri } }); + } else { + return undefined; + } + } + public openConfig(task: CustomTask): TPromise { // @ToDo need to adopt since this is not working anymore let resource = this.contextService.toResource(task._source.config.file); @@ -1390,33 +1413,38 @@ class TaskService extends EventEmitter implements ITaskService { let configuringTask = configurations.byIdentifier[task.defines._key]; if (configuringTask) { result.push(TaskConfig.createCustomTask(task, configuringTask)); - continue; + } else { + result.push(task); } } else if (legacyTaskConfigurations) { let configuringTask = legacyTaskConfigurations[task.defines._key]; if (configuringTask) { result.push(TaskConfig.createCustomTask(task, configuringTask)); customTasksToDelete.push(configuringTask); - continue; + } else { + result.push(task); } } else { result.push(task); } } - } - if (customTasksToDelete.length > 0) { - let toDelete = customTasksToDelete.reduce>((map, task) => { - map[task._id] = true; - return map; - }, Object.create(null)); - for (let task of folderTasks.set.tasks) { - if (toDelete[task._id]) { - continue; + if (customTasksToDelete.length > 0) { + let toDelete = customTasksToDelete.reduce>((map, task) => { + map[task._id] = true; + return map; + }, Object.create(null)); + for (let task of folderTasks.set.tasks) { + if (toDelete[task._id]) { + continue; + } + result.push(task); } - result.push(task); + } else { + result.push(...folderTasks.set.tasks); } } else { result.push(...folderTasks.set.tasks); + result.push(...contributed); } } }); @@ -1479,89 +1507,6 @@ class TaskService extends EventEmitter implements ITaskService { }); } - /* - private computeWorkspaceTasks2(): TPromise { - let configPromise: TPromise; - { - let { config, hasParseErrors } = this.getConfiguration(); - if (hasParseErrors) { - return TPromise.as({ set: undefined, hasErrors: true, configurations: undefined }); - } - let engine = ExecutionEngine._default; - if (config) { - engine = TaskConfig.ExecutionEngine.from(config); - if (engine === ExecutionEngine.Process) { - if (this.hasDetectorSupport(config)) { - configPromise = new ProcessRunnerDetector(this.fileService, this.contextService, this.configurationResolverService, config).detect(true).then((value): WorkspaceFolderConfigurationResult => { - let hasErrors = this.printStderr(value.stderr); - let detectedConfig = value.config; - if (!detectedConfig) { - return { config, hasErrors }; - } - let result: TaskConfig.ExternalTaskRunnerConfiguration = Objects.clone(config); - let configuredTasks: IStringDictionary = Object.create(null); - if (!result.tasks) { - if (detectedConfig.tasks) { - result.tasks = detectedConfig.tasks; - } - } else { - result.tasks.forEach(task => configuredTasks[task.taskName] = task); - detectedConfig.tasks.forEach((task) => { - if (!configuredTasks[task.taskName]) { - result.tasks.push(task); - } - }); - } - return { config: result, hasErrors }; - }); - } else { - configPromise = TPromise.as({ config, hasErrors: false }); - } - } else { - configPromise = TPromise.as({ config, hasErrors: false }); - } - } else { - if (engine === ExecutionEngine.Terminal) { - configPromise = TPromise.as({ config, hasErrors: false }); - } else { - configPromise = new ProcessRunnerDetector(this.fileService, this.contextService, this.configurationResolverService).detect(true).then((value) => { - let hasErrors = this.printStderr(value.stderr); - return { config: value.config, hasErrors }; - }); - } - } - } - return configPromise.then((resolved) => { - return ProblemMatcherRegistry.onReady().then((): WorkspaceTaskResult => { - if (!resolved || !resolved.config) { - return { set: undefined, configurations: undefined, hasErrors: resolved !== void 0 ? resolved.hasErrors : false }; - } - let problemReporter = new ProblemReporter(this._outputChannel); - let parseResult = TaskConfig.parse(resolved.config, problemReporter); - let hasErrors = false; - if (!parseResult.validationStatus.isOK()) { - hasErrors = true; - this.showOutput(); - } - if (problemReporter.status.isFatal()) { - problemReporter.fatal(nls.localize('TaskSystem.configurationErrors', 'Error: the provided task configuration has validation errors and can\'t not be used. Please correct the errors first.')); - return { set: undefined, configurations: undefined, hasErrors }; - } - let customizedTasks: { byIdentifier: IStringDictionary; }; - if (parseResult.configured && parseResult.configured.length > 0) { - customizedTasks = { - byIdentifier: Object.create(null) - }; - for (let task of parseResult.configured) { - customizedTasks.byIdentifier[task.configures._key] = task; - } - } - return { set: { tasks: parseResult.custom }, configurations: customizedTasks, hasErrors }; - }); - }); - } - */ - private computeWorkspaceTasks(): TPromise> { if (this._workspaceFolders.length === 0) { return TPromise.as(new Map()); @@ -1666,15 +1611,15 @@ class TaskService extends EventEmitter implements ITaskService { let executionEngine = ExecutionEngine.Terminal; let schemaVersion = JsonSchemaVersion.V2_0_0; - if (this.contextService.hasFolderWorkspace()) { - let workspaceFolder: WorkspaceFolder = { uri: this.contextService.getWorkspace().roots[0] }; + if (this.contextService.getWorkbenchState() === WorkbenchState.FOLDER) { + let workspaceFolder: WorkspaceFolder = { uri: this.contextService.getWorkspace().folders[0] }; workspaceFolders.push(workspaceFolder); executionEngine = this.computeExecutionEngine(workspaceFolder); schemaVersion = this.computeJsonSchemaVersion(workspaceFolder); - } else if (this.contextService.hasMultiFolderWorkspace()) { - for (let folder of this.contextService.getWorkspace().roots) { + } else if (this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE) { + for (let folder of this.contextService.getWorkspace().folders) { let workspaceFolder = { uri: folder }; - if (this._schemaVersion === this.computeJsonSchemaVersion(workspaceFolder)) { + if (schemaVersion === this.computeJsonSchemaVersion(workspaceFolder)) { workspaceFolders.push(workspaceFolder); } else { this._outputChannel.append(nls.localize( @@ -1703,10 +1648,8 @@ class TaskService extends EventEmitter implements ITaskService { return TaskConfig.JsonSchemaVersion.from(config); } - private getConfiguration(): { config: TaskConfig.ExternalTaskRunnerConfiguration; hasParseErrors: boolean } { - let result = this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY ? this.configurationService.getConfiguration('tasks', { resource: this.contextService.getWorkspace().folders[0] }) : undefined; private getConfiguration(workspaceFolder: WorkspaceFolder): { config: TaskConfig.ExternalTaskRunnerConfiguration; hasParseErrors: boolean } { - let result = this.contextService.hasWorkspace() + let result = this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY ? this.configurationService.getConfiguration('tasks', { resource: workspaceFolder.uri }) : undefined; if (!result) { diff --git a/src/vs/workbench/parts/tasks/node/taskConfiguration.ts b/src/vs/workbench/parts/tasks/node/taskConfiguration.ts index c16b90342fe..9bd43c3080f 100644 --- a/src/vs/workbench/parts/tasks/node/taskConfiguration.ts +++ b/src/vs/workbench/parts/tasks/node/taskConfiguration.ts @@ -1222,7 +1222,7 @@ namespace CustomTask { let result: Tasks.CustomTask = { type: 'custom', _id: context.uuidMap.getUUID(taskName), - _source: Objects.assign({}, source, { config: { index, element: external, file: '.vscode\\tasks.json' } }), + _source: Objects.assign({}, source, { config: { index, element: external, file: '.vscode\\tasks.json', workspaceFolder: context.workspaceFolder } }), _label: taskName, name: taskName, identifier: taskName, @@ -1756,7 +1756,7 @@ class ConfigurationParser { let isBackground = fileConfig.isBackground ? !!fileConfig.isBackground : fileConfig.isWatching ? !!fileConfig.isWatching : undefined; let task: Tasks.CustomTask = { _id: context.uuidMap.getUUID(globals.command.name), - _source: Objects.assign({}, source, { config: { index: -1, element: fileConfig } }), + _source: Objects.assign({}, source, { config: { index: -1, element: fileConfig, workspaceFolder: context.workspaceFolder } }), _label: globals.command.name, type: 'custom', name: globals.command.name,