Skip to content

Commit

Permalink
Ensure tasks are resolved when run from extension host (#101904)
Browse files Browse the repository at this point in the history
Related to #101884
  • Loading branch information
alexr00 committed Jul 8, 2020
1 parent 49b121d commit d5e9aa0
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 13 deletions.
47 changes: 37 additions & 10 deletions src/vs/workbench/api/browser/mainThreadTask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -534,20 +534,47 @@ export class MainThreadTask implements MainThreadTaskShape {
}
}

public $executeTask(value: TaskDTO): Promise<TaskExecutionDTO> {
// Passing in a TaskHandleDTO will cause the task to get re-resolved, which is important for tasks are coming from the core,
// such as those gotten from a fetchTasks, since they can have missing configuration properties.
public $executeTask(value: TaskHandleDTO | TaskDTO): Promise<TaskExecutionDTO> {
return new Promise<TaskExecutionDTO>((resolve, reject) => {
const task = TaskDTO.to(value, this._workspaceContextServer, true)!;
this._taskService.run(task).then(undefined, reason => {
// eat the error, it has already been surfaced to the user and we don't care about it here
});
const result: TaskExecutionDTO = {
id: task._id,
task: TaskDTO.from(task)
};
resolve(result);
if (TaskHandleDTO.is(value)) {
const workspaceFolder = typeof value.workspaceFolder === 'string' ? value.workspaceFolder : this._workspaceContextServer.getWorkspaceFolder(URI.revive(value.workspaceFolder));
if (workspaceFolder) {
this._taskService.getTask(workspaceFolder, value.id, true).then((task: Task | undefined) => {
if (!task) {
reject(new Error('Task not found'));
} else {
this._taskService.run(task).then(undefined, reason => {
// eat the error, it has already been surfaced to the user and we don't care about it here
});
const result: TaskExecutionDTO = {
id: value.id,
task: TaskDTO.from(task)
};
resolve(result);
}
}, (_error) => {
reject(new Error('Task not found'));
});
} else {
reject(new Error('No workspace folder'));
}
} else {
const task = TaskDTO.to(value, this._workspaceContextServer, true)!;
this._taskService.run(task).then(undefined, reason => {
// eat the error, it has already been surfaced to the user and we don't care about it here
});
const result: TaskExecutionDTO = {
id: task._id,
task: TaskDTO.from(task)
};
resolve(result);
}
});
}


public $customExecutionComplete(id: string, result?: number): Promise<void> {
return new Promise<void>((resolve, reject) => {
this._taskService.getActiveTasks().then((tasks) => {
Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/api/common/extHost.protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -780,7 +780,7 @@ export interface MainThreadTaskShape extends IDisposable {
$unregisterTaskProvider(handle: number): Promise<void>;
$fetchTasks(filter?: tasks.TaskFilterDTO): Promise<tasks.TaskDTO[]>;
$getTaskExecution(value: tasks.TaskHandleDTO | tasks.TaskDTO): Promise<tasks.TaskExecutionDTO>;
$executeTask(task: tasks.TaskDTO): Promise<tasks.TaskExecutionDTO>;
$executeTask(task: tasks.TaskHandleDTO | tasks.TaskDTO): Promise<tasks.TaskExecutionDTO>;
$terminateTask(id: string): Promise<void>;
$registerTaskSystem(scheme: string, info: tasks.TaskSystemInfoDTO): void;
$customExecutionComplete(id: string, result?: number): Promise<void>;
Expand Down
5 changes: 3 additions & 2 deletions src/vs/workbench/api/node/extHostTask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,13 @@ export class ExtHostTask extends ExtHostTaskBase {
// We have a preserved ID. So the task didn't change.
if (tTask._id !== undefined) {
// Always get the task execution first to prevent timing issues when retrieving it later
const executionDTO = await this._proxy.$getTaskExecution(TaskHandleDTO.from(tTask));
const handleDto = TaskHandleDTO.from(tTask);
const executionDTO = await this._proxy.$getTaskExecution(handleDto);
if (executionDTO.task === undefined) {
throw new Error('Task from execution DTO is undefined');
}
const execution = await this.getTaskExecution(executionDTO, task);
this._proxy.$executeTask(executionDTO.task).catch(() => { /* The error here isn't actionable. */ });
this._proxy.$executeTask(handleDto).catch(() => { /* The error here isn't actionable. */ });
return execution;
} else {
const dto = TaskDTO.from(task, extension);
Expand Down

0 comments on commit d5e9aa0

Please sign in to comment.