11import * as vscode from "vscode" ;
22import type { Config } from "./config" ;
3- import { log , unwrapUndefinable } from "./util" ;
43import * as toolchain from "./toolchain" ;
54
65// This ends up as the `type` key in tasks.json. RLS also uses `cargo` and
@@ -10,21 +9,21 @@ export const SHELL_TASK_TYPE = "shell";
109
1110export const RUST_TASK_SOURCE = "rust" ;
1211
13- export type RustTargetDefinition = {
12+ export type TaskDefinition = vscode . TaskDefinition & {
1413 readonly type : typeof CARGO_TASK_TYPE | typeof SHELL_TASK_TYPE ;
15- } & vscode . TaskDefinition &
16- RustTarget ;
17- export type RustTarget = {
18- // The command to run, usually `cargo`.
19- command : string ;
20- // Additional arguments passed to the command.
2114 args ?: string [ ] ;
22- // The working directory to run the command in.
23- cwd ?: string ;
24- // The shell environment.
25- env ?: { [ key : string ] : string } ;
15+ command : string ;
2616} ;
2717
18+ export type CargoTaskDefinition = {
19+ env ?: Record < string , string > ;
20+ type : typeof CARGO_TASK_TYPE ;
21+ } & TaskDefinition ;
22+
23+ function isCargoTask ( definition : vscode . TaskDefinition ) : definition is CargoTaskDefinition {
24+ return definition . type === CARGO_TASK_TYPE ;
25+ }
26+
2827class RustTaskProvider implements vscode . TaskProvider {
2928 private readonly config : Config ;
3029
@@ -58,13 +57,13 @@ class RustTaskProvider implements vscode.TaskProvider {
5857 for ( const workspaceTarget of vscode . workspace . workspaceFolders ) {
5958 for ( const def of defs ) {
6059 const definition = {
61- command : cargo ,
62- args : [ def . command ] ,
63- } ;
64- const exec = await targetToExecution ( definition , this . config . cargoRunner ) ;
60+ command : def . command ,
61+ type : CARGO_TASK_TYPE ,
62+ } as const ;
63+ const exec = await targetToExecution ( definition , { } , cargo ) ;
6564 const vscodeTask = await buildRustTask (
6665 workspaceTarget ,
67- { ... definition , type : CARGO_TASK_TYPE } ,
66+ definition ,
6867 `cargo ${ def . command } ` ,
6968 this . config . problemMatcher ,
7069 exec ,
@@ -81,23 +80,13 @@ class RustTaskProvider implements vscode.TaskProvider {
8180 // VSCode calls this for every cargo task in the user's tasks.json,
8281 // we need to inform VSCode how to execute that command by creating
8382 // a ShellExecution for it.
84- if ( task . definition . type === CARGO_TASK_TYPE ) {
85- const taskDefinition = task . definition as RustTargetDefinition ;
86- const cargo = await toolchain . cargoPath ( ) ;
87- const exec = await targetToExecution (
88- {
89- command : cargo ,
90- args : [ taskDefinition . command ] . concat ( taskDefinition . args || [ ] ) ,
91- cwd : taskDefinition . cwd ,
92- env : taskDefinition . env ,
93- } ,
94- this . config . cargoRunner ,
95- ) ;
96- return await buildRustTask (
83+ if ( isCargoTask ( task . definition ) ) {
84+ const exec = await targetToExecution ( task . definition , { env : task . definition . env } ) ;
85+ return buildRustTask (
9786 task . scope ,
98- taskDefinition ,
87+ task . definition ,
9988 task . name ,
100- this . config . problemMatcher ,
89+ task . problemMatchers ,
10190 exec ,
10291 ) ;
10392 }
@@ -108,7 +97,7 @@ class RustTaskProvider implements vscode.TaskProvider {
10897
10998export async function buildRustTask (
11099 scope : vscode . WorkspaceFolder | vscode . TaskScope | undefined ,
111- definition : RustTargetDefinition ,
100+ definition : TaskDefinition ,
112101 name : string ,
113102 problemMatcher : string [ ] ,
114103 exec : vscode . ProcessExecution | vscode . ShellExecution ,
@@ -126,40 +115,23 @@ export async function buildRustTask(
126115}
127116
128117export async function targetToExecution (
129- definition : RustTarget ,
130- customRunner ?: string ,
131- throwOnError : boolean = false ,
118+ definition : TaskDefinition ,
119+ options ?: {
120+ env ?: { [ key : string ] : string } ;
121+ cwd ?: string ;
122+ } ,
123+ cargo ?: string ,
132124) : Promise < vscode . ProcessExecution | vscode . ShellExecution > {
133- if ( customRunner ) {
134- const runnerCommand = `${ customRunner } .buildShellExecution` ;
135-
136- try {
137- const runnerArgs = {
138- kind : CARGO_TASK_TYPE ,
139- args : definition . args ,
140- cwd : definition . cwd ,
141- env : definition . env ,
142- } ;
143- const customExec = await vscode . commands . executeCommand ( runnerCommand , runnerArgs ) ;
144- if ( customExec ) {
145- if ( customExec instanceof vscode . ShellExecution ) {
146- return customExec ;
147- } else {
148- log . debug ( "Invalid cargo ShellExecution" , customExec ) ;
149- throw "Invalid cargo ShellExecution." ;
150- }
151- }
152- // fallback to default processing
153- } catch ( e ) {
154- if ( throwOnError ) throw `Cargo runner '${ customRunner } ' failed! ${ e } ` ;
155- // fallback to default processing
156- }
125+ let command , args ;
126+ if ( isCargoTask ( definition ) ) {
127+ // FIXME: The server should provide cargo
128+ command = cargo || ( await toolchain . cargoPath ( ) ) ;
129+ args = [ definition . command ] . concat ( definition . args || [ ] ) ;
130+ } else {
131+ command = definition . command ;
132+ args = definition . args || [ ] ;
157133 }
158- const args = unwrapUndefinable ( definition . args ) ;
159- return new vscode . ProcessExecution ( definition . command , args , {
160- cwd : definition . cwd ,
161- env : definition . env ,
162- } ) ;
134+ return new vscode . ProcessExecution ( command , args , options ) ;
163135}
164136
165137export function activateTaskProvider ( config : Config ) : vscode . Disposable {
0 commit comments