Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(rustup-mode): install the active toolchain by default on rustup toolchain install #3983

Merged
merged 4 commits into from
Aug 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 19 additions & 8 deletions src/cli/rustup_mode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,14 @@ fn plus_toolchain_value_parser(s: &str) -> clap::error::Result<ResolvableToolcha
#[derive(Debug, Subcommand)]
#[command(name = "rustup", bin_name = "rustup[EXE]")]
enum RustupSubcmd {
/// Update Rust toolchains
/// Install or update the given toolchains, or by default the active toolchain
#[command(hide = true, after_help = INSTALL_HELP)]
Install {
#[command(flatten)]
opts: UpdateOpts,
},

/// Uninstall Rust toolchains
/// Uninstall the given toolchains
#[command(hide = true)]
Uninstall {
#[command(flatten)]
Expand Down Expand Up @@ -302,14 +302,14 @@ enum ToolchainSubcmd {
quiet: bool,
},

/// Install or update a given toolchain
/// Install or update the given toolchains, or by default the active toolchain
#[command(aliases = ["update", "add"] )]
Install {
#[command(flatten)]
opts: UpdateOpts,
},

/// Uninstall a toolchain
/// Uninstall the given toolchains
#[command(alias = "remove")]
Uninstall {
#[command(flatten)]
Expand All @@ -330,7 +330,6 @@ enum ToolchainSubcmd {
#[derive(Debug, Default, Args)]
struct UpdateOpts {
#[arg(
required = true,
help = OFFICIAL_TOOLCHAIN_ARG_HELP,
num_args = 1..,
)]
Expand Down Expand Up @@ -584,7 +583,7 @@ pub async fn main(current_dir: PathBuf, process: &Process) -> Result<utils::Exit

match subcmd {
RustupSubcmd::DumpTestament => 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),
Expand All @@ -610,11 +609,12 @@ pub async fn main(current_dir: PathBuf, process: &Process) -> Result<utils::Exit
force_non_host,
..UpdateOpts::default()
},
false,
)
.await
}
RustupSubcmd::Toolchain { subcmd } => 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))
}
Expand Down Expand Up @@ -791,7 +791,11 @@ async fn check_updates(cfg: &Cfg<'_>) -> Result<utils::ExitCode> {
Ok(utils::ExitCode(0))
}

async fn update(cfg: &mut Cfg<'_>, opts: UpdateOpts) -> Result<utils::ExitCode> {
async fn update(
cfg: &mut Cfg<'_>,
opts: UpdateOpts,
ensure_active_toolchain: bool,
) -> Result<utils::ExitCode> {
let mut exit_code = utils::ExitCode(0);

common::warn_if_host_is_emulated(cfg.process);
Expand Down Expand Up @@ -861,6 +865,13 @@ async fn update(cfg: &mut Cfg<'_>, opts: UpdateOpts) -> Result<utils::ExitCode>
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");
Expand Down
15 changes: 9 additions & 6 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
}
}

Expand Down Expand Up @@ -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,
})
}

Expand All @@ -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) => {
Expand All @@ -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))
Expand All @@ -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))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ Usage: rustup[EXE] toolchain <COMMAND>

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)

Expand Down
Original file line number Diff line number Diff line change
@@ -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] <TOOLCHAIN>...
Usage: rustup[EXE] toolchain install [OPTIONS] [TOOLCHAIN]...

Arguments:
<TOOLCHAIN>... 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:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
bin.name = "rustup"
args = ["toolchain", "uninstall", "--help"]
stdout = """
...
Uninstall a toolchain
Uninstall the given toolchains

Usage: rustup[EXE] toolchain uninstall <TOOLCHAIN>...

Expand Down
56 changes: 41 additions & 15 deletions tests/suite/cli_rustup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down
Loading