Skip to content

Commit 360b1f5

Browse files
committed
Auto merge of #17547 - Veykril:runnables-env, r=Veykril
internal: Clean up runnable lsp extension This feels like a natural addition to me, and also allows us to drop the expect-test hardcoding from the extension. Additionally, `cargoExtraArgs` is pointless, all the client will do is merge it with `cargoArgs` so the server can do that instead of delegating that to the client.
2 parents 78d5f05 + 8f69d98 commit 360b1f5

File tree

9 files changed

+102
-64
lines changed

9 files changed

+102
-64
lines changed

crates/rust-analyzer/src/handlers/request.rs

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -847,7 +847,7 @@ pub(crate) fn handle_runnables(
847847
if expect_test {
848848
if let lsp_ext::RunnableArgs::Cargo(r) = &mut runnable.args {
849849
runnable.label = format!("{} + expect", runnable.label);
850-
r.expect_test = Some(true);
850+
r.environment.insert("UPDATE_EXPECT".to_owned(), "1".to_owned());
851851
}
852852
}
853853
res.push(runnable);
@@ -874,6 +874,7 @@ pub(crate) fn handle_runnables(
874874
if all_targets {
875875
cargo_args.push("--all-targets".to_owned());
876876
}
877+
cargo_args.extend(config.cargo_extra_args.iter().cloned());
877878
res.push(lsp_ext::Runnable {
878879
label: format!(
879880
"cargo {cmd} -p {}{all_targets}",
@@ -884,33 +885,35 @@ pub(crate) fn handle_runnables(
884885
kind: lsp_ext::RunnableKind::Cargo,
885886
args: lsp_ext::RunnableArgs::Cargo(lsp_ext::CargoRunnableArgs {
886887
workspace_root: Some(spec.workspace_root.clone().into()),
887-
cwd: Some(cwd.into()),
888+
cwd: cwd.into(),
888889
override_cargo: config.override_cargo.clone(),
889890
cargo_args,
890-
cargo_extra_args: config.cargo_extra_args.clone(),
891891
executable_args: Vec::new(),
892-
expect_test: None,
892+
environment: Default::default(),
893893
}),
894894
})
895895
}
896896
}
897897
Some(TargetSpec::ProjectJson(_)) => {}
898898
None => {
899899
if !snap.config.linked_or_discovered_projects().is_empty() {
900-
res.push(lsp_ext::Runnable {
901-
label: "cargo check --workspace".to_owned(),
902-
location: None,
903-
kind: lsp_ext::RunnableKind::Cargo,
904-
args: lsp_ext::RunnableArgs::Cargo(lsp_ext::CargoRunnableArgs {
905-
workspace_root: None,
906-
cwd: None,
907-
override_cargo: config.override_cargo,
908-
cargo_args: vec!["check".to_owned(), "--workspace".to_owned()],
909-
cargo_extra_args: config.cargo_extra_args,
910-
executable_args: Vec::new(),
911-
expect_test: None,
912-
}),
913-
});
900+
if let Some(path) = snap.file_id_to_file_path(file_id).parent() {
901+
let mut cargo_args = vec!["check".to_owned(), "--workspace".to_owned()];
902+
cargo_args.extend(config.cargo_extra_args.iter().cloned());
903+
res.push(lsp_ext::Runnable {
904+
label: "cargo check --workspace".to_owned(),
905+
location: None,
906+
kind: lsp_ext::RunnableKind::Cargo,
907+
args: lsp_ext::RunnableArgs::Cargo(lsp_ext::CargoRunnableArgs {
908+
workspace_root: None,
909+
cwd: path.as_path().unwrap().to_path_buf().into(),
910+
override_cargo: config.override_cargo,
911+
cargo_args,
912+
executable_args: Vec::new(),
913+
environment: Default::default(),
914+
}),
915+
});
916+
};
914917
}
915918
}
916919
}

crates/rust-analyzer/src/lsp/ext.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -460,28 +460,27 @@ pub enum RunnableKind {
460460
#[derive(Deserialize, Serialize, Debug)]
461461
#[serde(rename_all = "camelCase")]
462462
pub struct CargoRunnableArgs {
463-
// command to be executed instead of cargo
463+
#[serde(skip_serializing_if = "FxHashMap::is_empty")]
464+
pub environment: FxHashMap<String, String>,
465+
pub cwd: Utf8PathBuf,
466+
/// Command to be executed instead of cargo
464467
pub override_cargo: Option<String>,
465468
#[serde(skip_serializing_if = "Option::is_none")]
466469
pub workspace_root: Option<Utf8PathBuf>,
467-
#[serde(skip_serializing_if = "Option::is_none")]
468-
pub cwd: Option<Utf8PathBuf>,
469470
// command, --package and --lib stuff
470471
pub cargo_args: Vec<String>,
471-
// user-specified additional cargo args, like `--release`.
472-
pub cargo_extra_args: Vec<String>,
473472
// stuff after --
474473
pub executable_args: Vec<String>,
475-
#[serde(skip_serializing_if = "Option::is_none")]
476-
pub expect_test: Option<bool>,
477474
}
478475

479476
#[derive(Deserialize, Serialize, Debug)]
480477
#[serde(rename_all = "camelCase")]
481478
pub struct ShellRunnableArgs {
479+
#[serde(skip_serializing_if = "FxHashMap::is_empty")]
480+
pub environment: FxHashMap<String, String>,
481+
pub cwd: Utf8PathBuf,
482482
pub program: String,
483483
pub args: Vec<String>,
484-
pub cwd: Utf8PathBuf,
485484
}
486485

487486
pub enum RelatedTests {}

crates/rust-analyzer/src/lsp/to_proto.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1390,10 +1390,9 @@ pub(crate) fn runnable(
13901390
workspace_root: Some(workspace_root.into()),
13911391
override_cargo: config.override_cargo,
13921392
cargo_args,
1393-
cwd: Some(cwd.into()),
1394-
cargo_extra_args: config.cargo_extra_args,
1393+
cwd: cwd.into(),
13951394
executable_args,
1396-
expect_test: None,
1395+
environment: Default::default(),
13971396
}),
13981397
}))
13991398
}
@@ -1407,6 +1406,7 @@ pub(crate) fn runnable(
14071406
program: json_shell_runnable_args.program,
14081407
args: json_shell_runnable_args.args,
14091408
cwd: json_shell_runnable_args.cwd,
1409+
environment: Default::default(),
14101410
};
14111411
Ok(Some(lsp_ext::Runnable {
14121412
label,
@@ -1419,6 +1419,9 @@ pub(crate) fn runnable(
14191419
}
14201420
}
14211421
None => {
1422+
let Some(path) = snap.file_id_to_file_path(runnable.nav.file_id).parent() else {
1423+
return Ok(None);
1424+
};
14221425
let (cargo_args, executable_args) =
14231426
CargoTargetSpec::runnable_args(snap, None, &runnable.kind, &runnable.cfg);
14241427

@@ -1433,10 +1436,9 @@ pub(crate) fn runnable(
14331436
workspace_root: None,
14341437
override_cargo: config.override_cargo,
14351438
cargo_args,
1436-
cwd: None,
1437-
cargo_extra_args: config.cargo_extra_args,
1439+
cwd: path.as_path().unwrap().to_path_buf().into(),
14381440
executable_args,
1439-
expect_test: None,
1441+
environment: Default::default(),
14401442
}),
14411443
}))
14421444
}

crates/rust-analyzer/src/target_spec.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,8 @@ impl CargoTargetSpec {
110110
kind: &RunnableKind,
111111
cfg: &Option<CfgExpr>,
112112
) -> (Vec<String>, Vec<String>) {
113-
let extra_test_binary_args = snap.config.runnables().extra_test_binary_args;
113+
let config = snap.config.runnables();
114+
let extra_test_binary_args = config.extra_test_binary_args;
114115

115116
let mut cargo_args = Vec::new();
116117
let mut executable_args = Vec::new();
@@ -196,6 +197,7 @@ impl CargoTargetSpec {
196197
}
197198
}
198199
}
200+
cargo_args.extend(config.cargo_extra_args.iter().cloned());
199201
(cargo_args, executable_args)
200202
}
201203

crates/rust-analyzer/tests/slow-tests/main.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,6 @@ fn main() {}
258258
"args": {
259259
"cargoArgs": ["test", "--package", "foo", "--test", "spam"],
260260
"executableArgs": ["test_eggs", "--exact", "--show-output"],
261-
"cargoExtraArgs": [],
262261
"overrideCargo": null,
263262
"cwd": server.path().join("foo"),
264263
"workspaceRoot": server.path().join("foo")
@@ -289,7 +288,6 @@ fn main() {}
289288
"--test",
290289
"spam"
291290
],
292-
"cargoExtraArgs": [],
293291
"executableArgs": [
294292
"",
295293
"--show-output"
@@ -325,7 +323,6 @@ fn main() {}
325323
"args": {
326324
"cargoArgs": ["check", "--package", "foo", "--all-targets"],
327325
"executableArgs": [],
328-
"cargoExtraArgs": [],
329326
"overrideCargo": null,
330327
"cwd": server.path().join("foo"),
331328
"workspaceRoot": server.path().join("foo")
@@ -337,7 +334,6 @@ fn main() {}
337334
"args": {
338335
"cargoArgs": ["test", "--package", "foo", "--all-targets"],
339336
"executableArgs": [],
340-
"cargoExtraArgs": [],
341337
"overrideCargo": null,
342338
"cwd": server.path().join("foo"),
343339
"workspaceRoot": server.path().join("foo")
@@ -426,7 +422,6 @@ mod tests {
426422
runnable,
427423
"--all-targets"
428424
],
429-
"cargoExtraArgs": [],
430425
"executableArgs": []
431426
},
432427
},
@@ -489,7 +484,6 @@ fn otherpkg() {}
489484
"mainpkg",
490485
"--all-targets"
491486
],
492-
"cargoExtraArgs": [],
493487
"executableArgs": []
494488
},
495489
},
@@ -515,7 +509,6 @@ fn otherpkg() {}
515509
"otherpkg",
516510
"--all-targets"
517511
],
518-
"cargoExtraArgs": [],
519512
"executableArgs": []
520513
},
521514
},

docs/dev/lsp-extensions.md

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!---
2-
lsp/ext.rs hash: 8e6e340f2899b5e9
2+
lsp/ext.rs hash: a0867710490bf8da
33
44
If you need to change the above hash to make the test pass, please check if you
55
need to adjust this doc as well and ping this issue:
@@ -376,12 +376,29 @@ rust-analyzer supports two `kind`s of runnables, `"cargo"` and `"shell"`. The `a
376376

377377
```typescript
378378
{
379+
/**
380+
* Environment variables to set before running the command.
381+
*/
382+
environment?: Record<string, string>;
383+
/**
384+
* The working directory to run the command in.
385+
*/
386+
cwd: string;
387+
/**
388+
* The workspace root directory of the cargo project.
389+
*/
379390
workspaceRoot?: string;
380-
cwd?: string;
391+
/**
392+
* The cargo command to run.
393+
*/
381394
cargoArgs: string[];
382-
cargoExtraArgs: string[];
395+
/**
396+
* Arguments to pass to the executable, these will be passed to the command after a `--` argument.
397+
*/
383398
executableArgs: string[];
384-
expectTest?: boolean;
399+
/**
400+
* Command to execute instead of `cargo`.
401+
*/
385402
overrideCargo?: string;
386403
}
387404
```
@@ -390,10 +407,17 @@ The args for `"shell"` look like this:
390407

391408
```typescript
392409
{
410+
/**
411+
* Environment variables to set before running the command.
412+
*/
413+
environment?: Record<string, string>;
414+
/**
415+
* The working directory to run the command in.
416+
*/
417+
cwd: string;
393418
kind: string;
394419
program: string;
395420
args: string[];
396-
cwd: string;
397421
}
398422
```
399423

editors/code/src/lsp_ext.ts

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -235,22 +235,43 @@ type RunnableShell = {
235235
args: ShellRunnableArgs;
236236
};
237237

238+
export type CommonRunnableArgs = {
239+
/**
240+
* Environment variables to set before running the command.
241+
*/
242+
environment?: Record<string, string>;
243+
/**
244+
* The working directory to run the command in.
245+
*/
246+
cwd: string;
247+
};
248+
238249
export type ShellRunnableArgs = {
239250
kind: string;
240251
program: string;
241252
args: string[];
242-
cwd: string;
243-
};
253+
} & CommonRunnableArgs;
244254

245255
export type CargoRunnableArgs = {
256+
/**
257+
* The workspace root directory of the cargo project.
258+
*/
246259
workspaceRoot?: string;
247-
cargoArgs: string[];
248-
cwd: string;
249-
cargoExtraArgs: string[];
260+
/**
261+
* Arguments to pass to the executable, these will be passed to the command after a `--` argument.
262+
*/
250263
executableArgs: string[];
251-
expectTest?: boolean;
264+
/**
265+
* Arguments to pass to cargo.
266+
*/
267+
cargoArgs: string[];
268+
/**
269+
* Command to execute instead of `cargo`.
270+
*/
271+
// This is supplied by the user via config. We could pull this through the client config in the
272+
// extension directly, but that would prevent us from honoring the rust-analyzer.toml for it.
252273
overrideCargo?: string;
253-
};
274+
} & CommonRunnableArgs;
254275

255276
export type RunnablesParams = {
256277
textDocument: lc.TextDocumentIdentifier;

editors/code/src/run.ts

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,12 @@ export class RunnableQuickPick implements vscode.QuickPickItem {
6666
}
6767
}
6868

69-
export function prepareBaseEnv(): Record<string, string> {
69+
export function prepareBaseEnv(base?: Record<string, string>): Record<string, string> {
7070
const env: Record<string, string> = { RUST_BACKTRACE: "short" };
71-
Object.assign(env, process.env as { [key: string]: string });
71+
Object.assign(env, process.env);
72+
if (base) {
73+
Object.assign(env, base);
74+
}
7275
return env;
7376
}
7477

@@ -77,12 +80,7 @@ export function prepareEnv(
7780
runnableArgs: ra.CargoRunnableArgs,
7881
runnableEnvCfg: RunnableEnvCfg,
7982
): Record<string, string> {
80-
const env = prepareBaseEnv();
81-
82-
if (runnableArgs.expectTest) {
83-
env["UPDATE_EXPECT"] = "1";
84-
}
85-
83+
const env = prepareBaseEnv(runnableArgs.environment);
8684
const platform = process.platform;
8785

8886
const checkPlatform = (it: RunnableEnvCfgItem) => {
@@ -167,9 +165,6 @@ export async function createTaskFromRunnable(
167165

168166
export function createCargoArgs(runnableArgs: ra.CargoRunnableArgs): string[] {
169167
const args = [...runnableArgs.cargoArgs]; // should be a copy!
170-
if (runnableArgs.cargoExtraArgs) {
171-
args.push(...runnableArgs.cargoExtraArgs); // Append user-specified cargo options.
172-
}
173168
if (runnableArgs.executableArgs.length > 0) {
174169
args.push("--", ...runnableArgs.executableArgs);
175170
}

editors/code/tests/unit/runnable_env.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ function makeRunnable(label: string): ra.Runnable {
1212
cargoArgs: [],
1313
cwd: ".",
1414
executableArgs: [],
15-
cargoExtraArgs: [],
1615
},
1716
};
1817
}

0 commit comments

Comments
 (0)