Skip to content

Commit aab4071

Browse files
committed
feat: implement configuration to change subcommand for test and bench
1 parent 11d6212 commit aab4071

5 files changed

Lines changed: 236 additions & 22 deletions

File tree

crates/rust-analyzer/src/config.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -904,8 +904,22 @@ 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}` to dynamically replace the package name,
913+
/// target option (such as `--bin` or `--example`), and the target name.
914+
runnables_bench_overrideCommand: Option<Vec<String>> = None,
907915
/// Command to be executed instead of 'cargo' for runnables.
908916
runnables_command: Option<String> = None,
917+
/// Override the command used for bench runnables.
918+
/// The first element of the array should be the program to execute (for example, `cargo`).
919+
///
920+
/// Use the placeholders `${package}`, `${target_arg}`, `${target}` to dynamically replace the package name,
921+
/// target option (such as `--bin` or `--example`), and the target name.
922+
runnables_doctest_overrideCommand: Option<Vec<String>> = None,
909923
/// Additional arguments to be passed to cargo for runnables such as
910924
/// tests or binaries. For example, it may be `--release`.
911925
runnables_extraArgs: Vec<String> = vec![],
@@ -917,6 +931,14 @@ config_data! {
917931
/// they will end up being interpreted as options to
918932
/// [`rustc`’s built-in test harness (“libtest”)](https://doc.rust-lang.org/rustc/tests/index.html#cli-arguments).
919933
runnables_extraTestBinaryArgs: Vec<String> = vec!["--nocapture".to_owned()],
934+
/// Subcommand used for test runnables instead of `test`.
935+
runnables_test_command: String = "test".to_owned(),
936+
/// Override the command used for test runnables.
937+
/// The first element of the array should be the program to execute (for example, `cargo`).
938+
///
939+
/// Use the placeholders `${package}`, `${target_arg}`, `${target}` to dynamically replace the package name,
940+
/// target option (such as `--bin` or `--example`), and the target name.
941+
runnables_test_overrideCommand: Option<Vec<String>> = None,
920942

921943
/// Path to the Cargo.toml of the rust compiler workspace, for usage in rustc_private
922944
/// projects, or "discover" to try to automatically find it if the `rustc-dev` component
@@ -1568,6 +1590,16 @@ pub struct RunnablesConfig {
15681590
pub cargo_extra_args: Vec<String>,
15691591
/// Additional arguments for the binary being run, if it is a test or benchmark.
15701592
pub extra_test_binary_args: Vec<String>,
1593+
/// Subcommand used for doctest runnables instead of `test`.
1594+
pub test_command: String,
1595+
/// Override the command used for test runnables.
1596+
pub test_override_command: Option<Vec<String>>,
1597+
/// Subcommand used for doctest runnables instead of `bench`.
1598+
pub bench_command: String,
1599+
/// Override the command used for bench runnables.
1600+
pub bench_override_command: Option<Vec<String>>,
1601+
/// Override the command used for doctest runnables.
1602+
pub doc_test_override_command: Option<Vec<String>>,
15711603
}
15721604

15731605
/// Configuration for workspace symbol search requests.
@@ -2494,6 +2526,11 @@ impl Config {
24942526
override_cargo: self.runnables_command(source_root).clone(),
24952527
cargo_extra_args: self.runnables_extraArgs(source_root).clone(),
24962528
extra_test_binary_args: self.runnables_extraTestBinaryArgs(source_root).clone(),
2529+
test_command: self.runnables_test_command(source_root).clone(),
2530+
test_override_command: self.runnables_test_overrideCommand(source_root).clone(),
2531+
bench_command: self.runnables_bench_command(source_root).clone(),
2532+
bench_override_command: self.runnables_bench_overrideCommand(source_root).clone(),
2533+
doc_test_override_command: self.runnables_doctest_overrideCommand(source_root).clone(),
24972534
}
24982535
}
24992536

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().into_iter().chain(executable_args).collect(),
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: 47 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,45 @@ 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 = match kind {
218+
RunnableKind::Test { .. } | RunnableKind::TestMod { .. } => {
219+
config.test_override_command
220+
}
221+
RunnableKind::Bench { .. } => config.bench_override_command,
222+
RunnableKind::DocTest { .. } => config.doc_test_override_command,
223+
RunnableKind::Bin => match spec {
224+
Some(CargoTargetSpec { target_kind: TargetKind::Test, .. }) => {
225+
config.test_override_command
226+
}
227+
_ => None,
228+
},
229+
};
230+
231+
let target_arg = |kind| match kind {
232+
TargetKind::Bin => "--bin",
233+
TargetKind::Test => "--test",
234+
TargetKind::Bench => "--bench",
235+
TargetKind::Example => "--example",
236+
TargetKind::Lib { .. } => "--lib",
237+
TargetKind::BuildScript | TargetKind::Other => "",
238+
};
239+
240+
let replace_placeholders = |arg| match &spec {
241+
Some(spec) if arg == "${package}" => spec.package.clone(),
242+
Some(spec) if arg == "${target_arg}" => target_arg(spec.target_kind).to_string(),
243+
Some(spec) if arg == "${target}" => spec.target.clone(),
244+
_ => arg,
245+
};
246+
247+
args.map(|args| args.into_iter().map(replace_placeholders).collect())
248+
}
249+
209250
pub(crate) fn push_to(self, buf: &mut Vec<String>, kind: &RunnableKind) {
210251
buf.push("--package".to_owned());
211252
buf.push(self.package);

docs/book/src/configuration_generated.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1348,13 +1348,42 @@ 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}` to dynamically replace the package name,
1366+
target option (such as `--bin` or `--example`), and the target name.
1367+
1368+
13511369
## rust-analyzer.runnables.command {#runnables.command}
13521370

13531371
Default: `null`
13541372

13551373
Command to be executed instead of 'cargo' for runnables.
13561374

13571375

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

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

13831412

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

13861433
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}` to dynamically replace the package name,\ntarget option (such as `--bin` or `--example`), and the target name.",
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}` to dynamically replace the package name,\ntarget option (such as `--bin` or `--example`), and the target name.",
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}` to dynamically replace the package name,\ntarget option (such as `--bin` or `--example`), and the target name.",
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)