提交 9c6880cb 编写于 作者: D Dirk Baeumer

Add workspace folders to task API

上级 48a286f9
...@@ -3887,11 +3887,31 @@ declare module 'vscode' { ...@@ -3887,11 +3887,31 @@ declare module 'vscode' {
*/ */
constructor(taskDefinition: TaskDefinition, name: string, source: string, execution?: ProcessExecution | ShellExecution, problemMatchers?: string | string[]); constructor(taskDefinition: TaskDefinition, name: string, source: string, execution?: ProcessExecution | ShellExecution, problemMatchers?: string | string[]);
/**
* Creates a new task.
*
* @param definition The task definition as defined in the taskDefinitions extension point.
* @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.
* @param execution The process or shell execution.
* @param problemMatchers the names of problem matchers to use, like '$tsc'
* 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[]);
/** /**
* The task's definition. * The task's definition.
*/ */
definition: TaskDefinition; definition: TaskDefinition;
/**
* The workspace folder this task is associated with. Can be undefined if
* the task is not associated with any workspace folder.
*/
workspaceFolder?: WorkspaceFolder;
/** /**
* The task's name * The task's name
*/ */
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
'use strict'; 'use strict';
import URI from 'vs/base/common/uri';
import * as nls from 'vs/nls'; import * as nls from 'vs/nls';
import { TPromise } from 'vs/base/common/winjs.base'; import { TPromise } from 'vs/base/common/winjs.base';
import * as Objects from 'vs/base/common/objects'; import * as Objects from 'vs/base/common/objects';
...@@ -326,10 +327,11 @@ namespace Tasks { ...@@ -326,10 +327,11 @@ namespace Tasks {
return undefined; return undefined;
} }
command.presentation = PresentationOptions.from(task.presentationOptions); command.presentation = PresentationOptions.from(task.presentationOptions);
let source = { let source: TaskSystem.ExtensionTaskSource = {
kind: TaskSystem.TaskSourceKind.Extension, kind: TaskSystem.TaskSourceKind.Extension,
label: typeof task.source === 'string' ? task.source : extension.name, label: typeof task.source === 'string' ? task.source : extension.name,
extension: extension.id extension: extension.id,
workspaceFolder: task.workspaceFolder ? { uri: task.workspaceFolder.uri as URI } : undefined
}; };
let label = nls.localize('task.label', '{0}: {1}', source.label, task.name); let label = nls.localize('task.label', '{0}: {1}', source.label, task.name);
let key = (task as types.Task).definitionKey; let key = (task as types.Task).definitionKey;
......
...@@ -1218,6 +1218,7 @@ export class Task implements vscode.Task { ...@@ -1218,6 +1218,7 @@ export class Task implements vscode.Task {
private _definition: vscode.TaskDefinition; private _definition: vscode.TaskDefinition;
private _definitionKey: string; private _definitionKey: string;
private _workspaceFolder: vscode.WorkspaceFolder;
private _name: string; private _name: string;
private _execution: ProcessExecution | ShellExecution; private _execution: ProcessExecution | ShellExecution;
private _problemMatchers: string[]; private _problemMatchers: string[];
...@@ -1227,11 +1228,23 @@ export class Task implements vscode.Task { ...@@ -1227,11 +1228,23 @@ export class Task implements vscode.Task {
private _group: TaskGroup; private _group: TaskGroup;
private _presentationOptions: vscode.TaskPresentationOptions; private _presentationOptions: vscode.TaskPresentationOptions;
constructor(definition: vscode.TaskDefinition, name: string, source: string, execution?: ProcessExecution | ShellExecution, problemMatchers?: string | string[]) { 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) {
this.definition = definition; this.definition = definition;
this.name = name; let problemMatchers: string | string[];
this.source = source; if (typeof arg2 === 'string') {
this.execution = execution; this.name = arg2;
this.source = arg3;
this.execution = arg4;
problemMatchers = arg5;
} else {
this.workspaceFolder = arg2;
this.name = arg3;
this.source = arg4;
this.execution = arg5;
problemMatchers = arg6;
}
if (typeof problemMatchers === 'string') { if (typeof problemMatchers === 'string') {
this._problemMatchers = [problemMatchers]; this._problemMatchers = [problemMatchers];
this._hasDefinedMatchers = true; this._hasDefinedMatchers = true;
...@@ -1266,6 +1279,14 @@ export class Task implements vscode.Task { ...@@ -1266,6 +1279,14 @@ export class Task implements vscode.Task {
return this._definitionKey; return this._definitionKey;
} }
get workspaceFolder(): vscode.WorkspaceFolder {
return this._workspaceFolder;
}
set workspaceFolder(value: vscode.WorkspaceFolder) {
this._workspaceFolder = value;
}
get name(): string { get name(): string {
return this._name; return this._name;
} }
......
...@@ -244,6 +244,7 @@ export interface ExtensionTaskSource { ...@@ -244,6 +244,7 @@ export interface ExtensionTaskSource {
kind: 'extension'; kind: 'extension';
label: string; label: string;
extension: string; extension: string;
workspaceFolder: WorkspaceFolder | undefined;
} }
export interface CompositeTaskSource { export interface CompositeTaskSource {
...@@ -417,6 +418,16 @@ export namespace Task { ...@@ -417,6 +418,16 @@ export namespace Task {
} }
} }
export function getWorkspaceFolder(task: Task): WorkspaceFolder | undefined {
if (CustomTask.is(task)) {
return task._source.config.workspaceFolder;
} else if (ContributedTask.is(task)) {
return task._source.workspaceFolder;
} else {
return undefined;
}
}
export function getTelemetryKind(task: Task): string { export function getTelemetryKind(task: Task): string {
if (ContributedTask.is(task)) { if (ContributedTask.is(task)) {
return 'extension'; return 'extension';
......
...@@ -667,7 +667,7 @@ class TaskService extends EventEmitter implements ITaskService { ...@@ -667,7 +667,7 @@ class TaskService extends EventEmitter implements ITaskService {
private _workspaceFolders: WorkspaceFolder[]; private _workspaceFolders: WorkspaceFolder[];
private _providers: Map<number, ITaskProvider>; private _providers: Map<number, ITaskProvider>;
private _workspaceTasksPromise: TPromise<WorkspaceTaskResult>; private _workspaceTasksPromise: TPromise<Map<string, WorkspaceFolderTaskResult>>;
private _taskSystem: ITaskSystem; private _taskSystem: ITaskSystem;
private _taskSystemListeners: IDisposable[]; private _taskSystemListeners: IDisposable[];
...@@ -719,22 +719,14 @@ class TaskService extends EventEmitter implements ITaskService { ...@@ -719,22 +719,14 @@ class TaskService extends EventEmitter implements ITaskService {
if (!this._taskSystem && !this._workspaceTasksPromise) { if (!this._taskSystem && !this._workspaceTasksPromise) {
return; return;
} }
this.updateWorkspaceTasks(); let folderSetup = this.computeWorkspaceFolders();
if (!this._taskSystem) { if (this._executionEngine !== folderSetup[1] && this._taskSystem && this._taskSystem.getActiveTasks().length > 0) {
return;
}
let currentExecutionEngine = this._taskSystem instanceof TerminalTaskSystem
? ExecutionEngine.Terminal
: this._taskSystem instanceof ProcessTaskSystem
? ExecutionEngine.Process
: ExecutionEngine._default;
if (currentExecutionEngine !== this.getExecutionEngine()) {
this.messageService.show( this.messageService.show(
Severity.Info, Severity.Info,
{ {
message: nls.localize( message: nls.localize(
'TaskSystem.noHotSwap', 'TaskSystem.noHotSwap',
'Changing the task execution engine requires to reload the Window' 'Changing the task execution engine with an active task running requires to reload the Window'
), ),
actions: [ actions: [
new ReloadWindowAction(ReloadWindowAction.ID, ReloadWindowAction.LABEL, this._windowServive), new ReloadWindowAction(ReloadWindowAction.ID, ReloadWindowAction.LABEL, this._windowServive),
...@@ -742,9 +734,17 @@ class TaskService extends EventEmitter implements ITaskService { ...@@ -742,9 +734,17 @@ class TaskService extends EventEmitter implements ITaskService {
] ]
} }
); );
return;
} }
this._workspaceFolders = folderSetup[0];
this._executionEngine = folderSetup[1];
this._schemaVersion = folderSetup[2];
this.updateWorkspaceTasks();
}); });
this.updateWorkspaceFolders(); let folderSetup = this.computeWorkspaceFolders();
this._workspaceFolders = folderSetup[0];
this._executionEngine = folderSetup[1];
this._schemaVersion = folderSetup[2];
lifecycleService.onWillShutdown(event => event.veto(this.beforeShutdown())); lifecycleService.onWillShutdown(event => event.veto(this.beforeShutdown()));
this.registerCommands(); this.registerCommands();
} }
...@@ -823,20 +823,14 @@ class TaskService extends EventEmitter implements ITaskService { ...@@ -823,20 +823,14 @@ class TaskService extends EventEmitter implements ITaskService {
} }
public getTask(identifier: string): TPromise<Task> { public getTask(identifier: string): TPromise<Task> {
return this.getTaskSets().then((sets) => { return this.getAllTasks().then((tasks) => {
let resolver = this.createResolver(sets); let resolver = this.createResolver(tasks);
return resolver.resolve(identifier); return resolver.resolve(identifier);
}); });
} }
public tasks(): TPromise<Task[]> { public tasks(): TPromise<Task[]> {
return this.getTaskSets().then((sets) => { return this.getAllTasks();
let result: Task[] = [];
for (let set of sets) {
result.push(...set.tasks);
}
return result;
});
}; };
public isActive(): TPromise<boolean> { public isActive(): TPromise<boolean> {
...@@ -890,10 +884,10 @@ class TaskService extends EventEmitter implements ITaskService { ...@@ -890,10 +884,10 @@ class TaskService extends EventEmitter implements ITaskService {
} }
public build(): TPromise<ITaskSummary> { public build(): TPromise<ITaskSummary> {
return this.getTaskSets().then((values) => { return this.getAllTasks().then((tasks) => {
let runnable = this.createRunnableTask(values, TaskGroup.Build); let runnable = this.createRunnableTask(tasks, TaskGroup.Build);
if (!runnable || !runnable.task) { if (!runnable || !runnable.task) {
if (this.getJsonSchemaVersion() === JsonSchemaVersion.V0_1_0) { if (this._schemaVersion === JsonSchemaVersion.V0_1_0) {
throw new TaskError(Severity.Info, nls.localize('TaskService.noBuildTask1', 'No build task defined. Mark a task with \'isBuildCommand\' in the tasks.json file.'), TaskErrors.NoBuildTask); throw new TaskError(Severity.Info, nls.localize('TaskService.noBuildTask1', 'No build task defined. Mark a task with \'isBuildCommand\' in the tasks.json file.'), TaskErrors.NoBuildTask);
} else { } else {
throw new TaskError(Severity.Info, nls.localize('TaskService.noBuildTask2', 'No build task defined. Mark a task with as a \'build\' group in the tasks.json file.'), TaskErrors.NoBuildTask); throw new TaskError(Severity.Info, nls.localize('TaskService.noBuildTask2', 'No build task defined. Mark a task with as a \'build\' group in the tasks.json file.'), TaskErrors.NoBuildTask);
...@@ -915,10 +909,10 @@ class TaskService extends EventEmitter implements ITaskService { ...@@ -915,10 +909,10 @@ class TaskService extends EventEmitter implements ITaskService {
} }
public runTest(): TPromise<ITaskSummary> { public runTest(): TPromise<ITaskSummary> {
return this.getTaskSets().then((values) => { return this.getAllTasks().then((tasks) => {
let runnable = this.createRunnableTask(values, TaskGroup.Test); let runnable = this.createRunnableTask(tasks, TaskGroup.Test);
if (!runnable || !runnable.task) { if (!runnable || !runnable.task) {
if (this.getJsonSchemaVersion() === JsonSchemaVersion.V0_1_0) { if (this._schemaVersion === JsonSchemaVersion.V0_1_0) {
throw new TaskError(Severity.Info, nls.localize('TaskService.noTestTask1', 'No test task defined. Mark a task with \'isTestCommand\' in the tasks.json file.'), TaskErrors.NoTestTask); throw new TaskError(Severity.Info, nls.localize('TaskService.noTestTask1', 'No test task defined. Mark a task with \'isTestCommand\' in the tasks.json file.'), TaskErrors.NoTestTask);
} else { } else {
throw new TaskError(Severity.Info, nls.localize('TaskService.noTestTask2', 'No test task defined. Mark a task with as a \'test\' group in the tasks.json file.'), TaskErrors.NoTestTask); throw new TaskError(Severity.Info, nls.localize('TaskService.noTestTask2', 'No test task defined. Mark a task with as a \'test\' group in the tasks.json file.'), TaskErrors.NoTestTask);
...@@ -932,8 +926,8 @@ class TaskService extends EventEmitter implements ITaskService { ...@@ -932,8 +926,8 @@ class TaskService extends EventEmitter implements ITaskService {
} }
public run(task: string | Task, options?: RunOptions): TPromise<ITaskSummary> { public run(task: string | Task, options?: RunOptions): TPromise<ITaskSummary> {
return this.getTaskSets().then((values) => { return this.getAllTasks().then((tasks) => {
let resolver = this.createResolver(values); let resolver = this.createResolver(tasks);
let requested: string; let requested: string;
let toExecute: Task; let toExecute: Task;
if (Types.isString(task)) { if (Types.isString(task)) {
...@@ -1042,13 +1036,11 @@ class TaskService extends EventEmitter implements ITaskService { ...@@ -1042,13 +1036,11 @@ class TaskService extends EventEmitter implements ITaskService {
} }
public getTasksForGroup(group: string): TPromise<Task[]> { public getTasksForGroup(group: string): TPromise<Task[]> {
return this.getTaskSets().then((values) => { return this.getAllTasks().then((tasks) => {
let result: Task[] = []; let result: Task[] = [];
for (let value of values) { for (let task of tasks) {
for (let task of value.tasks) { if (task.group === group) {
if (task.group === group) { result.push(task);
result.push(task);
}
} }
} }
return result; return result;
...@@ -1056,11 +1048,15 @@ class TaskService extends EventEmitter implements ITaskService { ...@@ -1056,11 +1048,15 @@ class TaskService extends EventEmitter implements ITaskService {
} }
public canCustomize(): boolean { public canCustomize(): boolean {
return this.getJsonSchemaVersion() === JsonSchemaVersion.V2_0_0; return this._schemaVersion === JsonSchemaVersion.V2_0_0;
} }
public customize(task: ContributedTask | CustomTask, properties?: CustomizationProperties, openConfig?: boolean): TPromise<void> { public customize(task: ContributedTask | CustomTask, properties?: CustomizationProperties, openConfig?: boolean): TPromise<void> {
let configuration = this.getConfiguration(); let workspaceFolder = Task.getWorkspaceFolder(task);
if (!workspaceFolder) {
return TPromise.as<void>(undefined);
}
let configuration = this.getConfiguration(workspaceFolder);
if (configuration.hasParseErrors) { if (configuration.hasParseErrors) {
this.messageService.show(Severity.Warning, nls.localize('customizeParseErrors', 'The current task configuration has errors. Please fix the errors first before customizing a task.')); this.messageService.show(Severity.Warning, nls.localize('customizeParseErrors', 'The current task configuration has errors. Please fix the errors first before customizing a task.'));
return TPromise.as<void>(undefined); return TPromise.as<void>(undefined);
...@@ -1166,6 +1162,7 @@ class TaskService extends EventEmitter implements ITaskService { ...@@ -1166,6 +1162,7 @@ class TaskService extends EventEmitter implements ITaskService {
} }
public openConfig(task: CustomTask): TPromise<void> { public openConfig(task: CustomTask): TPromise<void> {
// @ToDo need to adopt since this is not working anymore
let resource = this.contextService.toResource(task._source.config.file); let resource = this.contextService.toResource(task._source.config.file);
return this.editorService.openEditor({ return this.editorService.openEditor({
resource: resource, resource: resource,
...@@ -1176,26 +1173,24 @@ class TaskService extends EventEmitter implements ITaskService { ...@@ -1176,26 +1173,24 @@ class TaskService extends EventEmitter implements ITaskService {
}, false).then(() => undefined); }, false).then(() => undefined);
} }
private createRunnableTask(sets: TaskSet[], group: TaskGroup): { task: Task; resolver: ITaskResolver } { private createRunnableTask(tasks: Task[], group: TaskGroup): { task: Task; resolver: ITaskResolver } {
let idMap: IStringDictionary<Task> = Object.create(null); let idMap: IStringDictionary<Task> = Object.create(null);
let labelMap: IStringDictionary<Task> = Object.create(null); let labelMap: IStringDictionary<Task> = Object.create(null);
let identifierMap: IStringDictionary<Task> = Object.create(null); let identifierMap: IStringDictionary<Task> = Object.create(null);
let workspaceTasks: Task[] = []; let workspaceTasks: Task[] = [];
let extensionTasks: Task[] = []; let extensionTasks: Task[] = [];
sets.forEach((set) => { tasks.forEach((task) => {
set.tasks.forEach((task) => { idMap[task._id] = task;
idMap[task._id] = task; labelMap[task._label] = task;
labelMap[task._label] = task; identifierMap[task.identifier] = task;
identifierMap[task.identifier] = task; if (group && task.group === group) {
if (group && task.group === group) { if (task._source.kind === TaskSourceKind.Workspace) {
if (task._source.kind === TaskSourceKind.Workspace) { workspaceTasks.push(task);
workspaceTasks.push(task); } else {
} else { extensionTasks.push(task);
extensionTasks.push(task);
}
} }
}); }
}); });
let resolver: ITaskResolver = { let resolver: ITaskResolver = {
resolve: (id: string) => { resolve: (id: string) => {
...@@ -1231,15 +1226,13 @@ class TaskService extends EventEmitter implements ITaskService { ...@@ -1231,15 +1226,13 @@ class TaskService extends EventEmitter implements ITaskService {
} }
} }
private createResolver(sets: TaskSet[]): ITaskResolver { private createResolver(tasks: Task[]): ITaskResolver {
let labelMap: IStringDictionary<Task> = Object.create(null); let labelMap: IStringDictionary<Task> = Object.create(null);
let identifierMap: IStringDictionary<Task> = Object.create(null); let identifierMap: IStringDictionary<Task> = Object.create(null);
sets.forEach((set) => { tasks.forEach((task) => {
set.tasks.forEach((task) => { labelMap[task._label] = task;
labelMap[task._label] = task; identifierMap[task.identifier] = task;
identifierMap[task.identifier] = task;
});
}); });
return { return {
resolve: (id: string) => { resolve: (id: string) => {
...@@ -1308,8 +1301,7 @@ class TaskService extends EventEmitter implements ITaskService { ...@@ -1308,8 +1301,7 @@ class TaskService extends EventEmitter implements ITaskService {
if (this._taskSystem) { if (this._taskSystem) {
return this._taskSystem; return this._taskSystem;
} }
let engine = this.getExecutionEngine(); if (this._executionEngine === ExecutionEngine.Terminal) {
if (engine === ExecutionEngine.Terminal) {
this._taskSystem = new TerminalTaskSystem( this._taskSystem = new TerminalTaskSystem(
this.terminalService, this.outputService, this.markerService, this.terminalService, this.outputService, this.markerService,
this.modelService, this.configurationResolverService, this.telemetryService, this.modelService, this.configurationResolverService, this.telemetryService,
...@@ -1331,7 +1323,7 @@ class TaskService extends EventEmitter implements ITaskService { ...@@ -1331,7 +1323,7 @@ class TaskService extends EventEmitter implements ITaskService {
return this._taskSystem; return this._taskSystem;
} }
private getTaskSets(): TPromise<TaskSet[]> { private getAllTasks(): TPromise<Task[]> {
return this.extensionService.activateByEvent('onCommand:workbench.action.tasks.runTask').then(() => { return this.extensionService.activateByEvent('onCommand:workbench.action.tasks.runTask').then(() => {
return new TPromise<TaskSet[]>((resolve, reject) => { return new TPromise<TaskSet[]>((resolve, reject) => {
let result: TaskSet[] = []; let result: TaskSet[] = [];
...@@ -1349,7 +1341,7 @@ class TaskService extends EventEmitter implements ITaskService { ...@@ -1349,7 +1341,7 @@ class TaskService extends EventEmitter implements ITaskService {
resolve(result); resolve(result);
} }
}; };
if (this.getJsonSchemaVersion() === JsonSchemaVersion.V2_0_0 && this._providers.size > 0) { if (this._schemaVersion === JsonSchemaVersion.V2_0_0 && this._providers.size > 0) {
this._providers.forEach((provider) => { this._providers.forEach((provider) => {
counter++; counter++;
provider.provideTasks().done(done, error); provider.provideTasks().done(done, error);
...@@ -1358,57 +1350,83 @@ class TaskService extends EventEmitter implements ITaskService { ...@@ -1358,57 +1350,83 @@ class TaskService extends EventEmitter implements ITaskService {
resolve(result); resolve(result);
} }
}); });
}).then((result) => { }).then((contributedTaskSets) => {
return this.getWorkspaceTasks().then((workspaceTaskResult) => { let result: Task[] = [];
let workspaceTasksToDelete: Task[] = []; let contributedTasks: Map<string, Task[]> = new Map();
let configurations = workspaceTaskResult.configurations; for (let set of contributedTaskSets) {
let legacyTaskConfigurations = workspaceTaskResult.set ? this.getLegacyTaskConfigurations(workspaceTaskResult.set) : undefined; for (let task of set.tasks) {
if (configurations || legacyTaskConfigurations) { if (!ContributedTask.is(task)) {
for (let set of result) { continue;
for (let i = 0; i < set.tasks.length; i++) { }
let task = set.tasks[i]; let workspaceFolder = task._source.workspaceFolder;
if (!ContributedTask.is(task)) { if (workspaceFolder) {
continue; let values = contributedTasks.get(workspaceFolder.uri.toString());
} if (!values) {
if (configurations) { values = [task];
let configuringTask = configurations.byIdentifier[task.defines._key]; contributedTasks.set(workspaceFolder.uri.toString(), values);
if (configuringTask) { } else {
set.tasks[i] = TaskConfig.createCustomTask(task, configuringTask); values.push(task);
}
} else {
result.push(task);
}
}
}
return this.getWorkspaceTasks().then((customTasks) => {
customTasks.forEach((folderTasks, key) => {
let contributed = contributedTasks.get(key);
if (!contributed) {
result.push(...folderTasks.set.tasks);
} else {
let configurations = folderTasks.configurations;
let legacyTaskConfigurations = folderTasks.set ? this.getLegacyTaskConfigurations(folderTasks.set) : undefined;
let customTasksToDelete: Task[] = [];
if (configurations || legacyTaskConfigurations) {
for (let task of contributed) {
if (!ContributedTask.is(task)) {
continue; continue;
} }
if (configurations) {
let configuringTask = configurations.byIdentifier[task.defines._key];
if (configuringTask) {
result.push(TaskConfig.createCustomTask(task, configuringTask));
continue;
}
} 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);
}
} }
if (legacyTaskConfigurations) { }
let configuringTask = legacyTaskConfigurations[task.defines._key]; if (customTasksToDelete.length > 0) {
if (configuringTask) { let toDelete = customTasksToDelete.reduce<IStringDictionary<boolean>>((map, task) => {
set.tasks[i] = TaskConfig.createCustomTask(task, configuringTask); map[task._id] = true;
workspaceTasksToDelete.push(configuringTask); return map;
set.tasks[i] = configuringTask; }, Object.create(null));
for (let task of folderTasks.set.tasks) {
if (toDelete[task._id]) {
continue; continue;
} }
result.push(task);
} }
} else {
result.push(...folderTasks.set.tasks);
} }
} }
} });
if (workspaceTaskResult.set) {
if (workspaceTasksToDelete.length > 0) {
let tasks = workspaceTaskResult.set.tasks;
let newSet: TaskSet = {
extension: workspaceTaskResult.set.extension,
tasks: []
};
let toDelete = workspaceTasksToDelete.reduce<IStringDictionary<boolean>>((map, task) => {
map[task._id] = true;
return map;
}, Object.create(null));
newSet.tasks = tasks.filter(task => !toDelete[task._id]);
result.push(newSet);
} else {
result.push(workspaceTaskResult.set);
}
}
return result; return result;
}, () => { }, () => {
// If we can't read the tasks.json file provide at least the contributed tasks // If we can't read the tasks.json file provide at least the contributed tasks
let result: Task[] = [];
for (let set of contributedTaskSets) {
result.push(...set.tasks);
}
return result; return result;
}); });
}); });
...@@ -1440,7 +1458,7 @@ class TaskService extends EventEmitter implements ITaskService { ...@@ -1440,7 +1458,7 @@ class TaskService extends EventEmitter implements ITaskService {
return result; return result;
} }
private getWorkspaceTasks(): TPromise<WorkspaceTaskResult> { private getWorkspaceTasks(): TPromise<Map<string, WorkspaceFolderTaskResult>> {
if (this._workspaceTasksPromise) { if (this._workspaceTasksPromise) {
return this._workspaceTasksPromise; return this._workspaceTasksPromise;
} }
...@@ -1450,9 +1468,12 @@ class TaskService extends EventEmitter implements ITaskService { ...@@ -1450,9 +1468,12 @@ class TaskService extends EventEmitter implements ITaskService {
private updateWorkspaceTasks(): void { private updateWorkspaceTasks(): void {
this._workspaceTasksPromise = this.computeWorkspaceTasks().then(value => { this._workspaceTasksPromise = this.computeWorkspaceTasks().then(value => {
this._configHasErrors = value.hasErrors; if (this._executionEngine === ExecutionEngine.Process && this._taskSystem instanceof ProcessTaskSystem) {
if (this._taskSystem instanceof ProcessTaskSystem) { // We can only have a process engine if we have one folder.
this._taskSystem.hasErrors(this._configHasErrors); value.forEach((value) => {
this._configHasErrors = value.hasErrors;
(this._taskSystem as ProcessTaskSystem).hasErrors(this._configHasErrors);
});
} }
return value; return value;
}); });
...@@ -1640,20 +1661,21 @@ class TaskService extends EventEmitter implements ITaskService { ...@@ -1640,20 +1661,21 @@ class TaskService extends EventEmitter implements ITaskService {
} }
} }
private updateWorkspaceFolders(): void { private computeWorkspaceFolders(): [WorkspaceFolder[], ExecutionEngine, JsonSchemaVersion] {
let workspaceFolders: WorkspaceFolder[] = [];
let executionEngine = ExecutionEngine.Terminal;
let schemaVersion = JsonSchemaVersion.V2_0_0;
if (this.contextService.hasFolderWorkspace()) { if (this.contextService.hasFolderWorkspace()) {
let workspaceFolder = { uri: this.contextService.getWorkspace().roots[0] }; let workspaceFolder: WorkspaceFolder = { uri: this.contextService.getWorkspace().roots[0] };
this._workspaceFolders = [workspaceFolder]; workspaceFolders.push(workspaceFolder);
this._executionEngine = this.computeExecutionEngine(workspaceFolder); executionEngine = this.computeExecutionEngine(workspaceFolder);
this._schemaVersion = this.computeJsonSchemaVersion(workspaceFolder); schemaVersion = this.computeJsonSchemaVersion(workspaceFolder);
} else if (this.contextService.hasMultiFolderWorkspace()) { } else if (this.contextService.hasMultiFolderWorkspace()) {
this._executionEngine = ExecutionEngine.Terminal;
this._schemaVersion = JsonSchemaVersion.V2_0_0;
this._workspaceFolders = [];
for (let folder of this.contextService.getWorkspace().roots) { for (let folder of this.contextService.getWorkspace().roots) {
let workspaceFolder = { uri: folder }; let workspaceFolder = { uri: folder };
if (this._schemaVersion === this.computeJsonSchemaVersion(workspaceFolder)) { if (this._schemaVersion === this.computeJsonSchemaVersion(workspaceFolder)) {
this._workspaceFolders.push(workspaceFolder); workspaceFolders.push(workspaceFolder);
} else { } else {
this._outputChannel.append(nls.localize( this._outputChannel.append(nls.localize(
'taskService.ignoreingFolder', 'taskService.ignoreingFolder',
...@@ -1661,11 +1683,8 @@ class TaskService extends EventEmitter implements ITaskService { ...@@ -1661,11 +1683,8 @@ class TaskService extends EventEmitter implements ITaskService {
folder.fsPath)); folder.fsPath));
} }
} }
} else {
this._workspaceFolders = [];
this._executionEngine = ExecutionEngine.Terminal;
this._schemaVersion = JsonSchemaVersion.V2_0_0;
} }
return [workspaceFolders, executionEngine, schemaVersion];
} }
private computeExecutionEngine(workspaceFolder: WorkspaceFolder): ExecutionEngine { private computeExecutionEngine(workspaceFolder: WorkspaceFolder): ExecutionEngine {
...@@ -1727,7 +1746,7 @@ class TaskService extends EventEmitter implements ITaskService { ...@@ -1727,7 +1746,7 @@ class TaskService extends EventEmitter implements ITaskService {
if (this._taskSystem) { if (this._taskSystem) {
return this._taskSystem instanceof TerminalTaskSystem; return this._taskSystem instanceof TerminalTaskSystem;
} }
return this.getExecutionEngine() === ExecutionEngine.Terminal; return this._executionEngine === ExecutionEngine.Terminal;
} }
private hasDetectorSupport(config: TaskConfig.ExternalTaskRunnerConfiguration): boolean { private hasDetectorSupport(config: TaskConfig.ExternalTaskRunnerConfiguration): boolean {
...@@ -1939,7 +1958,7 @@ class TaskService extends EventEmitter implements ITaskService { ...@@ -1939,7 +1958,7 @@ class TaskService extends EventEmitter implements ITaskService {
if (!this.canRunCommand()) { if (!this.canRunCommand()) {
return; return;
} }
if (this.getJsonSchemaVersion() === JsonSchemaVersion.V0_1_0) { if (this._schemaVersion === JsonSchemaVersion.V0_1_0) {
this.build(); this.build();
return; return;
} }
...@@ -1982,7 +2001,7 @@ class TaskService extends EventEmitter implements ITaskService { ...@@ -1982,7 +2001,7 @@ class TaskService extends EventEmitter implements ITaskService {
if (!this.canRunCommand()) { if (!this.canRunCommand()) {
return; return;
} }
if (this.getJsonSchemaVersion() === JsonSchemaVersion.V0_1_0) { if (this._schemaVersion === JsonSchemaVersion.V0_1_0) {
this.runTest(); this.runTest();
return; return;
} }
...@@ -2088,7 +2107,7 @@ class TaskService extends EventEmitter implements ITaskService { ...@@ -2088,7 +2107,7 @@ class TaskService extends EventEmitter implements ITaskService {
if (!this.canRunCommand()) { if (!this.canRunCommand()) {
return; return;
} }
if (this.getJsonSchemaVersion() === JsonSchemaVersion.V2_0_0) { if (this._schemaVersion === JsonSchemaVersion.V2_0_0) {
this.tasks().then((tasks => { this.tasks().then((tasks => {
if (tasks.length === 0) { if (tasks.length === 0) {
this.configureBuildTask().run(); this.configureBuildTask().run();
...@@ -2123,7 +2142,7 @@ class TaskService extends EventEmitter implements ITaskService { ...@@ -2123,7 +2142,7 @@ class TaskService extends EventEmitter implements ITaskService {
if (!this.canRunCommand()) { if (!this.canRunCommand()) {
return; return;
} }
if (this.getJsonSchemaVersion() === JsonSchemaVersion.V2_0_0) { if (this._schemaVersion === JsonSchemaVersion.V2_0_0) {
this.tasks().then((tasks => { this.tasks().then((tasks => {
if (tasks.length === 0) { if (tasks.length === 0) {
this.configureAction().run(); this.configureAction().run();
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
'use strict'; 'use strict';
import URI from 'vs/base/common/uri';
import * as assert from 'assert'; import * as assert from 'assert';
import Severity from 'vs/base/common/severity'; import Severity from 'vs/base/common/severity';
import * as UUID from 'vs/base/common/uuid'; import * as UUID from 'vs/base/common/uuid';
...@@ -347,7 +348,7 @@ class PatternBuilder { ...@@ -347,7 +348,7 @@ class PatternBuilder {
function testDefaultProblemMatcher(external: ExternalTaskRunnerConfiguration, resolved: number) { function testDefaultProblemMatcher(external: ExternalTaskRunnerConfiguration, resolved: number) {
let reporter = new ProblemReporter(); let reporter = new ProblemReporter();
let result = parse(external, { uri: undefined }, reporter); let result = parse({ uri: URI.file('/Workspace/folderOne') }, external, reporter);
assert.ok(!reporter.receivedMessage); assert.ok(!reporter.receivedMessage);
assert.strictEqual(result.custom.length, 1); assert.strictEqual(result.custom.length, 1);
let task = result.custom[0]; let task = result.custom[0];
...@@ -358,7 +359,7 @@ function testDefaultProblemMatcher(external: ExternalTaskRunnerConfiguration, re ...@@ -358,7 +359,7 @@ function testDefaultProblemMatcher(external: ExternalTaskRunnerConfiguration, re
function testConfiguration(external: ExternalTaskRunnerConfiguration, builder: ConfiguationBuilder): void { function testConfiguration(external: ExternalTaskRunnerConfiguration, builder: ConfiguationBuilder): void {
builder.done(); builder.done();
let reporter = new ProblemReporter(); let reporter = new ProblemReporter();
let result = parse(external, { uri: undefined }, reporter); let result = parse({ uri: URI.file('/Workspace/folderOne') }, external, reporter);
if (reporter.receivedMessage) { if (reporter.receivedMessage) {
assert.ok(false, reporter.lastMessage); assert.ok(false, reporter.lastMessage);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册