diff --git a/src/vs/workbench/api/browser/mainThreadTask.ts b/src/vs/workbench/api/browser/mainThreadTask.ts index cc6abfc2eae..a779de27b58 100644 --- a/src/vs/workbench/api/browser/mainThreadTask.ts +++ b/src/vs/workbench/api/browser/mainThreadTask.ts @@ -668,6 +668,9 @@ export class MainThreadTask implements MainThreadTaskShape { }, getDefaultShellAndArgs: (): Promise<{ shell: string, args: string[] | string | undefined }> => { return Promise.resolve(this._proxy.$getDefaultShellAndArgs()); + }, + findExecutable: (command: string, cwd?: string, paths?: string[]): Promise => { + return this._proxy.$findExecutable(command, cwd, paths); } }); } diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 98dd1bcafcc..9ab54e1f7b0 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -1451,6 +1451,7 @@ export interface ExtHostTaskShape { $resolveVariables(workspaceFolder: UriComponents, toResolve: { process?: { name: string; cwd?: string; }, variables: string[]; }): Promise<{ process?: string; variables: { [key: string]: string; }; }>; $getDefaultShellAndArgs(): Thenable<{ shell: string, args: string[] | string | undefined; }>; $jsonTasksSupported(): Thenable; + $findExecutable(command: string, cwd?: string, paths?: string[]): Promise; } export interface IBreakpointDto { diff --git a/src/vs/workbench/api/common/extHostTask.ts b/src/vs/workbench/api/common/extHostTask.ts index 6bf128644e9..05d67b09eab 100644 --- a/src/vs/workbench/api/common/extHostTask.ts +++ b/src/vs/workbench/api/common/extHostTask.ts @@ -679,7 +679,9 @@ export abstract class ExtHostTaskBase implements ExtHostTaskShape, IExtHostTask } } - public abstract async $jsonTasksSupported(): Promise; + public abstract $jsonTasksSupported(): Promise; + + public abstract $findExecutable(command: string, cwd?: string | undefined, paths?: string[] | undefined): Promise; } export class WorkerExtHostTask extends ExtHostTaskBase { @@ -775,6 +777,10 @@ export class WorkerExtHostTask extends ExtHostTaskBase { public async $jsonTasksSupported(): Promise { return false; } + + public async $findExecutable(command: string, cwd?: string | undefined, paths?: string[] | undefined): Promise { + return undefined; + } } export const IExtHostTask = createDecorator('IExtHostTask'); diff --git a/src/vs/workbench/api/node/extHostTask.ts b/src/vs/workbench/api/node/extHostTask.ts index 8d3d6b3861d..ad10c7cb61e 100644 --- a/src/vs/workbench/api/node/extHostTask.ts +++ b/src/vs/workbench/api/node/extHostTask.ts @@ -195,4 +195,8 @@ export class ExtHostTask extends ExtHostTaskBase { public async $jsonTasksSupported(): Promise { return true; } + + public async $findExecutable(command: string, cwd?: string, paths?: string[]): Promise { + return win32.findExecutable(command, cwd, paths); + } } diff --git a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts index 14b7d7bdd0c..c5b1ed19e29 100644 --- a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts +++ b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts @@ -496,12 +496,15 @@ export class TerminalTaskSystem implements ITaskSystem { } } - private resolveAndFindExecutable(workspaceFolder: IWorkspaceFolder | undefined, task: CustomTask | ContributedTask, cwd: string | undefined, envPath: string | undefined): Promise { - return this.findExecutable( - this.configurationResolverService.resolve(workspaceFolder, CommandString.value(task.command.name!)), - cwd ? this.configurationResolverService.resolve(workspaceFolder, cwd) : undefined, - envPath ? envPath.split(path.delimiter).map(p => this.configurationResolverService.resolve(workspaceFolder, p)) : undefined - ); + private async resolveAndFindExecutable(systemInfo: TaskSystemInfo | undefined, workspaceFolder: IWorkspaceFolder | undefined, task: CustomTask | ContributedTask, cwd: string | undefined, envPath: string | undefined): Promise { + const command = this.configurationResolverService.resolve(workspaceFolder, CommandString.value(task.command.name!)); + cwd = cwd ? this.configurationResolverService.resolve(workspaceFolder, cwd) : undefined; + const paths = envPath ? envPath.split(path.delimiter).map(p => this.configurationResolverService.resolve(workspaceFolder, p)) : undefined; + let foundExecutable = await systemInfo?.findExecutable(command, cwd, paths); + if (!foundExecutable) { + foundExecutable = await this.findExecutable(command, cwd, paths); + } + return foundExecutable; } private findUnresolvedVariables(variables: Set, alreadyResolved: Map): Set { @@ -562,7 +565,7 @@ export class TerminalTaskSystem implements ITaskSystem { if (isProcess) { let process = CommandString.value(task.command.name!); if (taskSystemInfo.platform === Platform.Platform.Windows) { - process = await this.resolveAndFindExecutable(workspaceFolder, task, cwd, envPath); + process = await this.resolveAndFindExecutable(taskSystemInfo, workspaceFolder, task, cwd, envPath); } resolved.variables.set(TerminalTaskSystem.ProcessVarName, process); } @@ -581,7 +584,7 @@ export class TerminalTaskSystem implements ITaskSystem { if (isProcess) { let processVarValue: string; if (Platform.isWindows) { - processVarValue = await this.resolveAndFindExecutable(workspaceFolder, task, cwd, envPath); + processVarValue = await this.resolveAndFindExecutable(taskSystemInfo, workspaceFolder, task, cwd, envPath); } else { processVarValue = this.configurationResolverService.resolve(workspaceFolder, CommandString.value(task.command.name!)); } diff --git a/src/vs/workbench/contrib/tasks/common/taskSystem.ts b/src/vs/workbench/contrib/tasks/common/taskSystem.ts index 482eb62461e..56bc04b325c 100644 --- a/src/vs/workbench/contrib/tasks/common/taskSystem.ts +++ b/src/vs/workbench/contrib/tasks/common/taskSystem.ts @@ -121,6 +121,7 @@ export interface TaskSystemInfo { uriProvider: (this: void, path: string) => URI; resolveVariables(workspaceFolder: IWorkspaceFolder, toResolve: ResolveSet, target: ConfigurationTarget): Promise; getDefaultShellAndArgs(): Promise<{ shell: string, args: string[] | string | undefined }>; + findExecutable(command: string, cwd?: string, paths?: string[]): Promise; } export interface TaskSystemInfoResolver {