Implement invocation location config

This commit is contained in:
Lukas Wirth 2022-10-22 23:02:59 +02:00
parent 19efa0b110
commit 0f8904ec9c
9 changed files with 188 additions and 57 deletions

View File

@ -28,6 +28,13 @@ pub enum InvocationStrategy {
PerWorkspace, PerWorkspace,
} }
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub enum InvocationLocation {
Root(AbsPathBuf),
#[default]
Workspace,
}
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
pub enum FlycheckConfig { pub enum FlycheckConfig {
CargoCommand { CargoCommand {
@ -39,13 +46,13 @@ pub enum FlycheckConfig {
features: Vec<String>, features: Vec<String>,
extra_args: Vec<String>, extra_args: Vec<String>,
extra_env: FxHashMap<String, String>, extra_env: FxHashMap<String, String>,
invocation_strategy: InvocationStrategy,
}, },
CustomCommand { CustomCommand {
command: String, command: String,
args: Vec<String>, args: Vec<String>,
extra_env: FxHashMap<String, String>, extra_env: FxHashMap<String, String>,
invocation_strategy: InvocationStrategy, invocation_strategy: InvocationStrategy,
invocation_location: InvocationLocation,
}, },
} }
@ -275,7 +282,7 @@ impl FlycheckActor {
} }
fn check_command(&self) -> Command { fn check_command(&self) -> Command {
let (mut cmd, args, invocation_strategy) = match &self.config { let (mut cmd, args) = match &self.config {
FlycheckConfig::CargoCommand { FlycheckConfig::CargoCommand {
command, command,
target_triple, target_triple,
@ -285,7 +292,6 @@ impl FlycheckActor {
extra_args, extra_args,
features, features,
extra_env, extra_env,
invocation_strategy,
} => { } => {
let mut cmd = Command::new(toolchain::cargo()); let mut cmd = Command::new(toolchain::cargo());
cmd.arg(command); cmd.arg(command);
@ -309,18 +315,40 @@ impl FlycheckActor {
} }
} }
cmd.envs(extra_env); cmd.envs(extra_env);
(cmd, extra_args, invocation_strategy) (cmd, extra_args)
} }
FlycheckConfig::CustomCommand { command, args, extra_env, invocation_strategy } => { FlycheckConfig::CustomCommand {
command,
args,
extra_env,
invocation_strategy,
invocation_location,
} => {
let mut cmd = Command::new(command); let mut cmd = Command::new(command);
cmd.envs(extra_env); cmd.envs(extra_env);
(cmd, args, invocation_strategy)
match invocation_location {
InvocationLocation::Workspace => {
match invocation_strategy {
InvocationStrategy::Once => {
cmd.current_dir(&self.root);
}
InvocationStrategy::PerWorkspace => {
// FIXME: cmd.current_dir(&affected_workspace);
cmd.current_dir(&self.root);
}
}
}
InvocationLocation::Root(root) => {
cmd.current_dir(root);
}
}
(cmd, args)
} }
}; };
match invocation_strategy {
InvocationStrategy::PerWorkspace => cmd.current_dir(&self.root), cmd.args(args);
InvocationStrategy::Once => cmd.args(args),
};
cmd cmd
} }

View File

@ -21,7 +21,8 @@ use semver::Version;
use serde::Deserialize; use serde::Deserialize;
use crate::{ use crate::{
cfg_flag::CfgFlag, CargoConfig, CargoFeatures, CargoWorkspace, InvocationStrategy, Package, cfg_flag::CfgFlag, CargoConfig, CargoFeatures, CargoWorkspace, InvocationLocation,
InvocationStrategy, Package,
}; };
#[derive(Debug, Default, Clone, PartialEq, Eq)] #[derive(Debug, Default, Clone, PartialEq, Eq)]
@ -55,10 +56,7 @@ impl BuildScriptOutput {
} }
impl WorkspaceBuildScripts { impl WorkspaceBuildScripts {
fn build_command( fn build_command(config: &CargoConfig, current_dir: &path::Path) -> io::Result<Command> {
config: &CargoConfig,
workspace_root: Option<&path::Path>,
) -> io::Result<Command> {
let mut cmd = match config.run_build_script_command.as_deref() { let mut cmd = match config.run_build_script_command.as_deref() {
Some([program, args @ ..]) => { Some([program, args @ ..]) => {
let mut cmd = Command::new(program); let mut cmd = Command::new(program);
@ -94,14 +92,11 @@ impl WorkspaceBuildScripts {
} }
} }
if let Some(workspace_root) = workspace_root {
cmd.current_dir(workspace_root);
}
cmd cmd
} }
}; };
cmd.current_dir(current_dir);
cmd.envs(&config.extra_env); cmd.envs(&config.extra_env);
if config.wrap_rustc_in_build_scripts { if config.wrap_rustc_in_build_scripts {
// Setup RUSTC_WRAPPER to point to `rust-analyzer` binary itself. We use // Setup RUSTC_WRAPPER to point to `rust-analyzer` binary itself. We use
@ -124,19 +119,21 @@ impl WorkspaceBuildScripts {
) -> io::Result<WorkspaceBuildScripts> { ) -> io::Result<WorkspaceBuildScripts> {
const RUST_1_62: Version = Version::new(1, 62, 0); const RUST_1_62: Version = Version::new(1, 62, 0);
let workspace_root: &path::Path = &workspace.workspace_root().as_ref(); let current_dir = match &config.invocation_location {
InvocationLocation::Root(root) if config.run_build_script_command.is_some() => {
root.as_path()
}
_ => &workspace.workspace_root(),
}
.as_ref();
match Self::run_per_ws( match Self::run_per_ws(Self::build_command(config, current_dir)?, workspace, progress) {
Self::build_command(config, Some(workspace_root))?,
workspace,
progress,
) {
Ok(WorkspaceBuildScripts { error: Some(error), .. }) Ok(WorkspaceBuildScripts { error: Some(error), .. })
if toolchain.as_ref().map_or(false, |it| *it >= RUST_1_62) => if toolchain.as_ref().map_or(false, |it| *it >= RUST_1_62) =>
{ {
// building build scripts failed, attempt to build with --keep-going so // building build scripts failed, attempt to build with --keep-going so
// that we potentially get more build data // that we potentially get more build data
let mut cmd = Self::build_command(config, Some(workspace_root))?; let mut cmd = Self::build_command(config, current_dir)?;
cmd.args(&["-Z", "unstable-options", "--keep-going"]).env("RUSTC_BOOTSTRAP", "1"); cmd.args(&["-Z", "unstable-options", "--keep-going"]).env("RUSTC_BOOTSTRAP", "1");
let mut res = Self::run_per_ws(cmd, workspace, progress)?; let mut res = Self::run_per_ws(cmd, workspace, progress)?;
res.error = Some(error); res.error = Some(error);
@ -154,7 +151,17 @@ impl WorkspaceBuildScripts {
progress: &dyn Fn(String), progress: &dyn Fn(String),
) -> io::Result<Vec<WorkspaceBuildScripts>> { ) -> io::Result<Vec<WorkspaceBuildScripts>> {
assert_eq!(config.invocation_strategy, InvocationStrategy::Once); assert_eq!(config.invocation_strategy, InvocationStrategy::Once);
let cmd = Self::build_command(config, None)?;
let current_dir = match &config.invocation_location {
InvocationLocation::Root(root) => root,
InvocationLocation::Workspace => {
return Err(io::Error::new(
io::ErrorKind::Other,
"Cannot run build scripts from workspace with invocation strategy `once`",
))
}
};
let cmd = Self::build_command(config, current_dir.as_path().as_ref())?;
// NB: Cargo.toml could have been modified between `cargo metadata` and // NB: Cargo.toml could have been modified between `cargo metadata` and
// `cargo check`. We shouldn't assume that package ids we see here are // `cargo check`. We shouldn't assume that package ids we see here are
// exactly those from `config`. // exactly those from `config`.

View File

@ -14,7 +14,7 @@ use rustc_hash::FxHashMap;
use serde::Deserialize; use serde::Deserialize;
use serde_json::from_value; use serde_json::from_value;
use crate::{utf8_stdout, ManifestPath}; use crate::{utf8_stdout, InvocationLocation, ManifestPath};
use crate::{CfgOverrides, InvocationStrategy}; use crate::{CfgOverrides, InvocationStrategy};
/// [`CargoWorkspace`] represents the logical structure of, well, a Cargo /// [`CargoWorkspace`] represents the logical structure of, well, a Cargo
@ -107,6 +107,7 @@ pub struct CargoConfig {
/// Extra env vars to set when invoking the cargo command /// Extra env vars to set when invoking the cargo command
pub extra_env: FxHashMap<String, String>, pub extra_env: FxHashMap<String, String>,
pub invocation_strategy: InvocationStrategy, pub invocation_strategy: InvocationStrategy,
pub invocation_location: InvocationLocation,
} }
impl CargoConfig { impl CargoConfig {

View File

@ -164,3 +164,10 @@ pub enum InvocationStrategy {
#[default] #[default]
PerWorkspace, PerWorkspace,
} }
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub enum InvocationLocation {
Root(AbsPathBuf),
#[default]
Workspace,
}

View File

@ -332,7 +332,9 @@ impl ProjectWorkspace {
config: &CargoConfig, config: &CargoConfig,
progress: &dyn Fn(String), progress: &dyn Fn(String),
) -> Vec<Result<WorkspaceBuildScripts>> { ) -> Vec<Result<WorkspaceBuildScripts>> {
if let InvocationStrategy::PerWorkspace = config.invocation_strategy { if matches!(config.invocation_strategy, InvocationStrategy::PerWorkspace)
|| config.run_build_script_command.is_some()
{
return workspaces.iter().map(|it| it.run_build_scripts(config, progress)).collect(); return workspaces.iter().map(|it| it.run_build_scripts(config, progress)).collect();
} }

View File

@ -69,10 +69,16 @@ config_data! {
cargo_autoreload: bool = "true", cargo_autoreload: bool = "true",
/// Run build scripts (`build.rs`) for more precise code analysis. /// Run build scripts (`build.rs`) for more precise code analysis.
cargo_buildScripts_enable: bool = "true", cargo_buildScripts_enable: bool = "true",
/// Specifies the working directory for running build scripts.
/// - "workspace": run build scripts for a workspace in the workspace's root directory.
/// This is incompatible with `#rust-analyzer.cargo.buildScripts.invocationStrategy#` set to `once`.
/// - "root": run build scripts in the project's root directory.
/// This config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#`
/// is set.
cargo_buildScripts_invocationLocation: InvocationLocation = "\"workspace\"",
/// Specifies the invocation strategy to use when running the build scripts command. /// Specifies the invocation strategy to use when running the build scripts command.
/// If `per_workspace` is set, the command will be executed for each workspace from the /// If `per_workspace` is set, the command will be executed for each workspace.
/// corresponding workspace root. /// If `once` is set, the command will be executed once.
/// If `once` is set, the command will be executed once in the project root.
/// This config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#` /// This config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#`
/// is set. /// is set.
cargo_buildScripts_invocationStrategy: InvocationStrategy = "\"per_workspace\"", cargo_buildScripts_invocationStrategy: InvocationStrategy = "\"per_workspace\"",
@ -129,10 +135,17 @@ config_data! {
/// ///
/// Set to `"all"` to pass `--all-features` to Cargo. /// Set to `"all"` to pass `--all-features` to Cargo.
checkOnSave_features: Option<CargoFeaturesDef> = "null", checkOnSave_features: Option<CargoFeaturesDef> = "null",
/// Specifies the working directory for running checks.
/// - "workspace": run checks for workspaces in the corresponding workspaces' root directories.
// FIXME: Ideally we would support this in some way
/// This falls back to "root" if `#rust-analyzer.cargo.checkOnSave.invocationStrategy#` is set to `once`.
/// - "root": run checks in the project's root directory.
/// This config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#`
/// is set.
checkOnSave_invocationLocation: InvocationLocation = "\"workspace\"",
/// Specifies the invocation strategy to use when running the checkOnSave command. /// Specifies the invocation strategy to use when running the checkOnSave command.
/// If `per_workspace` is set, the command will be executed for each workspace from the /// If `per_workspace` is set, the command will be executed for each workspace.
/// corresponding workspace root. /// If `once` is set, the command will be executed once.
/// If `once` is set, the command will be executed once in the project root.
/// This config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#` /// This config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#`
/// is set. /// is set.
checkOnSave_invocationStrategy: InvocationStrategy = "\"per_workspace\"", checkOnSave_invocationStrategy: InvocationStrategy = "\"per_workspace\"",
@ -1074,6 +1087,12 @@ impl Config {
InvocationStrategy::Once => project_model::InvocationStrategy::Once, InvocationStrategy::Once => project_model::InvocationStrategy::Once,
InvocationStrategy::PerWorkspace => project_model::InvocationStrategy::PerWorkspace, InvocationStrategy::PerWorkspace => project_model::InvocationStrategy::PerWorkspace,
}, },
invocation_location: match self.data.cargo_buildScripts_invocationLocation {
InvocationLocation::Root => {
project_model::InvocationLocation::Root(self.root_path.clone())
}
InvocationLocation::Workspace => project_model::InvocationLocation::Workspace,
},
run_build_script_command: self.data.cargo_buildScripts_overrideCommand.clone(), run_build_script_command: self.data.cargo_buildScripts_overrideCommand.clone(),
extra_env: self.data.cargo_extraEnv.clone(), extra_env: self.data.cargo_extraEnv.clone(),
} }
@ -1097,10 +1116,6 @@ impl Config {
if !self.data.checkOnSave_enable { if !self.data.checkOnSave_enable {
return None; return None;
} }
let invocation_strategy = match self.data.checkOnSave_invocationStrategy {
InvocationStrategy::Once => flycheck::InvocationStrategy::Once,
InvocationStrategy::PerWorkspace => flycheck::InvocationStrategy::PerWorkspace,
};
let flycheck_config = match &self.data.checkOnSave_overrideCommand { let flycheck_config = match &self.data.checkOnSave_overrideCommand {
Some(args) if !args.is_empty() => { Some(args) if !args.is_empty() => {
let mut args = args.clone(); let mut args = args.clone();
@ -1109,7 +1124,18 @@ impl Config {
command, command,
args, args,
extra_env: self.check_on_save_extra_env(), extra_env: self.check_on_save_extra_env(),
invocation_strategy, invocation_strategy: match self.data.checkOnSave_invocationStrategy {
InvocationStrategy::Once => flycheck::InvocationStrategy::Once,
InvocationStrategy::PerWorkspace => {
flycheck::InvocationStrategy::PerWorkspace
}
},
invocation_location: match self.data.checkOnSave_invocationLocation {
InvocationLocation::Root => {
flycheck::InvocationLocation::Root(self.root_path.clone())
}
InvocationLocation::Workspace => flycheck::InvocationLocation::Workspace,
},
} }
} }
Some(_) | None => FlycheckConfig::CargoCommand { Some(_) | None => FlycheckConfig::CargoCommand {
@ -1139,7 +1165,6 @@ impl Config {
}, },
extra_args: self.data.checkOnSave_extraArgs.clone(), extra_args: self.data.checkOnSave_extraArgs.clone(),
extra_env: self.check_on_save_extra_env(), extra_env: self.check_on_save_extra_env(),
invocation_strategy,
}, },
}; };
Some(flycheck_config) Some(flycheck_config)
@ -1618,6 +1643,13 @@ enum InvocationStrategy {
PerWorkspace, PerWorkspace,
} }
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "snake_case")]
enum InvocationLocation {
Root,
Workspace,
}
#[derive(Deserialize, Debug, Clone)] #[derive(Deserialize, Debug, Clone)]
#[serde(untagged)] #[serde(untagged)]
enum LifetimeElisionDef { enum LifetimeElisionDef {
@ -2036,8 +2068,16 @@ fn field_props(field: &str, ty: &str, doc: &[&str], default: &str) -> serde_json
"type": "string", "type": "string",
"enum": ["per_workspace", "once"], "enum": ["per_workspace", "once"],
"enumDescriptions": [ "enumDescriptions": [
"The command will be executed for each workspace from the corresponding workspace root.", "The command will be executed for each workspace.",
"The command will be executed once in the project root." "The command will be executed once."
],
},
"InvocationLocation" => set! {
"type": "string",
"enum": ["workspace", "root"],
"enumDescriptions": [
"The command will be executed in the corresponding workspace root.",
"The command will be executed in the project root."
], ],
}, },
_ => panic!("missing entry for {}: {}", ty, default), _ => panic!("missing entry for {}: {}", ty, default),

View File

@ -473,8 +473,10 @@ impl GlobalState {
}; };
let sender = self.flycheck_sender.clone(); let sender = self.flycheck_sender.clone();
let (FlycheckConfig::CargoCommand { invocation_strategy, .. } let invocation_strategy = match config {
| FlycheckConfig::CustomCommand { invocation_strategy, .. }) = config; FlycheckConfig::CargoCommand { .. } => flycheck::InvocationStrategy::PerWorkspace,
FlycheckConfig::CustomCommand { invocation_strategy, .. } => invocation_strategy,
};
self.flycheck = match invocation_strategy { self.flycheck = match invocation_strategy {
flycheck::InvocationStrategy::Once => vec![FlycheckHandle::spawn( flycheck::InvocationStrategy::Once => vec![FlycheckHandle::spawn(

View File

@ -24,13 +24,22 @@ Automatically refresh project info via `cargo metadata` on
-- --
Run build scripts (`build.rs`) for more precise code analysis. Run build scripts (`build.rs`) for more precise code analysis.
-- --
[[rust-analyzer.cargo.buildScripts.invocationLocation]]rust-analyzer.cargo.buildScripts.invocationLocation (default: `"workspace"`)::
+
--
Specifies the working directory for running build scripts.
- "workspace": run build scripts for a workspace in the workspace's root directory.
This is incompatible with `#rust-analyzer.cargo.buildScripts.invocationStrategy#` set to `once`.
- "root": run build scripts in the project's root directory.
This config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#`
is set.
--
[[rust-analyzer.cargo.buildScripts.invocationStrategy]]rust-analyzer.cargo.buildScripts.invocationStrategy (default: `"per_workspace"`):: [[rust-analyzer.cargo.buildScripts.invocationStrategy]]rust-analyzer.cargo.buildScripts.invocationStrategy (default: `"per_workspace"`)::
+ +
-- --
Specifies the invocation strategy to use when running the build scripts command. Specifies the invocation strategy to use when running the build scripts command.
If `per_workspace` is set, the command will be executed for each workspace from the If `per_workspace` is set, the command will be executed for each workspace.
corresponding workspace root. If `once` is set, the command will be executed once.
If `once` is set, the command will be executed once in the project root.
This config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#` This config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#`
is set. is set.
-- --
@ -128,13 +137,22 @@ List of features to activate. Defaults to
Set to `"all"` to pass `--all-features` to Cargo. Set to `"all"` to pass `--all-features` to Cargo.
-- --
[[rust-analyzer.checkOnSave.invocationLocation]]rust-analyzer.checkOnSave.invocationLocation (default: `"workspace"`)::
+
--
Specifies the working directory for running checks.
- "workspace": run checks for workspaces in the corresponding workspaces' root directories.
This falls back to "root" if `#rust-analyzer.cargo.checkOnSave.invocationStrategy#` is set to `once`.
- "root": run checks in the project's root directory.
This config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#`
is set.
--
[[rust-analyzer.checkOnSave.invocationStrategy]]rust-analyzer.checkOnSave.invocationStrategy (default: `"per_workspace"`):: [[rust-analyzer.checkOnSave.invocationStrategy]]rust-analyzer.checkOnSave.invocationStrategy (default: `"per_workspace"`)::
+ +
-- --
Specifies the invocation strategy to use when running the checkOnSave command. Specifies the invocation strategy to use when running the checkOnSave command.
If `per_workspace` is set, the command will be executed for each workspace from the If `per_workspace` is set, the command will be executed for each workspace.
corresponding workspace root. If `once` is set, the command will be executed once.
If `once` is set, the command will be executed once in the project root.
This config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#` This config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#`
is set. is set.
-- --

View File

@ -432,8 +432,21 @@
"default": true, "default": true,
"type": "boolean" "type": "boolean"
}, },
"rust-analyzer.cargo.buildScripts.invocationLocation": {
"markdownDescription": "Specifies the working directory for running build scripts.\n- \"workspace\": run build scripts for a workspace in the workspace's root directory.\n This is incompatible with `#rust-analyzer.cargo.buildScripts.invocationStrategy#` set to `once`.\n- \"root\": run build scripts in the project's root directory.\nThis config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#`\nis set.",
"default": "workspace",
"type": "string",
"enum": [
"workspace",
"root"
],
"enumDescriptions": [
"The command will be executed in the corresponding workspace root.",
"The command will be executed in the project root."
]
},
"rust-analyzer.cargo.buildScripts.invocationStrategy": { "rust-analyzer.cargo.buildScripts.invocationStrategy": {
"markdownDescription": "Specifies the invocation strategy to use when running the build scripts command.\nIf `per_workspace` is set, the command will be executed for each workspace from the\ncorresponding workspace root.\nIf `once` is set, the command will be executed once in the project root.\nThis config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#`\nis set.", "markdownDescription": "Specifies the invocation strategy to use when running the build scripts command.\nIf `per_workspace` is set, the command will be executed for each workspace.\nIf `once` is set, the command will be executed once.\nThis config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#`\nis set.",
"default": "per_workspace", "default": "per_workspace",
"type": "string", "type": "string",
"enum": [ "enum": [
@ -441,8 +454,8 @@
"once" "once"
], ],
"enumDescriptions": [ "enumDescriptions": [
"The command will be executed for each workspace from the corresponding workspace root.", "The command will be executed for each workspace.",
"The command will be executed once in the project root." "The command will be executed once."
] ]
}, },
"rust-analyzer.cargo.buildScripts.overrideCommand": { "rust-analyzer.cargo.buildScripts.overrideCommand": {
@ -570,8 +583,21 @@
} }
] ]
}, },
"rust-analyzer.checkOnSave.invocationLocation": {
"markdownDescription": "Specifies the working directory for running checks.\n- \"workspace\": run checks for workspaces in the corresponding workspaces' root directories.\n This falls back to \"root\" if `#rust-analyzer.cargo.checkOnSave.invocationStrategy#` is set to `once`.\n- \"root\": run checks in the project's root directory.\nThis config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#`\nis set.",
"default": "workspace",
"type": "string",
"enum": [
"workspace",
"root"
],
"enumDescriptions": [
"The command will be executed in the corresponding workspace root.",
"The command will be executed in the project root."
]
},
"rust-analyzer.checkOnSave.invocationStrategy": { "rust-analyzer.checkOnSave.invocationStrategy": {
"markdownDescription": "Specifies the invocation strategy to use when running the checkOnSave command.\nIf `per_workspace` is set, the command will be executed for each workspace from the\ncorresponding workspace root.\nIf `once` is set, the command will be executed once in the project root.\nThis config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#`\nis set.", "markdownDescription": "Specifies the invocation strategy to use when running the checkOnSave command.\nIf `per_workspace` is set, the command will be executed for each workspace.\nIf `once` is set, the command will be executed once.\nThis config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#`\nis set.",
"default": "per_workspace", "default": "per_workspace",
"type": "string", "type": "string",
"enum": [ "enum": [
@ -579,8 +605,8 @@
"once" "once"
], ],
"enumDescriptions": [ "enumDescriptions": [
"The command will be executed for each workspace from the corresponding workspace root.", "The command will be executed for each workspace.",
"The command will be executed once in the project root." "The command will be executed once."
] ]
}, },
"rust-analyzer.checkOnSave.noDefaultFeatures": { "rust-analyzer.checkOnSave.noDefaultFeatures": {