Skip to content

Commit d711705

Browse files
Merge pull request #21308 from dfireBird/runnable-subcommand-config
feat: implement configuration to change sub command for test, bench and doctest
2 parents 414a28d + 52af033 commit d711705

5 files changed

Lines changed: 250 additions & 22 deletions

File tree

crates/rust-analyzer/src/config.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -904,8 +904,24 @@ config_data! {
904904
/// This config takes a map of crate names with the exported proc-macro names to ignore as values.
905905
procMacro_ignored: FxHashMap<Box<str>, Box<[Box<str>]>> = FxHashMap::default(),
906906

907+
/// Subcommand used for bench runnables instead of `bench`.
908+
runnables_bench_command: String = "bench".to_owned(),
909+
/// Override the command used for bench runnables.
910+
/// The first element of the array should be the program to execute (for example, `cargo`).
911+
///
912+
/// Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically
913+
/// replace the package name, target option (such as `--bin` or `--example`), the target name and
914+
/// the test name (name of test function or test mod path).
915+
runnables_bench_overrideCommand: Option<Vec<String>> = None,
907916
/// Command to be executed instead of 'cargo' for runnables.
908917
runnables_command: Option<String> = None,
918+
/// Override the command used for bench runnables.
919+
/// The first element of the array should be the program to execute (for example, `cargo`).
920+
///
921+
/// Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically
922+
/// replace the package name, target option (such as `--bin` or `--example`), the target name and
923+
/// the test name (name of test function or test mod path).
924+
runnables_doctest_overrideCommand: Option<Vec<String>> = None,
909925
/// Additional arguments to be passed to cargo for runnables such as
910926
/// tests or binaries. For example, it may be `--release`.
911927
runnables_extraArgs: Vec<String> = vec![],
@@ -917,6 +933,15 @@ config_data! {
917933
/// they will end up being interpreted as options to
918934
/// [`rustc`’s built-in test harness (“libtest”)](https://doc.rust-lang.org/rustc/tests/index.html#cli-arguments).
919935
runnables_extraTestBinaryArgs: Vec<String> = vec!["--nocapture".to_owned()],
936+
/// Subcommand used for test runnables instead of `test`.
937+
runnables_test_command: String = "test".to_owned(),
938+
/// Override the command used for test runnables.
939+
/// The first element of the array should be the program to execute (for example, `cargo`).
940+
///
941+
/// Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically
942+
/// replace the package name, target option (such as `--bin` or `--example`), the target name and
943+
/// the test name (name of test function or test mod path).
944+
runnables_test_overrideCommand: Option<Vec<String>> = None,
920945

921946
/// Path to the Cargo.toml of the rust compiler workspace, for usage in rustc_private
922947
/// projects, or "discover" to try to automatically find it if the `rustc-dev` component
@@ -1568,6 +1593,16 @@ pub struct RunnablesConfig {
15681593
pub cargo_extra_args: Vec<String>,
15691594
/// Additional arguments for the binary being run, if it is a test or benchmark.
15701595
pub extra_test_binary_args: Vec<String>,
1596+
/// Subcommand used for doctest runnables instead of `test`.
1597+
pub test_command: String,
1598+
/// Override the command used for test runnables.
1599+
pub test_override_command: Option<Vec<String>>,
1600+
/// Subcommand used for doctest runnables instead of `bench`.
1601+
pub bench_command: String,
1602+
/// Override the command used for bench runnables.
1603+
pub bench_override_command: Option<Vec<String>>,
1604+
/// Override the command used for doctest runnables.
1605+
pub doc_test_override_command: Option<Vec<String>>,
15711606
}
15721607

15731608
/// Configuration for workspace symbol search requests.
@@ -2494,6 +2529,11 @@ impl Config {
24942529
override_cargo: self.runnables_command(source_root).clone(),
24952530
cargo_extra_args: self.runnables_extraArgs(source_root).clone(),
24962531
extra_test_binary_args: self.runnables_extraTestBinaryArgs(source_root).clone(),
2532+
test_command: self.runnables_test_command(source_root).clone(),
2533+
test_override_command: self.runnables_test_overrideCommand(source_root).clone(),
2534+
bench_command: self.runnables_bench_command(source_root).clone(),
2535+
bench_override_command: self.runnables_bench_overrideCommand(source_root).clone(),
2536+
doc_test_override_command: self.runnables_doctest_overrideCommand(source_root).clone(),
24972537
}
24982538
}
24992539

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

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1561,6 +1561,9 @@ pub(crate) fn runnable(
15611561

15621562
let target = spec.target.clone();
15631563

1564+
let override_command =
1565+
CargoTargetSpec::override_command(snap, Some(spec.clone()), &runnable.kind);
1566+
15641567
let (cargo_args, executable_args) = CargoTargetSpec::runnable_args(
15651568
snap,
15661569
Some(spec.clone()),
@@ -1576,23 +1579,41 @@ pub(crate) fn runnable(
15761579
let label = runnable.label(Some(&target));
15771580
let location = location_link(snap, None, runnable.nav)?;
15781581

1579-
Ok(Some(lsp_ext::Runnable {
1580-
label,
1581-
location: Some(location),
1582-
kind: lsp_ext::RunnableKind::Cargo,
1583-
args: lsp_ext::RunnableArgs::Cargo(lsp_ext::CargoRunnableArgs {
1584-
workspace_root: Some(workspace_root.into()),
1585-
override_cargo: config.override_cargo,
1586-
cargo_args,
1587-
cwd: cwd.into(),
1588-
executable_args,
1589-
environment: spec
1590-
.sysroot_root
1591-
.map(|root| ("RUSTC_TOOLCHAIN".to_owned(), root.to_string()))
1592-
.into_iter()
1593-
.collect(),
1582+
let environment = spec
1583+
.sysroot_root
1584+
.map(|root| ("RUSTC_TOOLCHAIN".to_owned(), root.to_string()))
1585+
.into_iter()
1586+
.collect();
1587+
1588+
Ok(match override_command {
1589+
Some(override_command) => match override_command.split_first() {
1590+
Some((program, args)) => Some(lsp_ext::Runnable {
1591+
label,
1592+
location: Some(location),
1593+
kind: lsp_ext::RunnableKind::Shell,
1594+
args: lsp_ext::RunnableArgs::Shell(lsp_ext::ShellRunnableArgs {
1595+
environment,
1596+
cwd: cwd.into(),
1597+
program: program.to_string(),
1598+
args: args.to_vec(),
1599+
}),
1600+
}),
1601+
_ => None,
1602+
},
1603+
None => Some(lsp_ext::Runnable {
1604+
label,
1605+
location: Some(location),
1606+
kind: lsp_ext::RunnableKind::Cargo,
1607+
args: lsp_ext::RunnableArgs::Cargo(lsp_ext::CargoRunnableArgs {
1608+
workspace_root: Some(workspace_root.into()),
1609+
override_cargo: config.override_cargo,
1610+
cargo_args,
1611+
cwd: cwd.into(),
1612+
executable_args,
1613+
environment,
1614+
}),
15941615
}),
1595-
}))
1616+
})
15961617
}
15971618
Some(TargetSpec::ProjectJson(spec)) => {
15981619
let label = runnable.label(Some(&spec.label));

crates/rust-analyzer/src/target_spec.rs

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ impl CargoTargetSpec {
123123

124124
match kind {
125125
RunnableKind::Test { test_id, attr } => {
126-
cargo_args.push("test".to_owned());
126+
cargo_args.push(config.test_command);
127127
executable_args.push(test_id.to_string());
128128
if let TestId::Path(_) = test_id {
129129
executable_args.push("--exact".to_owned());
@@ -134,12 +134,12 @@ impl CargoTargetSpec {
134134
}
135135
}
136136
RunnableKind::TestMod { path } => {
137-
cargo_args.push("test".to_owned());
137+
cargo_args.push(config.test_command);
138138
executable_args.push(path.clone());
139139
executable_args.extend(extra_test_binary_args);
140140
}
141141
RunnableKind::Bench { test_id } => {
142-
cargo_args.push("bench".to_owned());
142+
cargo_args.push(config.bench_command);
143143
executable_args.push(test_id.to_string());
144144
if let TestId::Path(_) = test_id {
145145
executable_args.push("--exact".to_owned());
@@ -154,10 +154,12 @@ impl CargoTargetSpec {
154154
}
155155
RunnableKind::Bin => {
156156
let subcommand = match spec {
157-
Some(CargoTargetSpec { target_kind: TargetKind::Test, .. }) => "test",
158-
_ => "run",
157+
Some(CargoTargetSpec { target_kind: TargetKind::Test, .. }) => {
158+
config.test_command
159+
}
160+
_ => "run".to_owned(),
159161
};
160-
cargo_args.push(subcommand.to_owned());
162+
cargo_args.push(subcommand);
161163
}
162164
}
163165

@@ -206,6 +208,53 @@ impl CargoTargetSpec {
206208
(cargo_args, executable_args)
207209
}
208210

211+
pub(crate) fn override_command(
212+
snap: &GlobalStateSnapshot,
213+
spec: Option<CargoTargetSpec>,
214+
kind: &RunnableKind,
215+
) -> Option<Vec<String>> {
216+
let config = snap.config.runnables(None);
217+
let (args, test_name) = match kind {
218+
RunnableKind::Test { test_id, .. } => {
219+
(config.test_override_command, Some(test_id.to_string()))
220+
}
221+
RunnableKind::TestMod { path } => (config.test_override_command, Some(path.clone())),
222+
RunnableKind::Bench { test_id } => {
223+
(config.bench_override_command, Some(test_id.to_string()))
224+
}
225+
RunnableKind::DocTest { test_id } => {
226+
(config.doc_test_override_command, Some(test_id.to_string()))
227+
}
228+
RunnableKind::Bin => match spec {
229+
Some(CargoTargetSpec { target_kind: TargetKind::Test, .. }) => {
230+
(config.test_override_command, None)
231+
}
232+
_ => (None, None),
233+
},
234+
};
235+
let test_name = test_name.unwrap_or_default();
236+
237+
let target_arg = |kind| match kind {
238+
TargetKind::Bin => "--bin",
239+
TargetKind::Test => "--test",
240+
TargetKind::Bench => "--bench",
241+
TargetKind::Example => "--example",
242+
TargetKind::Lib { .. } => "--lib",
243+
TargetKind::BuildScript | TargetKind::Other => "",
244+
};
245+
246+
let replace_placeholders = |arg: String| match &spec {
247+
Some(spec) => arg
248+
.replace("${package}", &spec.package)
249+
.replace("${target_arg}", target_arg(spec.target_kind))
250+
.replace("${target}", &spec.target)
251+
.replace("${test_name}", &test_name),
252+
_ => arg,
253+
};
254+
255+
args.map(|args| args.into_iter().map(replace_placeholders).collect())
256+
}
257+
209258
pub(crate) fn push_to(self, buf: &mut Vec<String>, kind: &RunnableKind) {
210259
buf.push("--package".to_owned());
211260
buf.push(self.package);

docs/book/src/configuration_generated.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1348,13 +1348,44 @@ Default: `true`
13481348
Whether to warn when a rename will cause conflicts (change the meaning of the code).
13491349

13501350

1351+
## rust-analyzer.runnables.bench.command {#runnables.bench.command}
1352+
1353+
Default: `"bench"`
1354+
1355+
Subcommand used for bench runnables instead of `bench`.
1356+
1357+
1358+
## rust-analyzer.runnables.bench.overrideCommand {#runnables.bench.overrideCommand}
1359+
1360+
Default: `null`
1361+
1362+
Override the command used for bench runnables.
1363+
The first element of the array should be the program to execute (for example, `cargo`).
1364+
1365+
Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically
1366+
replace the package name, target option (such as `--bin` or `--example`), the target name and
1367+
the test name (name of test function or test mod path).
1368+
1369+
13511370
## rust-analyzer.runnables.command {#runnables.command}
13521371

13531372
Default: `null`
13541373

13551374
Command to be executed instead of 'cargo' for runnables.
13561375

13571376

1377+
## rust-analyzer.runnables.doctest.overrideCommand {#runnables.doctest.overrideCommand}
1378+
1379+
Default: `null`
1380+
1381+
Override the command used for bench runnables.
1382+
The first element of the array should be the program to execute (for example, `cargo`).
1383+
1384+
Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically
1385+
replace the package name, target option (such as `--bin` or `--example`), the target name and
1386+
the test name (name of test function or test mod path).
1387+
1388+
13581389
## rust-analyzer.runnables.extraArgs {#runnables.extraArgs}
13591390

13601391
Default: `[]`
@@ -1381,6 +1412,25 @@ they will end up being interpreted as options to
13811412
[`rustc`’s built-in test harness (“libtest”)](https://doc.rust-lang.org/rustc/tests/index.html#cli-arguments).
13821413

13831414

1415+
## rust-analyzer.runnables.test.command {#runnables.test.command}
1416+
1417+
Default: `"test"`
1418+
1419+
Subcommand used for test runnables instead of `test`.
1420+
1421+
1422+
## rust-analyzer.runnables.test.overrideCommand {#runnables.test.overrideCommand}
1423+
1424+
Default: `null`
1425+
1426+
Override the command used for test runnables.
1427+
The first element of the array should be the program to execute (for example, `cargo`).
1428+
1429+
Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically
1430+
replace the package name, target option (such as `--bin` or `--example`), the target name and
1431+
the test name (name of test function or test mod path).
1432+
1433+
13841434
## rust-analyzer.rustc.source {#rustc.source}
13851435

13861436
Default: `null`

editors/code/package.json

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2826,6 +2826,32 @@
28262826
}
28272827
}
28282828
},
2829+
{
2830+
"title": "Runnables",
2831+
"properties": {
2832+
"rust-analyzer.runnables.bench.command": {
2833+
"markdownDescription": "Subcommand used for bench runnables instead of `bench`.",
2834+
"default": "bench",
2835+
"type": "string"
2836+
}
2837+
}
2838+
},
2839+
{
2840+
"title": "Runnables",
2841+
"properties": {
2842+
"rust-analyzer.runnables.bench.overrideCommand": {
2843+
"markdownDescription": "Override the command used for bench runnables.\nThe first element of the array should be the program to execute (for example, `cargo`).\n\nUse the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically\nreplace the package name, target option (such as `--bin` or `--example`), the target name and\nthe test name (name of test function or test mod path).",
2844+
"default": null,
2845+
"type": [
2846+
"null",
2847+
"array"
2848+
],
2849+
"items": {
2850+
"type": "string"
2851+
}
2852+
}
2853+
}
2854+
},
28292855
{
28302856
"title": "Runnables",
28312857
"properties": {
@@ -2839,6 +2865,22 @@
28392865
}
28402866
}
28412867
},
2868+
{
2869+
"title": "Runnables",
2870+
"properties": {
2871+
"rust-analyzer.runnables.doctest.overrideCommand": {
2872+
"markdownDescription": "Override the command used for bench runnables.\nThe first element of the array should be the program to execute (for example, `cargo`).\n\nUse the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically\nreplace the package name, target option (such as `--bin` or `--example`), the target name and\nthe test name (name of test function or test mod path).",
2873+
"default": null,
2874+
"type": [
2875+
"null",
2876+
"array"
2877+
],
2878+
"items": {
2879+
"type": "string"
2880+
}
2881+
}
2882+
}
2883+
},
28422884
{
28432885
"title": "Runnables",
28442886
"properties": {
@@ -2867,6 +2909,32 @@
28672909
}
28682910
}
28692911
},
2912+
{
2913+
"title": "Runnables",
2914+
"properties": {
2915+
"rust-analyzer.runnables.test.command": {
2916+
"markdownDescription": "Subcommand used for test runnables instead of `test`.",
2917+
"default": "test",
2918+
"type": "string"
2919+
}
2920+
}
2921+
},
2922+
{
2923+
"title": "Runnables",
2924+
"properties": {
2925+
"rust-analyzer.runnables.test.overrideCommand": {
2926+
"markdownDescription": "Override the command used for test runnables.\nThe first element of the array should be the program to execute (for example, `cargo`).\n\nUse the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically\nreplace the package name, target option (such as `--bin` or `--example`), the target name and\nthe test name (name of test function or test mod path).",
2927+
"default": null,
2928+
"type": [
2929+
"null",
2930+
"array"
2931+
],
2932+
"items": {
2933+
"type": "string"
2934+
}
2935+
}
2936+
}
2937+
},
28702938
{
28712939
"title": "Rustc",
28722940
"properties": {

0 commit comments

Comments
 (0)