Skip to content

Commit f160fab

Browse files
committed
Merge pull request #164 from brson/cargo-fallback
Cargo fallback
2 parents e371c91 + 5aa1080 commit f160fab

File tree

4 files changed

+110
-11
lines changed

4 files changed

+110
-11
lines changed

src/multirust-cli/rustup_mode.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,10 +222,9 @@ fn update(cfg: &Cfg, m: &ArgMatches) -> Result<()> {
222222

223223
fn run(cfg: &Cfg, m: &ArgMatches) -> Result<()> {
224224
let ref toolchain = m.value_of("toolchain").expect("");
225-
let ref toolchain = try!(cfg.get_toolchain(toolchain, false));
226225
let args = m.values_of("command").unwrap();
227226
let args: Vec<_> = args.collect();
228-
let cmd = try!(toolchain.create_command(args[0]));
227+
let cmd = try!(cfg.create_command_for_toolchain(toolchain, args[0]));
229228

230229
common::run_inner(cmd, &args)
231230
}

src/multirust/config.rs

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,8 +336,52 @@ impl Cfg {
336336
}
337337

338338
pub fn create_command_for_dir(&self, path: &Path, binary: &str) -> Result<Command> {
339-
let (toolchain, _) = try!(self.toolchain_for_dir(path));
340-
toolchain.create_command(binary)
339+
let (ref toolchain, _) = try!(self.toolchain_for_dir(path));
340+
341+
if let Some(cmd) = try!(self.maybe_do_cargo_fallback(toolchain, binary)) {
342+
Ok(cmd)
343+
} else {
344+
toolchain.create_command(binary)
345+
}
346+
}
347+
348+
pub fn create_command_for_toolchain(&self, toolchain: &str, binary: &str) -> Result<Command> {
349+
let ref toolchain = try!(self.get_toolchain(toolchain, false));
350+
351+
if let Some(cmd) = try!(self.maybe_do_cargo_fallback(toolchain, binary)) {
352+
Ok(cmd)
353+
} else {
354+
toolchain.create_command(binary)
355+
}
356+
}
357+
358+
// Custom toolchains don't have cargo, so here we detect that situation and
359+
// try to find a different cargo.
360+
fn maybe_do_cargo_fallback(&self, toolchain: &Toolchain, binary: &str) -> Result<Option<Command>> {
361+
if !toolchain.is_custom() {
362+
return Ok(None);
363+
}
364+
365+
if binary != "cargo" && binary != "cargo.exe" {
366+
return Ok(None);
367+
}
368+
369+
let cargo_path = toolchain.path().join("bin/cargo");
370+
let cargo_exe_path = toolchain.path().join("bin/cargo.exe");
371+
372+
if cargo_path.exists() || cargo_exe_path.exists() {
373+
return Ok(None);
374+
}
375+
376+
for fallback in &["nightly", "beta", "stable"] {
377+
let fallback = try!(self.get_toolchain(fallback, false));
378+
if fallback.exists() {
379+
let cmd = try!(fallback.create_fallback_command("cargo", toolchain));
380+
return Ok(Some(cmd));
381+
}
382+
}
383+
384+
Ok(None)
341385
}
342386

343387
pub fn doc_path_for_dir(&self, path: &Path, relative: &str) -> Result<PathBuf> {

src/multirust/toolchain.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -229,14 +229,22 @@ impl<'a> Toolchain<'a> {
229229
return Err(Error::ToolchainNotInstalled(self.name.to_owned()));
230230
}
231231

232-
let mut cmd = Command::new(binary);
232+
let ref bin_path = self.path.join("bin").join(binary.as_ref());
233+
let mut cmd = Command::new(bin_path);
233234
self.set_env(&mut cmd);
234235
Ok(cmd)
235236
}
236237

237-
fn set_env(&self, cmd: &mut Command) {
238-
let ref bin_path = self.path.join("bin");
238+
// Create a command as a fallback for another toolchain. This is used
239+
// to give custom toolchains access to cargo
240+
pub fn create_fallback_command<T: AsRef<OsStr>>(&self, binary: T,
241+
primary_toolchain: &Toolchain) -> Result<Command> {
242+
let mut cmd = try!(self.create_command(binary));
243+
cmd.env("MULTIRUST_TOOLCHAIN", &primary_toolchain.name);
244+
Ok(cmd)
245+
}
239246

247+
fn set_env(&self, cmd: &mut Command) {
240248
self.set_ldpath(cmd);
241249

242250
// Because multirust and cargo use slightly different
@@ -247,12 +255,9 @@ impl<'a> Toolchain<'a> {
247255
cmd.env("CARGO_HOME", &cargo_home);
248256
}
249257

250-
env_var::set_path("PATH", bin_path, cmd);
251258
env_var::inc("RUST_RECURSION_COUNT", cmd);
252259

253-
// FIXME: This should not be a path, but a toolchain name.
254-
// Not sure what's going on here.
255-
cmd.env("MULTIRUST_TOOLCHAIN", &self.path);
260+
cmd.env("MULTIRUST_TOOLCHAIN", &self.name);
256261
cmd.env("MULTIRUST_HOME", &self.cfg.multirust_dir);
257262
}
258263

tests/cli-misc.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,3 +671,54 @@ fn multi_host_smoke_test() {
671671
"xxxx-n-2"); // cross-host mocks have their own versions
672672
});
673673
}
674+
675+
#[test]
676+
fn custom_toolchain_cargo_fallback_proxy() {
677+
setup(&|config| {
678+
let path = config.customdir.join("custom-1");
679+
680+
expect_ok(config, &["rustup", "toolchain", "link", "mytoolchain",
681+
&path.to_string_lossy()]);
682+
expect_ok(config, &["rustup", "default", "mytoolchain"]);
683+
684+
expect_ok(config, &["rustup", "update", "stable"]);
685+
expect_stdout_ok(config, &["cargo", "--version"],
686+
"hash-s-2");
687+
688+
expect_ok(config, &["rustup", "update", "beta"]);
689+
expect_stdout_ok(config, &["cargo", "--version"],
690+
"hash-b-2");
691+
692+
expect_ok(config, &["rustup", "update", "nightly"]);
693+
expect_stdout_ok(config, &["cargo", "--version"],
694+
"hash-n-2");
695+
});
696+
}
697+
698+
#[test]
699+
fn custom_toolchain_cargo_fallback_run() {
700+
setup(&|config| {
701+
let path = config.customdir.join("custom-1");
702+
703+
expect_ok(config, &["rustup", "toolchain", "link", "mytoolchain",
704+
&path.to_string_lossy()]);
705+
expect_ok(config, &["rustup", "default", "mytoolchain"]);
706+
707+
expect_ok(config, &["rustup", "update", "stable"]);
708+
expect_stdout_ok(config, &["rustup", "run", "mytoolchain",
709+
"cargo", "--version"],
710+
"hash-s-2");
711+
712+
expect_ok(config, &["rustup", "update", "beta"]);
713+
expect_stdout_ok(config, &["rustup", "run", "mytoolchain",
714+
"cargo", "--version"],
715+
"hash-b-2");
716+
717+
expect_ok(config, &["rustup", "update", "nightly"]);
718+
expect_stdout_ok(config, &["rustup", "run", "mytoolchain",
719+
"cargo", "--version"],
720+
"hash-n-2");
721+
722+
});
723+
}
724+

0 commit comments

Comments
 (0)