mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-27 03:54:24 +01:00
Adding support for TaskProvider.resolveTask (#71027)
* Adding support for TaskProvider.resolveTask. * Reorganize task grouping and resolution async code for readability. * Made small changes and implmented resolveTask for gulp
This commit is contained in:
@@ -16,7 +16,7 @@ import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||
|
||||
import {
|
||||
ContributedTask, KeyedTaskIdentifier, TaskExecution, Task, TaskEvent, TaskEventKind,
|
||||
ContributedTask, ConfiguringTask, KeyedTaskIdentifier, TaskExecution, Task, TaskEvent, TaskEventKind,
|
||||
PresentationOptions, CommandOptions, CommandConfiguration, RuntimeType, CustomTask, TaskScope, TaskSource,
|
||||
TaskSourceKind, ExtensionTaskSource, RunOptions, TaskSet, TaskDefinition
|
||||
} from 'vs/workbench/contrib/tasks/common/tasks';
|
||||
@@ -304,8 +304,8 @@ namespace TaskHandleDTO {
|
||||
}
|
||||
|
||||
namespace TaskDTO {
|
||||
export function from(task: Task): TaskDTO | undefined {
|
||||
if (task === undefined || task === null || (!CustomTask.is(task) && !ContributedTask.is(task))) {
|
||||
export function from(task: Task | ConfiguringTask): TaskDTO | undefined {
|
||||
if (task === undefined || task === null || (!CustomTask.is(task) && !ContributedTask.is(task) && !ConfiguringTask.is(task))) {
|
||||
return undefined;
|
||||
}
|
||||
const result: TaskDTO = {
|
||||
@@ -314,7 +314,7 @@ namespace TaskDTO {
|
||||
definition: TaskDefinitionDTO.from(task.getDefinition()),
|
||||
source: TaskSourceDTO.from(task._source),
|
||||
execution: undefined,
|
||||
presentationOptions: task.command ? TaskPresentationOptionsDTO.from(task.command.presentation) : undefined,
|
||||
presentationOptions: !ConfiguringTask.is(task) && task.command ? TaskPresentationOptionsDTO.from(task.command.presentation) : undefined,
|
||||
isBackground: task.configurationProperties.isBackground,
|
||||
problemMatchers: [],
|
||||
hasDefinedMatchers: ContributedTask.is(task) ? task.hasDefinedMatchers : false,
|
||||
@@ -323,7 +323,7 @@ namespace TaskDTO {
|
||||
if (task.configurationProperties.group) {
|
||||
result.group = task.configurationProperties.group;
|
||||
}
|
||||
if (task.command) {
|
||||
if (!ConfiguringTask.is(task) && task.command) {
|
||||
if (task.command.runtime === RuntimeType.Process) {
|
||||
result.execution = ProcessExecutionDTO.from(task.command);
|
||||
} else if (task.command.runtime === RuntimeType.Shell) {
|
||||
@@ -442,7 +442,7 @@ export class MainThreadTask implements MainThreadTaskShape {
|
||||
});
|
||||
}
|
||||
|
||||
public $registerTaskProvider(handle: number): Promise<void> {
|
||||
public $registerTaskProvider(handle: number, type: string): Promise<void> {
|
||||
const provider: ITaskProvider = {
|
||||
provideTasks: (validTypes: IStringDictionary<boolean>) => {
|
||||
return Promise.resolve(this._proxy.$provideTasks(handle, validTypes)).then((value) => {
|
||||
@@ -460,9 +460,24 @@ export class MainThreadTask implements MainThreadTaskShape {
|
||||
extension: value.extension
|
||||
} as TaskSet;
|
||||
});
|
||||
},
|
||||
resolveTask: (task: ConfiguringTask) => {
|
||||
const dto = TaskDTO.from(task);
|
||||
|
||||
if (dto) {
|
||||
dto.name = ((dto.name === undefined) ? '' : dto.name); // Using an empty name causes the name to default to the one given by the provider.
|
||||
return Promise.resolve(this._proxy.$resolveTask(handle, dto)).then(resolvedTask => {
|
||||
if (resolvedTask) {
|
||||
return TaskDTO.to(resolvedTask, this._workspaceContextServer, true);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
return Promise.resolve<ContributedTask | undefined>(undefined);
|
||||
}
|
||||
};
|
||||
const disposable = this._taskService.registerTaskProvider(provider);
|
||||
const disposable = this._taskService.registerTaskProvider(provider, type);
|
||||
this._providers.set(handle, { disposable, provider });
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
@@ -635,7 +635,7 @@ export interface MainThreadSearchShape extends IDisposable {
|
||||
|
||||
export interface MainThreadTaskShape extends IDisposable {
|
||||
$createTaskId(task: tasks.TaskDTO): Promise<string>;
|
||||
$registerTaskProvider(handle: number): Promise<void>;
|
||||
$registerTaskProvider(handle: number, type: string): Promise<void>;
|
||||
$unregisterTaskProvider(handle: number): Promise<void>;
|
||||
$fetchTasks(filter?: tasks.TaskFilterDTO): Promise<tasks.TaskDTO[]>;
|
||||
$executeTask(task: tasks.TaskHandleDTO | tasks.TaskDTO): Promise<tasks.TaskExecutionDTO>;
|
||||
@@ -1183,6 +1183,7 @@ export interface ExtHostSCMShape {
|
||||
|
||||
export interface ExtHostTaskShape {
|
||||
$provideTasks(handle: number, validTypes: { [key: string]: boolean; }): Thenable<tasks.TaskSetDTO>;
|
||||
$resolveTask(handle: number, taskDTO: tasks.TaskDTO): Thenable<tasks.TaskDTO | undefined>;
|
||||
$onDidStartTask(execution: tasks.TaskExecutionDTO, terminalId: number): void;
|
||||
$onDidStartTaskProcess(value: tasks.TaskProcessStartedDTO): void;
|
||||
$onDidEndTaskProcess(value: tasks.TaskProcessEndedDTO): void;
|
||||
|
||||
@@ -675,7 +675,7 @@ export function createApiFactory(
|
||||
return extHostDocumentContentProviders.registerTextDocumentContentProvider(scheme, provider);
|
||||
},
|
||||
registerTaskProvider: (type: string, provider: vscode.TaskProvider) => {
|
||||
return extHostTask.registerTaskProvider(extension, provider);
|
||||
return extHostTask.registerTaskProvider(extension, type, provider);
|
||||
},
|
||||
registerFileSystemProvider(scheme, provider, options) {
|
||||
return extHostFileSystem.registerFileSystemProvider(scheme, provider, options);
|
||||
@@ -776,7 +776,7 @@ export function createApiFactory(
|
||||
|
||||
const tasks: typeof vscode.tasks = {
|
||||
registerTaskProvider: (type: string, provider: vscode.TaskProvider) => {
|
||||
return extHostTask.registerTaskProvider(extension, provider);
|
||||
return extHostTask.registerTaskProvider(extension, type, provider);
|
||||
},
|
||||
fetchTasks: (filter?: vscode.TaskFilter): Thenable<vscode.Task[]> => {
|
||||
return extHostTask.fetchTasks(filter);
|
||||
|
||||
@@ -347,6 +347,7 @@ namespace TaskExecutionDTO {
|
||||
}
|
||||
|
||||
interface HandlerData {
|
||||
type: string;
|
||||
provider: vscode.TaskProvider;
|
||||
extension: IExtensionDescription;
|
||||
}
|
||||
@@ -492,13 +493,13 @@ export class ExtHostTask implements ExtHostTaskShape {
|
||||
this._activeCustomExecutions = new Map<string, CustomExecutionData>();
|
||||
}
|
||||
|
||||
public registerTaskProvider(extension: IExtensionDescription, provider: vscode.TaskProvider): vscode.Disposable {
|
||||
public registerTaskProvider(extension: IExtensionDescription, type: string, provider: vscode.TaskProvider): vscode.Disposable {
|
||||
if (!provider) {
|
||||
return new types.Disposable(() => { });
|
||||
}
|
||||
const handle = this.nextHandle();
|
||||
this._handlers.set(handle, { provider, extension });
|
||||
this._proxy.$registerTaskProvider(handle);
|
||||
this._handlers.set(handle, { type, provider, extension });
|
||||
this._proxy.$registerTaskProvider(handle, type);
|
||||
return new types.Disposable(() => {
|
||||
this._handlers.delete(handle);
|
||||
this._proxy.$unregisterTaskProvider(handle);
|
||||
@@ -652,15 +653,10 @@ export class ExtHostTask implements ExtHostTaskShape {
|
||||
taskDTOs.push(taskDTO);
|
||||
|
||||
if (CustomExecutionDTO.is(taskDTO.execution)) {
|
||||
taskIdPromises.push(new Promise((resolve) => {
|
||||
// The ID is calculated on the main thread task side, so, let's call into it here.
|
||||
// We need the task id's pre-computed for custom task executions because when OnDidStartTask
|
||||
// is invoked, we have to be able to map it back to our data.
|
||||
this._proxy.$createTaskId(taskDTO).then((taskId) => {
|
||||
this._providedCustomExecutions.set(taskId, new CustomExecutionData(<vscode.CustomExecution>(<vscode.Task2>task).execution2, this._terminalService));
|
||||
resolve();
|
||||
});
|
||||
}));
|
||||
// The ID is calculated on the main thread task side, so, let's call into it here.
|
||||
// We need the task id's pre-computed for custom task executions because when OnDidStartTask
|
||||
// is invoked, we have to be able to map it back to our data.
|
||||
taskIdPromises.push(this.addCustomExecution(taskDTO, <vscode.Task2>task));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -680,6 +676,38 @@ export class ExtHostTask implements ExtHostTaskShape {
|
||||
});
|
||||
}
|
||||
|
||||
public async $resolveTask(handle: number, taskDTO: TaskDTO): Promise<TaskDTO | undefined> {
|
||||
const handler = this._handlers.get(handle);
|
||||
if (!handler) {
|
||||
return Promise.reject(new Error('no handler found'));
|
||||
}
|
||||
|
||||
if (taskDTO.definition.type !== handler.type) {
|
||||
throw new Error(`Unexpected: Task of type [${taskDTO.definition.type}] cannot be resolved by provider of type [${handler.type}].`);
|
||||
}
|
||||
|
||||
const task = await TaskDTO.to(taskDTO, this._workspaceProvider);
|
||||
if (!task) {
|
||||
throw new Error('Unexpected: Task cannot be resolved.');
|
||||
}
|
||||
|
||||
const resolvedTask = await handler.provider.resolveTask(task, CancellationToken.None);
|
||||
if (!resolvedTask) {
|
||||
return;
|
||||
}
|
||||
|
||||
const resolvedTaskDTO: TaskDTO | undefined = TaskDTO.from(resolvedTask, handler.extension);
|
||||
if (!resolvedTaskDTO) {
|
||||
throw new Error('Unexpected: Task cannot be resolved.');
|
||||
}
|
||||
|
||||
if (CustomExecutionDTO.is(resolvedTaskDTO.execution)) {
|
||||
await this.addCustomExecution(taskDTO, <vscode.Task2>task);
|
||||
}
|
||||
|
||||
return resolvedTaskDTO;
|
||||
}
|
||||
|
||||
public async $resolveVariables(uriComponents: UriComponents, toResolve: { process?: { name: string; cwd?: string; path?: string }, variables: string[] }): Promise<{ process?: string, variables: { [key: string]: string; } }> {
|
||||
const configProvider = await this._configurationService.getConfigProvider();
|
||||
const uri: URI = URI.revive(uriComponents);
|
||||
@@ -725,6 +753,11 @@ export class ExtHostTask implements ExtHostTaskShape {
|
||||
return this._handleCounter++;
|
||||
}
|
||||
|
||||
private async addCustomExecution(taskDTO: TaskDTO, task: vscode.Task2): Promise<void> {
|
||||
const taskId = await this._proxy.$createTaskId(taskDTO);
|
||||
this._providedCustomExecutions.set(taskId, new CustomExecutionData(<vscode.CustomExecution>(<vscode.Task2>task).execution2, this._terminalService));
|
||||
}
|
||||
|
||||
private async getTaskExecution(execution: TaskExecutionDTO | string, task?: vscode.Task): Promise<TaskExecutionImpl> {
|
||||
if (typeof execution === 'string') {
|
||||
const taskExecution = this._taskExecutions.get(execution);
|
||||
|
||||
Reference in New Issue
Block a user