From 2c0def4255b64b167470b6669c879b56c3df832e Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 21 Nov 2017 13:07:17 +0100 Subject: [PATCH] Add `rustup run --install`, fix #1293 --- src/rustup-cli/proxy_mode.rs | 2 +- src/rustup-cli/rustup_mode.rs | 5 ++++- src/rustup/config.rs | 6 +++++- tests/cli-misc.rs | 18 ++++++++++++++++++ 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/rustup-cli/proxy_mode.rs b/src/rustup-cli/proxy_mode.rs index 0c90d074fb..f865d927f7 100644 --- a/src/rustup-cli/proxy_mode.rs +++ b/src/rustup-cli/proxy_mode.rs @@ -49,7 +49,7 @@ pub fn main() -> Result<()> { fn direct_proxy(cfg: &Cfg, arg0: &str, toolchain: Option<&str>, args: &[OsString]) -> Result<()> { let cmd = match toolchain { None => try!(cfg.create_command_for_dir(&try!(utils::current_dir()), arg0)), - Some(tc) => try!(cfg.create_command_for_toolchain(tc, arg0)), + Some(tc) => try!(cfg.create_command_for_toolchain(tc, false, arg0)), }; Ok(try!(run_command_for_dir(cmd, arg0, args, &cfg))) } diff --git a/src/rustup-cli/rustup_mode.rs b/src/rustup-cli/rustup_mode.rs index f306f57daa..21524e1b5a 100644 --- a/src/rustup-cli/rustup_mode.rs +++ b/src/rustup-cli/rustup_mode.rs @@ -277,6 +277,9 @@ pub fn cli() -> App<'static, 'static> { .about("Run a command with an environment configured for a given toolchain") .after_help(RUN_HELP) .setting(AppSettings::TrailingVarArg) + .arg(Arg::with_name("install") + .help("Install the requested toolchain if needed") + .long("install")) .arg(Arg::with_name("toolchain") .help(TOOLCHAIN_ARG_HELP) .required(true)) @@ -482,7 +485,7 @@ fn run(cfg: &Cfg, m: &ArgMatches) -> Result<()> { let ref toolchain = m.value_of("toolchain").expect(""); let args = m.values_of("command").unwrap(); let args: Vec<_> = args.collect(); - let cmd = try!(cfg.create_command_for_toolchain(toolchain, args[0])); + let cmd = try!(cfg.create_command_for_toolchain(toolchain, m.is_present("install"), args[0])); Ok(try!(command::run_command_for_dir(cmd, args[0], &args[1..], &cfg))) } diff --git a/src/rustup/config.rs b/src/rustup/config.rs index b35bd02766..e915dacbc9 100644 --- a/src/rustup/config.rs +++ b/src/rustup/config.rs @@ -410,8 +410,12 @@ impl Cfg { } } - pub fn create_command_for_toolchain(&self, toolchain: &str, binary: &str) -> Result { + pub fn create_command_for_toolchain(&self, toolchain: &str, install_if_missing: bool, + binary: &str) -> Result { let ref toolchain = try!(self.get_toolchain(toolchain, false)); + if install_if_missing && !toolchain.exists() { + try!(toolchain.install_from_dist()); + } if let Some(cmd) = try!(self.maybe_do_cargo_fallback(toolchain, binary)) { Ok(cmd) diff --git a/tests/cli-misc.rs b/tests/cli-misc.rs index ca02c3cb23..907b517575 100644 --- a/tests/cli-misc.rs +++ b/tests/cli-misc.rs @@ -320,6 +320,24 @@ fn rustup_failed_path_search() { }); } +#[test] +fn rustup_run_not_installed() { + setup(&|config| { + expect_ok(config, &["rustup", "install", "stable"]); + expect_err(config, &["rustup", "run", "nightly", "rustc", "--version"], + for_host!("toolchain 'nightly-{0}' is not installed")); + }); +} + +#[test] +fn rustup_run_install() { + setup(&|config| { + expect_ok(config, &["rustup", "install", "stable"]); + expect_stderr_ok(config, &["rustup", "run", "--install", "nightly", "cargo", "--version"], + "info: installing component 'rustc'"); + }); +} + #[test] fn multirust_env_compat() { setup(&|config| {