Skip to content

Commit c8dec07

Browse files
committed
Recursive tool invocations should invoke the proxy, not the tool directly
The way the proxy was setting up the PATH variable contained two bugs: first, that it allowed the toolchain path to precede the value of CARGO_HOME/bin; but second that it didn't add CARGO_HOME/bin to the path at all. The result was that when e.g. cargo execs rustc, it was directly execing the toolchain rustc. Now it execs the proxy, assuming that CARGO_HOME/bin is set up correctly, and guaranteeing not to run the toolchain tool directly. Fixes #809
1 parent e3aa6ec commit c8dec07

File tree

3 files changed

+46
-5
lines changed

3 files changed

+46
-5
lines changed

src/rustup-mock/src/mock_bin_src.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::process::Command;
12
use std::io::{self, BufWriter, Write};
23

34
fn main() {
@@ -13,6 +14,11 @@ fn main() {
1314
for _ in 0 .. 10000 {
1415
buf.write_all(b"error: a value named `fail` has already been defined in this module [E0428]\n").unwrap();
1516
}
17+
} else if args.get(1) == Some(&"--call-rustc".to_string()) {
18+
// Used by the fallback_cargo_calls_correct_rustc test. Tests that
19+
// the environment has been set up right such that invoking rustc
20+
// will actually invoke the wrapper
21+
Command::new("rustc").arg("--version").status().unwrap();
1622
} else {
1723
panic!("bad mock proxy commandline");
1824
}

src/rustup/toolchain.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -321,13 +321,13 @@ impl<'a> Toolchain<'a> {
321321
}
322322
env_var::prepend_path(sysenv::LOADER_PATH, &new_path, cmd);
323323

324-
// Prepend first cargo_home, then toolchain/bin to the PATH
325-
let mut path_to_prepend = PathBuf::from("");
324+
// Prepend CARGO_HOME/bin to the PATH variable so that we're sure to run
325+
// cargo/rustc via the proxy bins. There is no fallback case for if the
326+
// proxy bins don't exist. We'll just be running whatever happens to
327+
// be on the PATH.
326328
if let Ok(cargo_home) = utils::cargo_home() {
327-
path_to_prepend.push(cargo_home.join("bin"));
329+
env_var::prepend_path("PATH", &cargo_home.join("bin"), cmd);
328330
}
329-
path_to_prepend.push(self.path.join("bin"));
330-
env_var::prepend_path("PATH", path_to_prepend.as_path(), cmd);
331331
}
332332

333333
pub fn doc_path(&self, relative: &str) -> Result<PathBuf> {

tests/cli-rustup.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ extern crate rustup_utils;
55
extern crate rustup_mock;
66
extern crate tempdir;
77

8+
use std::fs;
9+
use std::env::consts::EXE_SUFFIX;
810
use rustup_mock::clitools::{self, Config, Scenario,
911
expect_ok, expect_ok_ex,
1012
expect_stdout_ok,
@@ -269,6 +271,39 @@ fn link() {
269271
});
270272
}
271273

274+
// Issue #809. When we call the fallback cargo, when it in turn invokes
275+
// "rustc", that rustc should actually be the rustup proxy, not the toolchain rustc.
276+
// That way the proxy can pick the correct toolchain.
277+
#[test]
278+
fn fallback_cargo_calls_correct_rustc() {
279+
setup(&|config| {
280+
// Hm, this is the _only_ test that assumes that toolchain proxies
281+
// exist in CARGO_HOME. Adding that proxy here.
282+
let ref rustup_path = config.exedir.join(format!("rustup{}", EXE_SUFFIX));
283+
let ref cargo_bin_path = config.cargodir.join("bin");
284+
fs::create_dir_all(cargo_bin_path).unwrap();
285+
let ref rustc_path = cargo_bin_path.join(format!("rustc{}", EXE_SUFFIX));
286+
fs::hard_link(rustup_path, rustc_path).unwrap();
287+
288+
// Install a custom toolchain and a nightly toolchain for the cargo fallback
289+
let path = config.customdir.join("custom-1");
290+
let path = path.to_string_lossy();
291+
expect_ok(config, &["rustup", "toolchain", "link", "custom",
292+
&path]);
293+
expect_ok(config, &["rustup", "default", "custom"]);
294+
expect_ok(config, &["rustup", "update", "nightly"]);
295+
expect_stdout_ok(config, &["rustc", "--version"],
296+
"hash-c-1");
297+
298+
// Here --call-rustc tells the mock cargo bin to exec `rustc --version`.
299+
// We should be ultimately calling the custom rustc, according to the
300+
// RUSTUP_TOOLCHAIN variable set by the original "cargo" proxy, and
301+
// interpreted by the nested "rustc" proxy.
302+
expect_stdout_ok(config, &["cargo", "--call-rustc"],
303+
"hash-c-1");
304+
});
305+
}
306+
272307
#[test]
273308
fn show_toolchain_none() {
274309
setup(&|config| {

0 commit comments

Comments
 (0)