diff --git a/src/cli/rustup_mode.rs b/src/cli/rustup_mode.rs index af76b7ef0f..03a6470805 100644 --- a/src/cli/rustup_mode.rs +++ b/src/cli/rustup_mode.rs @@ -100,14 +100,14 @@ fn plus_toolchain_value_parser(s: &str) -> clap::error::Result Result common::dump_testament(process), - RustupSubcmd::Install { opts } => update(cfg, opts).await, + RustupSubcmd::Install { opts } => update(cfg, opts, true).await, RustupSubcmd::Uninstall { opts } => toolchain_remove(cfg, opts), RustupSubcmd::Show { verbose, subcmd } => handle_epipe(match subcmd { None => show(cfg, verbose), @@ -610,11 +609,12 @@ pub async fn main(current_dir: PathBuf, process: &Process) -> Result match subcmd { - ToolchainSubcmd::Install { opts } => update(cfg, opts).await, + ToolchainSubcmd::Install { opts } => update(cfg, opts, true).await, ToolchainSubcmd::List { verbose, quiet } => { handle_epipe(common::list_toolchains(cfg, verbose, quiet)) } @@ -791,7 +791,11 @@ async fn check_updates(cfg: &Cfg<'_>) -> Result { Ok(utils::ExitCode(0)) } -async fn update(cfg: &mut Cfg<'_>, opts: UpdateOpts) -> Result { +async fn update( + cfg: &mut Cfg<'_>, + opts: UpdateOpts, + ensure_active_toolchain: bool, +) -> Result { let mut exit_code = utils::ExitCode(0); common::warn_if_host_is_emulated(cfg.process); @@ -861,6 +865,13 @@ async fn update(cfg: &mut Cfg<'_>, opts: UpdateOpts) -> Result if self_update { exit_code &= common::self_update(|| Ok(()), cfg.process).await?; } + } else if ensure_active_toolchain { + let (toolchain, reason) = cfg.find_or_install_active_toolchain(true).await?; + info!( + "the active toolchain `{}` has been installed", + toolchain.name() + ); + info!("it's active because: {reason}"); } else { exit_code &= common::update_all_channels(cfg, self_update, opts.force).await?; info!("cleaning up downloads & tmp directories"); diff --git a/src/config.rs b/src/config.rs index 8990b5a47e..6cc1165948 100644 --- a/src/config.rs +++ b/src/config.rs @@ -510,7 +510,7 @@ impl<'a> Cfg<'a> { LocalToolchainName::Named(ToolchainName::Official(desc)), )?) } - None => Ok(self.find_or_install_active_toolchain().await?.0), + None => Ok(self.find_or_install_active_toolchain(false).await?.0), } } @@ -718,7 +718,7 @@ impl<'a> Cfg<'a> { let desc = name.resolve(&self.get_default_host_triple()?)?; Toolchain::new(self, desc.into())? } - None => self.find_or_install_active_toolchain().await?.0, + None => self.find_or_install_active_toolchain(false).await?.0, }) } @@ -732,12 +732,15 @@ impl<'a> Cfg<'a> { Ok(match local { Some(tc) => Toolchain::from_local(tc, false, self).await?, - None => self.find_or_install_active_toolchain().await?.0, + None => self.find_or_install_active_toolchain(false).await?.0, }) } #[tracing::instrument(level = "trace", skip_all)] - async fn find_or_install_active_toolchain(&'a self) -> Result<(Toolchain<'a>, ActiveReason)> { + pub(crate) async fn find_or_install_active_toolchain( + &'a self, + verbose: bool, + ) -> Result<(Toolchain<'a>, ActiveReason)> { match self.find_override_config()? { Some((override_config, reason)) => match override_config { OverrideCfg::PathBased(path_based_name) => { @@ -755,7 +758,7 @@ impl<'a> Cfg<'a> { profile, } => { let toolchain = self - .ensure_installed(&toolchain, components, targets, profile, false) + .ensure_installed(&toolchain, components, targets, profile, verbose) .await? .1; Ok((toolchain, reason)) @@ -771,7 +774,7 @@ impl<'a> Cfg<'a> { Some(ToolchainName::Official(toolchain_desc)) => { let reason = ActiveReason::Default; let toolchain = self - .ensure_installed(&toolchain_desc, vec![], vec![], None, false) + .ensure_installed(&toolchain_desc, vec![], vec![], None, verbose) .await? .1; Ok((toolchain, reason)) diff --git a/tests/suite/cli-ui/rustup/rustup_toolchain_cmd_help_flag_stdout.toml b/tests/suite/cli-ui/rustup/rustup_toolchain_cmd_help_flag_stdout.toml index 9485b6323b..841e8232ea 100644 --- a/tests/suite/cli-ui/rustup/rustup_toolchain_cmd_help_flag_stdout.toml +++ b/tests/suite/cli-ui/rustup/rustup_toolchain_cmd_help_flag_stdout.toml @@ -8,8 +8,8 @@ Usage: rustup[EXE] toolchain Commands: list List installed toolchains - install Install or update a given toolchain - uninstall Uninstall a toolchain + install Install or update the given toolchains, or by default the active toolchain + uninstall Uninstall the given toolchains link Create a custom toolchain by symlinking to a directory help Print this message or the help of the given subcommand(s) diff --git a/tests/suite/cli-ui/rustup/rustup_toolchain_cmd_install_cmd_help_flag_stdout.toml b/tests/suite/cli-ui/rustup/rustup_toolchain_cmd_install_cmd_help_flag_stdout.toml index e986981ed9..6c56df7f7e 100644 --- a/tests/suite/cli-ui/rustup/rustup_toolchain_cmd_install_cmd_help_flag_stdout.toml +++ b/tests/suite/cli-ui/rustup/rustup_toolchain_cmd_install_cmd_help_flag_stdout.toml @@ -1,13 +1,12 @@ bin.name = "rustup" args = ["toolchain", "install", "--help"] stdout = """ -... -Install or update a given toolchain +Install or update the given toolchains, or by default the active toolchain -Usage: rustup[EXE] toolchain install [OPTIONS] ... +Usage: rustup[EXE] toolchain install [OPTIONS] [TOOLCHAIN]... Arguments: - ... Toolchain name, such as 'stable', 'nightly', or '1.8.0'. For more information see + [TOOLCHAIN]... Toolchain name, such as 'stable', 'nightly', or '1.8.0'. For more information see `rustup help toolchain` Options: diff --git a/tests/suite/cli-ui/rustup/rustup_toolchain_cmd_uninstall_cmd_help_flag_stdout.toml b/tests/suite/cli-ui/rustup/rustup_toolchain_cmd_uninstall_cmd_help_flag_stdout.toml index 42be34c34a..40fb0fdbf7 100644 --- a/tests/suite/cli-ui/rustup/rustup_toolchain_cmd_uninstall_cmd_help_flag_stdout.toml +++ b/tests/suite/cli-ui/rustup/rustup_toolchain_cmd_uninstall_cmd_help_flag_stdout.toml @@ -1,8 +1,7 @@ bin.name = "rustup" args = ["toolchain", "uninstall", "--help"] stdout = """ -... -Uninstall a toolchain +Uninstall the given toolchains Usage: rustup[EXE] toolchain uninstall ... diff --git a/tests/suite/cli_rustup.rs b/tests/suite/cli_rustup.rs index 5ae0e97385..b246fb9645 100644 --- a/tests/suite/cli_rustup.rs +++ b/tests/suite/cli_rustup.rs @@ -1450,12 +1450,49 @@ async fn toolchain_install_is_like_update_quiet() { } #[tokio::test] -async fn toolchain_install_is_like_update_except_that_bare_install_is_an_error() { - let cx = CliTestContext::new(Scenario::None).await; +async fn toolchain_install_without_args_installs_active() { + let cx = CliTestContext::new(Scenario::SimpleV2).await; + + let cwd = cx.config.current_dir(); + let toolchain_file = cwd.join("rust-toolchain.toml"); + raw::write_file( + &toolchain_file, + r#" +[toolchain] +profile = "minimal" +channel = "nightly" +"#, + ) + .unwrap(); + cx.config - .expect_err( + .expect_stderr_ok( &["rustup", "toolchain", "install"], - "arguments were not provided", + &format!( + "\ +info: syncing channel updates for 'nightly-{0}' +info: latest update on 2015-01-02, rust version 1.3.0 (hash-nightly-2) +info: downloading component 'rustc' +info: installing component 'rustc' +info: the active toolchain `nightly-{0}` has been installed +info: it's active because: overridden by '{1}'", + this_host_triple(), + toolchain_file.display(), + ), + ) + .await; + + cx.config + .expect_stderr_ok( + &["rustup", "toolchain", "install"], + &format!( + "\ +info: using existing install for 'nightly-{0}' +info: the active toolchain `nightly-{0}` has been installed +info: it's active because: overridden by '{1}'", + this_host_triple(), + toolchain_file.display(), + ), ) .await; } @@ -1494,17 +1531,6 @@ async fn toolchain_uninstall_is_like_uninstall() { .await; } -#[tokio::test] -async fn toolchain_update_is_like_update_except_that_bare_install_is_an_error() { - let cx = CliTestContext::new(Scenario::None).await; - cx.config - .expect_err( - &["rustup", "toolchain", "update"], - "arguments were not provided", - ) - .await; -} - #[tokio::test] async fn proxy_toolchain_shorthand() { let mut cx = CliTestContext::new(Scenario::SimpleV2).await;