Skip to content

Commit 5ce14b0

Browse files
committed
Enforce a current directory being set for spawned commands
1 parent 0f95e60 commit 5ce14b0

File tree

22 files changed

+99
-75
lines changed

22 files changed

+99
-75
lines changed

clippy.toml

+4
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,7 @@ disallowed-types = [
33
{ path = "std::collections::HashSet", reason = "use FxHashSet" },
44
{ path = "std::collections::hash_map::RandomState", reason = "use BuildHasherDefault<FxHasher>"}
55
]
6+
7+
disallowed-methods = [
8+
{ path = "std::process::Command::new", reason = "use `toolchain::command` instead as it forces the choice of a working directory" },
9+
]

crates/ide/src/expand_macro.rs

+1
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ fn _format(
253253
let &crate_id = db.relevant_crates(file_id).iter().next()?;
254254
let edition = db.crate_graph()[crate_id].edition;
255255

256+
#[allow(clippy::disallowed_methods)]
256257
let mut cmd = std::process::Command::new(toolchain::Tool::Rustfmt.path());
257258
cmd.arg("--edition");
258259
cmd.arg(edition.to_string());

crates/proc-macro-api/src/process.rs

+1
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ fn mk_child(
202202
env: impl IntoIterator<Item = (impl AsRef<std::ffi::OsStr>, impl AsRef<std::ffi::OsStr>)>,
203203
null_stderr: bool,
204204
) -> io::Result<Child> {
205+
#[allow(clippy::disallowed_methods)]
205206
let mut cmd = Command::new(path);
206207
cmd.envs(env)
207208
.env("RUST_ANALYZER_INTERNALS_DO_NOT_USE", "this is unstable")

crates/proc-macro-srv/build.rs

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ fn main() {
77
println!("cargo::rustc-check-cfg=cfg(rust_analyzer)");
88

99
let rustc = env::var("RUSTC").expect("proc-macro-srv's build script expects RUSTC to be set");
10+
#[allow(clippy::disallowed_methods)]
1011
let output = Command::new(rustc).arg("--version").output().expect("rustc --version must run");
1112
let version_string = std::str::from_utf8(&output.stdout[..])
1213
.expect("rustc --version output must be UTF-8")

crates/proc-macro-srv/proc-macro-test/build.rs

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
//! a specific rustup toolchain: this allows testing against older ABIs (e.g.
88
//! 1.58) and future ABIs (stage1, nightly)
99
10+
#![allow(clippy::disallowed_methods)]
11+
1012
use std::{
1113
env,
1214
path::{Path, PathBuf},

crates/project-model/src/build_dependencies.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -172,16 +172,15 @@ impl WorkspaceBuildScripts {
172172
}
173173
let res = (|| {
174174
let target_libdir = (|| {
175-
let mut cargo_config = sysroot.tool(Tool::Cargo);
175+
let mut cargo_config = sysroot.tool(Tool::Cargo, current_dir);
176176
cargo_config.envs(extra_env);
177177
cargo_config
178-
.current_dir(current_dir)
179178
.args(["rustc", "-Z", "unstable-options", "--print", "target-libdir"])
180179
.env("RUSTC_BOOTSTRAP", "1");
181180
if let Ok(it) = utf8_stdout(&mut cargo_config) {
182181
return Ok(it);
183182
}
184-
let mut cmd = sysroot.tool(Tool::Rustc);
183+
let mut cmd = sysroot.tool(Tool::Rustc, current_dir);
185184
cmd.envs(extra_env);
186185
cmd.args(["--print", "target-libdir"]);
187186
utf8_stdout(&mut cmd)
@@ -390,12 +389,12 @@ impl WorkspaceBuildScripts {
390389
) -> io::Result<Command> {
391390
let mut cmd = match config.run_build_script_command.as_deref() {
392391
Some([program, args @ ..]) => {
393-
let mut cmd = Command::new(program);
392+
let mut cmd = toolchain::command(program, current_dir);
394393
cmd.args(args);
395394
cmd
396395
}
397396
_ => {
398-
let mut cmd = sysroot.tool(Tool::Cargo);
397+
let mut cmd = sysroot.tool(Tool::Cargo, current_dir);
399398

400399
cmd.args(["check", "--quiet", "--workspace", "--message-format=json"]);
401400
cmd.args(&config.extra_args);
@@ -448,7 +447,6 @@ impl WorkspaceBuildScripts {
448447
}
449448
};
450449

451-
cmd.current_dir(current_dir);
452450
cmd.envs(&config.extra_env);
453451
if config.wrap_rustc_in_build_scripts {
454452
// Setup RUSTC_WRAPPER to point to `rust-analyzer` binary itself. We use

crates/project-model/src/cargo_workspace.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ impl CargoWorkspace {
294294
no_deps: bool,
295295
progress: &dyn Fn(String),
296296
) -> anyhow::Result<(cargo_metadata::Metadata, Option<anyhow::Error>)> {
297-
let cargo = sysroot.tool(Tool::Cargo);
297+
let cargo = sysroot.tool(Tool::Cargo, current_dir);
298298
let mut meta = MetadataCommand::new();
299299
meta.cargo_path(cargo.get_program());
300300
cargo.get_envs().for_each(|(var, val)| _ = meta.env(var, val.unwrap_or_default()));

crates/project-model/src/env.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,9 @@ pub(crate) fn cargo_config_env(
7474
extra_env: &FxHashMap<String, String>,
7575
sysroot: &Sysroot,
7676
) -> FxHashMap<String, String> {
77-
let mut cargo_config = sysroot.tool(Tool::Cargo);
77+
let mut cargo_config = sysroot.tool(Tool::Cargo, manifest.parent());
7878
cargo_config.envs(extra_env);
7979
cargo_config
80-
.current_dir(manifest.parent())
8180
.args(["-Z", "unstable-options", "config", "get", "env"])
8281
.env("RUSTC_BOOTSTRAP", "1");
8382
if manifest.is_rust_manifest() {

crates/project-model/src/sysroot.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//! but we can't process `.rlib` and need source code instead. The source code
55
//! is typically installed with `rustup component add rust-src` command.
66
7-
use std::{env, fs, ops, process::Command};
7+
use std::{env, fs, ops, path::Path, process::Command};
88

99
use anyhow::{format_err, Result};
1010
use base_db::CrateName;
@@ -170,7 +170,7 @@ impl Sysroot {
170170
}
171171

172172
/// Returns a command to run a tool preferring the cargo proxies if the sysroot exists.
173-
pub fn tool(&self, tool: Tool) -> Command {
173+
pub fn tool(&self, tool: Tool, current_dir: impl AsRef<Path>) -> Command {
174174
match self.root() {
175175
Some(root) => {
176176
// special case rustc, we can look that up directly in the sysroot's bin folder
@@ -179,15 +179,15 @@ impl Sysroot {
179179
if let Some(path) =
180180
probe_for_binary(root.join("bin").join(Tool::Rustc.name()).into())
181181
{
182-
return Command::new(path);
182+
return toolchain::command(path, current_dir);
183183
}
184184
}
185185

186-
let mut cmd = Command::new(tool.prefer_proxy());
186+
let mut cmd = toolchain::command(tool.prefer_proxy(), current_dir);
187187
cmd.env("RUSTUP_TOOLCHAIN", AsRef::<std::path::Path>::as_ref(root));
188188
cmd
189189
}
190-
_ => Command::new(tool.path()),
190+
_ => toolchain::command(tool.path(), current_dir),
191191
}
192192
}
193193

@@ -436,7 +436,7 @@ fn discover_sysroot_dir(
436436
current_dir: &AbsPath,
437437
extra_env: &FxHashMap<String, String>,
438438
) -> Result<AbsPathBuf> {
439-
let mut rustc = Command::new(Tool::Rustc.path());
439+
let mut rustc = toolchain::command(Tool::Rustc.path(), current_dir);
440440
rustc.envs(extra_env);
441441
rustc.current_dir(current_dir).args(["--print", "sysroot"]);
442442
tracing::debug!("Discovering sysroot by {:?}", rustc);
@@ -468,9 +468,9 @@ fn discover_sysroot_src_dir_or_add_component(
468468
) -> Result<AbsPathBuf> {
469469
discover_sysroot_src_dir(sysroot_path)
470470
.or_else(|| {
471-
let mut rustup = Command::new(Tool::Rustup.prefer_proxy());
471+
let mut rustup = toolchain::command(Tool::Rustup.prefer_proxy(), current_dir);
472472
rustup.envs(extra_env);
473-
rustup.current_dir(current_dir).args(["component", "add", "rust-src"]);
473+
rustup.args(["component", "add", "rust-src"]);
474474
tracing::info!("adding rust-src component by {:?}", rustup);
475475
utf8_stdout(&mut rustup).ok()?;
476476
get_rust_src(sysroot_path)

crates/project-model/src/toolchain_info/rustc_cfg.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ fn rustc_print_cfg(
4545
const RUSTC_ARGS: [&str; 3] = ["--print", "cfg", "-O"];
4646
let sysroot = match config {
4747
QueryConfig::Cargo(sysroot, cargo_toml) => {
48-
let mut cmd = sysroot.tool(Tool::Cargo);
48+
let mut cmd = sysroot.tool(Tool::Cargo, cargo_toml.parent());
4949
cmd.envs(extra_env);
50-
cmd.current_dir(cargo_toml.parent()).env("RUSTC_BOOTSTRAP", "1");
50+
cmd.env("RUSTC_BOOTSTRAP", "1");
5151
cmd.args(["rustc", "-Z", "unstable-options"]).args(RUSTC_ARGS);
5252
if let Some(target) = target {
5353
cmd.args(["--target", target]);
@@ -67,7 +67,7 @@ fn rustc_print_cfg(
6767
QueryConfig::Rustc(sysroot) => sysroot,
6868
};
6969

70-
let mut cmd = sysroot.tool(Tool::Rustc);
70+
let mut cmd = sysroot.tool(Tool::Rustc, &std::env::current_dir()?);
7171
cmd.envs(extra_env);
7272
cmd.args(RUSTC_ARGS);
7373
if let Some(target) = target {

crates/project-model/src/toolchain_info/target_data_layout.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ pub fn get(
2121
};
2222
let sysroot = match config {
2323
QueryConfig::Cargo(sysroot, cargo_toml) => {
24-
let mut cmd = sysroot.tool(Tool::Cargo);
24+
let mut cmd = sysroot.tool(Tool::Cargo, cargo_toml.parent());
2525
cmd.envs(extra_env);
26-
cmd.current_dir(cargo_toml.parent()).env("RUSTC_BOOTSTRAP", "1");
26+
cmd.env("RUSTC_BOOTSTRAP", "1");
2727
cmd.args(["rustc", "-Z", "unstable-options"]).args(RUSTC_ARGS).args([
2828
"--",
2929
"-Z",
@@ -43,7 +43,7 @@ pub fn get(
4343
QueryConfig::Rustc(sysroot) => sysroot,
4444
};
4545

46-
let mut cmd = Sysroot::tool(sysroot, Tool::Rustc);
46+
let mut cmd = Sysroot::tool(sysroot, Tool::Rustc, &std::env::current_dir()?);
4747
cmd.envs(extra_env)
4848
.env("RUSTC_BOOTSTRAP", "1")
4949
.args(["-Z", "unstable-options"])

crates/project-model/src/toolchain_info/target_triple.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ fn rustc_discover_host_triple(
3232
extra_env: &FxHashMap<String, String>,
3333
sysroot: &Sysroot,
3434
) -> anyhow::Result<String> {
35-
let mut cmd = sysroot.tool(Tool::Rustc);
35+
let mut cmd = sysroot.tool(Tool::Rustc, &std::env::current_dir()?);
3636
cmd.envs(extra_env);
3737
cmd.arg("-vV");
3838
let stdout = utf8_stdout(&mut cmd)
@@ -52,7 +52,7 @@ fn cargo_config_build_target(
5252
extra_env: &FxHashMap<String, String>,
5353
sysroot: &Sysroot,
5454
) -> Option<Vec<String>> {
55-
let mut cmd = sysroot.tool(Tool::Cargo);
55+
let mut cmd = sysroot.tool(Tool::Cargo, cargo_toml.parent());
5656
cmd.envs(extra_env);
5757
cmd.current_dir(cargo_toml.parent()).env("RUSTC_BOOTSTRAP", "1");
5858
cmd.args(["-Z", "unstable-options", "config", "get", "build.target"]);

crates/project-model/src/workspace.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,9 @@ fn get_toolchain_version(
176176
prefix: &str,
177177
) -> Result<Option<Version>, anyhow::Error> {
178178
let cargo_version = utf8_stdout(&mut {
179-
let mut cmd = Sysroot::tool(sysroot, tool);
179+
let mut cmd = Sysroot::tool(sysroot, tool, current_dir);
180180
cmd.envs(extra_env);
181-
cmd.arg("--version").current_dir(current_dir);
181+
cmd.arg("--version");
182182
cmd
183183
})
184184
.with_context(|| format!("Failed to query rust toolchain version at {current_dir}, is your toolchain setup correctly?"))?;

crates/rust-analyzer/build.rs

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ fn set_rerun() {
3232
}
3333

3434
fn set_commit_info() {
35+
#[allow(clippy::disallowed_methods)]
3536
let output = match Command::new("git")
3637
.arg("log")
3738
.arg("-1")

crates/rust-analyzer/src/bin/rustc_wrapper.rs

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ fn run_rustc_skipping_cargo_checking(
4646
}
4747

4848
fn run_rustc(rustc_executable: OsString, args: Vec<OsString>) -> io::Result<ExitCode> {
49+
#[allow(clippy::disallowed_methods)]
4950
let mut child = Command::new(rustc_executable)
5051
.args(args)
5152
.stdin(Stdio::inherit())

crates/rust-analyzer/src/discover.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Infrastructure for lazy project discovery. Currently only support rust-project.json discovery
22
//! via a custom discover command.
3-
use std::{io, process::Command};
3+
use std::{io, path::Path};
44

55
use crossbeam_channel::Sender;
66
use paths::{AbsPathBuf, Utf8Path, Utf8PathBuf};
@@ -43,7 +43,11 @@ impl DiscoverCommand {
4343
}
4444

4545
/// Spawn the command inside [Discover] and report progress, if any.
46-
pub(crate) fn spawn(&self, discover_arg: DiscoverArgument) -> io::Result<DiscoverHandle> {
46+
pub(crate) fn spawn(
47+
&self,
48+
discover_arg: DiscoverArgument,
49+
current_dir: &Path,
50+
) -> io::Result<DiscoverHandle> {
4751
let command = &self.command[0];
4852
let args = &self.command[1..];
4953

@@ -58,7 +62,7 @@ impl DiscoverCommand {
5862
})
5963
.collect();
6064

61-
let mut cmd = Command::new(command);
65+
let mut cmd = toolchain::command(command, current_dir);
6266
cmd.args(args);
6367

6468
Ok(DiscoverHandle {

crates/rust-analyzer/src/flycheck.rs

+8-12
Original file line numberDiff line numberDiff line change
@@ -444,12 +444,11 @@ impl FlycheckActor {
444444
) -> Option<Command> {
445445
match &self.config {
446446
FlycheckConfig::CargoCommand { command, options, ansi_color_output } => {
447-
let mut cmd = Command::new(Tool::Cargo.path());
447+
let mut cmd = toolchain::command(Tool::Cargo.path(), &*self.root);
448448
if let Some(sysroot_root) = &self.sysroot_root {
449449
cmd.env("RUSTUP_TOOLCHAIN", AsRef::<std::path::Path>::as_ref(sysroot_root));
450450
}
451451
cmd.arg(command);
452-
cmd.current_dir(&*self.root);
453452

454453
match package {
455454
Some(pkg) => cmd.arg("-p").arg(pkg),
@@ -486,18 +485,15 @@ impl FlycheckActor {
486485
Some(cmd)
487486
}
488487
FlycheckConfig::CustomCommand { command, args, extra_env, invocation_strategy } => {
489-
let mut cmd = Command::new(command);
490-
cmd.envs(extra_env);
491-
492-
match invocation_strategy {
493-
InvocationStrategy::Once => {
494-
cmd.current_dir(&*self.root);
495-
}
488+
let root = match invocation_strategy {
489+
InvocationStrategy::Once => &*self.root,
496490
InvocationStrategy::PerWorkspace => {
497-
// FIXME: cmd.current_dir(&affected_workspace);
498-
cmd.current_dir(&*self.root);
491+
// FIXME: &affected_workspace
492+
&*self.root
499493
}
500-
}
494+
};
495+
let mut cmd = toolchain::command(command, root);
496+
cmd.envs(extra_env);
501497

502498
// If the custom command has a $saved_file placeholder, and
503499
// we're saving a file, replace the placeholder in the arguments.

0 commit comments

Comments
 (0)