Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions crates/rust-analyzer/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -904,8 +904,24 @@ config_data! {
/// This config takes a map of crate names with the exported proc-macro names to ignore as values.
procMacro_ignored: FxHashMap<Box<str>, Box<[Box<str>]>> = FxHashMap::default(),

/// Subcommand used for bench runnables instead of `bench`.
runnables_bench_command: String = "bench".to_owned(),
/// Override the command used for bench runnables.
/// The first element of the array should be the program to execute (for example, `cargo`).
///
/// Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically
/// replace the package name, target option (such as `--bin` or `--example`), the target name and
/// the test name (name of test function or test mod path).
runnables_bench_overrideCommand: Option<Vec<String>> = None,
/// Command to be executed instead of 'cargo' for runnables.
runnables_command: Option<String> = None,
/// Override the command used for bench runnables.
/// The first element of the array should be the program to execute (for example, `cargo`).
///
/// Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically
/// replace the package name, target option (such as `--bin` or `--example`), the target name and
/// the test name (name of test function or test mod path).
runnables_doctest_overrideCommand: Option<Vec<String>> = None,
/// Additional arguments to be passed to cargo for runnables such as
/// tests or binaries. For example, it may be `--release`.
runnables_extraArgs: Vec<String> = vec![],
Expand All @@ -917,6 +933,15 @@ config_data! {
/// they will end up being interpreted as options to
/// [`rustc`’s built-in test harness (“libtest”)](https://doc.rust-lang.org/rustc/tests/index.html#cli-arguments).
runnables_extraTestBinaryArgs: Vec<String> = vec!["--nocapture".to_owned()],
/// Subcommand used for test runnables instead of `test`.
runnables_test_command: String = "test".to_owned(),
/// Override the command used for test runnables.
/// The first element of the array should be the program to execute (for example, `cargo`).
///
/// Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically
/// replace the package name, target option (such as `--bin` or `--example`), the target name and
/// the test name (name of test function or test mod path).
runnables_test_overrideCommand: Option<Vec<String>> = None,

/// Path to the Cargo.toml of the rust compiler workspace, for usage in rustc_private
/// projects, or "discover" to try to automatically find it if the `rustc-dev` component
Expand Down Expand Up @@ -1568,6 +1593,16 @@ pub struct RunnablesConfig {
pub cargo_extra_args: Vec<String>,
/// Additional arguments for the binary being run, if it is a test or benchmark.
pub extra_test_binary_args: Vec<String>,
/// Subcommand used for doctest runnables instead of `test`.
pub test_command: String,
/// Override the command used for test runnables.
pub test_override_command: Option<Vec<String>>,
/// Subcommand used for doctest runnables instead of `bench`.
pub bench_command: String,
/// Override the command used for bench runnables.
pub bench_override_command: Option<Vec<String>>,
/// Override the command used for doctest runnables.
pub doc_test_override_command: Option<Vec<String>>,
}

/// Configuration for workspace symbol search requests.
Expand Down Expand Up @@ -2494,6 +2529,11 @@ impl Config {
override_cargo: self.runnables_command(source_root).clone(),
cargo_extra_args: self.runnables_extraArgs(source_root).clone(),
extra_test_binary_args: self.runnables_extraTestBinaryArgs(source_root).clone(),
test_command: self.runnables_test_command(source_root).clone(),
test_override_command: self.runnables_test_overrideCommand(source_root).clone(),
bench_command: self.runnables_bench_command(source_root).clone(),
bench_override_command: self.runnables_bench_overrideCommand(source_root).clone(),
doc_test_override_command: self.runnables_doctest_overrideCommand(source_root).clone(),
}
}

Expand Down
53 changes: 37 additions & 16 deletions crates/rust-analyzer/src/lsp/to_proto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1561,6 +1561,9 @@ pub(crate) fn runnable(

let target = spec.target.clone();

let override_command =
CargoTargetSpec::override_command(snap, Some(spec.clone()), &runnable.kind);

let (cargo_args, executable_args) = CargoTargetSpec::runnable_args(
snap,
Some(spec.clone()),
Expand All @@ -1576,23 +1579,41 @@ pub(crate) fn runnable(
let label = runnable.label(Some(&target));
let location = location_link(snap, None, runnable.nav)?;

Ok(Some(lsp_ext::Runnable {
label,
location: Some(location),
kind: lsp_ext::RunnableKind::Cargo,
args: lsp_ext::RunnableArgs::Cargo(lsp_ext::CargoRunnableArgs {
workspace_root: Some(workspace_root.into()),
override_cargo: config.override_cargo,
cargo_args,
cwd: cwd.into(),
executable_args,
environment: spec
.sysroot_root
.map(|root| ("RUSTC_TOOLCHAIN".to_owned(), root.to_string()))
.into_iter()
.collect(),
let environment = spec
.sysroot_root
.map(|root| ("RUSTC_TOOLCHAIN".to_owned(), root.to_string()))
.into_iter()
.collect();

Ok(match override_command {
Some(override_command) => match override_command.split_first() {
Some((program, args)) => Some(lsp_ext::Runnable {
label,
location: Some(location),
kind: lsp_ext::RunnableKind::Shell,
args: lsp_ext::RunnableArgs::Shell(lsp_ext::ShellRunnableArgs {
environment,
cwd: cwd.into(),
program: program.to_string(),
args: args.to_vec(),
}),
}),
_ => None,
},
None => Some(lsp_ext::Runnable {
label,
location: Some(location),
kind: lsp_ext::RunnableKind::Cargo,
args: lsp_ext::RunnableArgs::Cargo(lsp_ext::CargoRunnableArgs {
workspace_root: Some(workspace_root.into()),
override_cargo: config.override_cargo,
cargo_args,
cwd: cwd.into(),
executable_args,
environment,
}),
}),
}))
})
}
Some(TargetSpec::ProjectJson(spec)) => {
let label = runnable.label(Some(&spec.label));
Expand Down
61 changes: 55 additions & 6 deletions crates/rust-analyzer/src/target_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ impl CargoTargetSpec {

match kind {
RunnableKind::Test { test_id, attr } => {
cargo_args.push("test".to_owned());
cargo_args.push(config.test_command);
executable_args.push(test_id.to_string());
if let TestId::Path(_) = test_id {
executable_args.push("--exact".to_owned());
Expand All @@ -134,12 +134,12 @@ impl CargoTargetSpec {
}
}
RunnableKind::TestMod { path } => {
cargo_args.push("test".to_owned());
cargo_args.push(config.test_command);
executable_args.push(path.clone());
executable_args.extend(extra_test_binary_args);
}
RunnableKind::Bench { test_id } => {
cargo_args.push("bench".to_owned());
cargo_args.push(config.bench_command);
executable_args.push(test_id.to_string());
if let TestId::Path(_) = test_id {
executable_args.push("--exact".to_owned());
Expand All @@ -154,10 +154,12 @@ impl CargoTargetSpec {
}
RunnableKind::Bin => {
let subcommand = match spec {
Some(CargoTargetSpec { target_kind: TargetKind::Test, .. }) => "test",
_ => "run",
Some(CargoTargetSpec { target_kind: TargetKind::Test, .. }) => {
config.test_command
}
_ => "run".to_owned(),
};
cargo_args.push(subcommand.to_owned());
cargo_args.push(subcommand);
}
}

Expand Down Expand Up @@ -206,6 +208,53 @@ impl CargoTargetSpec {
(cargo_args, executable_args)
}

pub(crate) fn override_command(
snap: &GlobalStateSnapshot,
spec: Option<CargoTargetSpec>,
kind: &RunnableKind,
) -> Option<Vec<String>> {
let config = snap.config.runnables(None);
let (args, test_name) = match kind {
RunnableKind::Test { test_id, .. } => {
(config.test_override_command, Some(test_id.to_string()))
}
RunnableKind::TestMod { path } => (config.test_override_command, Some(path.clone())),
RunnableKind::Bench { test_id } => {
(config.bench_override_command, Some(test_id.to_string()))
}
RunnableKind::DocTest { test_id } => {
(config.doc_test_override_command, Some(test_id.to_string()))
}
RunnableKind::Bin => match spec {
Some(CargoTargetSpec { target_kind: TargetKind::Test, .. }) => {
(config.test_override_command, None)
}
_ => (None, None),
},
};
let test_name = test_name.unwrap_or_default();

let target_arg = |kind| match kind {
TargetKind::Bin => "--bin",
TargetKind::Test => "--test",
TargetKind::Bench => "--bench",
TargetKind::Example => "--example",
TargetKind::Lib { .. } => "--lib",
TargetKind::BuildScript | TargetKind::Other => "",
};

let replace_placeholders = |arg: String| match &spec {
Some(spec) => arg
.replace("${package}", &spec.package)
.replace("${target_arg}", target_arg(spec.target_kind))
.replace("${target}", &spec.target)
.replace("${test_name}", &test_name),
_ => arg,
};

args.map(|args| args.into_iter().map(replace_placeholders).collect())
}

pub(crate) fn push_to(self, buf: &mut Vec<String>, kind: &RunnableKind) {
buf.push("--package".to_owned());
buf.push(self.package);
Expand Down
50 changes: 50 additions & 0 deletions docs/book/src/configuration_generated.md
Original file line number Diff line number Diff line change
Expand Up @@ -1348,13 +1348,44 @@ Default: `true`
Whether to warn when a rename will cause conflicts (change the meaning of the code).


## rust-analyzer.runnables.bench.command {#runnables.bench.command}

Default: `"bench"`

Subcommand used for bench runnables instead of `bench`.


## rust-analyzer.runnables.bench.overrideCommand {#runnables.bench.overrideCommand}

Default: `null`

Override the command used for bench runnables.
The first element of the array should be the program to execute (for example, `cargo`).

Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically
replace the package name, target option (such as `--bin` or `--example`), the target name and
the test name (name of test function or test mod path).


## rust-analyzer.runnables.command {#runnables.command}

Default: `null`

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


## rust-analyzer.runnables.doctest.overrideCommand {#runnables.doctest.overrideCommand}

Default: `null`

Override the command used for bench runnables.
The first element of the array should be the program to execute (for example, `cargo`).

Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically
replace the package name, target option (such as `--bin` or `--example`), the target name and
the test name (name of test function or test mod path).


## rust-analyzer.runnables.extraArgs {#runnables.extraArgs}

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


## rust-analyzer.runnables.test.command {#runnables.test.command}

Default: `"test"`

Subcommand used for test runnables instead of `test`.


## rust-analyzer.runnables.test.overrideCommand {#runnables.test.overrideCommand}

Default: `null`

Override the command used for test runnables.
The first element of the array should be the program to execute (for example, `cargo`).

Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically
replace the package name, target option (such as `--bin` or `--example`), the target name and
the test name (name of test function or test mod path).


## rust-analyzer.rustc.source {#rustc.source}

Default: `null`
Expand Down
68 changes: 68 additions & 0 deletions editors/code/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2826,6 +2826,32 @@
}
}
},
{
"title": "Runnables",
"properties": {
"rust-analyzer.runnables.bench.command": {
"markdownDescription": "Subcommand used for bench runnables instead of `bench`.",
"default": "bench",
"type": "string"
}
}
},
{
"title": "Runnables",
"properties": {
"rust-analyzer.runnables.bench.overrideCommand": {
"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).",
"default": null,
"type": [
"null",
"array"
],
"items": {
"type": "string"
}
}
}
},
{
"title": "Runnables",
"properties": {
Expand All @@ -2839,6 +2865,22 @@
}
}
},
{
"title": "Runnables",
"properties": {
"rust-analyzer.runnables.doctest.overrideCommand": {
"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).",
"default": null,
"type": [
"null",
"array"
],
"items": {
"type": "string"
}
}
}
},
{
"title": "Runnables",
"properties": {
Expand Down Expand Up @@ -2867,6 +2909,32 @@
}
}
},
{
"title": "Runnables",
"properties": {
"rust-analyzer.runnables.test.command": {
"markdownDescription": "Subcommand used for test runnables instead of `test`.",
"default": "test",
"type": "string"
}
}
},
{
"title": "Runnables",
"properties": {
"rust-analyzer.runnables.test.overrideCommand": {
"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).",
"default": null,
"type": [
"null",
"array"
],
"items": {
"type": "string"
}
}
}
},
{
"title": "Rustc",
"properties": {
Expand Down