diff --git a/src/rustup-cli/rustup_mode.rs b/src/rustup-cli/rustup_mode.rs index e3a2baf25b..9e2285f0ca 100644 --- a/src/rustup-cli/rustup_mode.rs +++ b/src/rustup-cli/rustup_mode.rs @@ -158,11 +158,13 @@ pub fn cli() -> App<'static, 'static> { .subcommand(SubCommand::with_name("install") .about("Install or update a given toolchain") .arg(Arg::with_name("toolchain") - .required(true))) + .required(true) + .multiple(true))) .subcommand(SubCommand::with_name("uninstall") .about("Uninstall a toolchain") .arg(Arg::with_name("toolchain") - .required(true))) + .required(true) + .multiple(true))) .subcommand(SubCommand::with_name("link") .about("Create a custom toolchain by symlinking to a directory") .arg(Arg::with_name("toolchain") @@ -172,15 +174,18 @@ pub fn cli() -> App<'static, 'static> { .subcommand(SubCommand::with_name("update") .setting(AppSettings::Hidden) // synonym for 'install' .arg(Arg::with_name("toolchain") - .required(true))) + .required(true) + .multiple(true))) .subcommand(SubCommand::with_name("add") .setting(AppSettings::Hidden) // synonym for 'install' .arg(Arg::with_name("toolchain") - .required(true))) + .required(true) + .multiple(true))) .subcommand(SubCommand::with_name("remove") .setting(AppSettings::Hidden) // synonym for 'uninstall' .arg(Arg::with_name("toolchain") - .required(true)))) + .required(true) + .multiple(true)))) .subcommand(SubCommand::with_name("target") .about("Modify a toolchain's supported targets") .setting(AppSettings::VersionlessSubcommands) @@ -458,21 +463,23 @@ fn default_(cfg: &Cfg, m: &ArgMatches) -> Result<()> { } fn update(cfg: &Cfg, m: &ArgMatches) -> Result<()> { - if let Some(name) = m.value_of("toolchain") { - try!(update_bare_triple_check(cfg, name)); - let toolchain = try!(cfg.get_toolchain(name, false)); - - let status = if !toolchain.is_custom() { - Some(try!(toolchain.install_from_dist())) - } else if !toolchain.exists() { - return Err(ErrorKind::ToolchainNotInstalled(toolchain.name().to_string()).into()); - } else { - None - }; + if let Some(names) = m.values_of("toolchain") { + for name in names { + try!(update_bare_triple_check(cfg, name)); + let toolchain = try!(cfg.get_toolchain(name, false)); + + let status = if !toolchain.is_custom() { + Some(try!(toolchain.install_from_dist())) + } else if !toolchain.exists() { + return Err(ErrorKind::ToolchainNotInstalled(toolchain.name().to_string()).into()); + } else { + None + }; - if let Some(status) = status { - println!(""); - try!(common::show_channel_update(cfg, toolchain.name(), Ok(status))); + if let Some(status) = status { + println!(""); + try!(common::show_channel_update(cfg, toolchain.name(), Ok(status))); + } } } else { try!(common::update_all_channels(cfg, !m.is_present("no-self-update") && !self_update::NEVER_SELF_UPDATE)); @@ -684,10 +691,11 @@ fn toolchain_link(cfg: &Cfg, m: &ArgMatches) -> Result<()> { } fn toolchain_remove(cfg: &Cfg, m: &ArgMatches) -> Result<()> { - let ref toolchain = m.value_of("toolchain").expect(""); - let toolchain = try!(cfg.get_toolchain(toolchain, false)); - - Ok(try!(toolchain.remove())) + for toolchain in m.values_of("toolchain").expect("") { + let toolchain = try!(cfg.get_toolchain(toolchain, false)); + try!(toolchain.remove()); + } + Ok(()) } fn override_add(cfg: &Cfg, m: &ArgMatches) -> Result<()> { diff --git a/tests/cli-v2.rs b/tests/cli-v2.rs index 98aa1f1bd7..1ec0e0de95 100644 --- a/tests/cli-v2.rs +++ b/tests/cli-v2.rs @@ -138,6 +138,32 @@ fn remove_toolchain() { }); } +#[test] +fn add_remove_multiple_toolchains() { + fn go(add: &str, rm: &str) { + setup(&|config| { + let tch1 = "beta"; + let tch2 = "nightly"; + + expect_ok(config, &["rustup", "toolchain", add, tch1, tch2]); + expect_ok(config, &["rustup", "toolchain", "list"]); + expect_stdout_ok(config, &["rustup", "toolchain", "list"], tch1); + expect_stdout_ok(config, &["rustup", "toolchain", "list"], tch2); + + expect_ok(config, &["rustup", "toolchain", rm, tch1, tch2]); + expect_ok(config, &["rustup", "toolchain", "list"]); + expect_not_stdout_ok(config, &["rustup", "toolchain", "list"], tch1); + expect_not_stdout_ok(config, &["rustup", "toolchain", "list"], tch2); + }); + } + + for add in &["add", "update", "install"] { + for rm in &["remove", "uninstall"] { + go(add, rm); + } + } +} + #[test] fn remove_default_toolchain_err_handling() { setup(&|config| {