diff --git a/tools/cargos/src/main.rs b/tools/cargos/src/main.rs index 82d04e33a1..0b969afcd9 100644 --- a/tools/cargos/src/main.rs +++ b/tools/cargos/src/main.rs @@ -27,7 +27,7 @@ use std::{ env, fmt, io::{self, Read as _}, - process::{self, Command}, + process::{self, Command, Output}, }; use serde_json::{Map, Value}; @@ -92,11 +92,10 @@ fn get_toolchain_versions() -> Versions { // use Cargo with that toolchain, `pkg-meta` would return `null` when asked // to retrieve the `rust-version` field. This also requires `RUSTFLAGS=''` // to override any unstable `RUSTFLAGS` set by the caller. - let output = Command::new("rustup") - .args(["run", "stable", "cargo", "metadata", "--format-version", "1"]) - .env("CARGO_TARGET_DIR", "target/cargos") - .output() - .unwrap(); + let output = rustup( + ["run", "stable", "cargo", "metadata", "--format-version", "1"], + Some(("CARGO_TARGET_DIR", "target/cargos")), + ); let json = serde_json::from_slice::(&output.stdout).unwrap(); let packages = json.as_object().unwrap().get("packages").unwrap(); @@ -124,14 +123,10 @@ fn get_toolchain_versions() -> Versions { } fn is_toolchain_installed(versions: &Versions, name: &str) -> Result { - let output = Command::new("rustup") - .args(["run", versions.get(name)?, "cargo", "version"]) - .output() - .unwrap(); - + let version = versions.get(name)?; + let output = rustup(["run", version, "cargo", "version"], None); if output.status.success() { - let output = Command::new("rustup").args(["component", "list"]).output().unwrap(); - + let output = rustup([&format!("+{version}"), "component", "list"], None); let stdout = String::from_utf8(output.stdout).unwrap(); Ok(stdout.contains("rust-src (installed)")) } else { @@ -147,9 +142,8 @@ fn install_toolchain_or_exit(versions: &Versions, name: &str) -> Result<(), Erro process::exit(1); } - eprintln!("[cargos] would you like to install toolchain '{name}' and component 'rust-src' via 'rustup'? yn"); - loop { + eprint!("[cargos] would you like to install toolchain '{name}' and component 'rust-src' via 'rustup' (y/n)? "); let mut input = [0]; io::stdin().read_exact(&mut input).unwrap(); match input[0] as char { @@ -176,6 +170,18 @@ fn get_rustflags(name: &str) -> &'static str { } } +fn rustup<'a>(args: impl IntoIterator, env: Option<(&str, &str)>) -> Output { + let mut cmd = Command::new("rustup"); + // It's important to set `RUSTUP_TOOLCHAIN` to override any value set while + // running this program. That variable overrides any `+` CLI + // argument. + cmd.args(args).env("RUSTUP_TOOLCHAIN", ""); + if let Some((name, val)) = env { + cmd.env(name, val); + } + cmd.output().unwrap() +} + fn delegate_cargo() -> Result<(), Error> { let mut args = env::args(); let this = args.next().unwrap();