Skip to content

Commit 4045b13

Browse files
rami3ldjc
authored andcommitted
fix!(config): re-enable active toolchain installation in Cfg::find_active_toolchain() with optional opt-out
1 parent b46e24c commit 4045b13

File tree

6 files changed

+80
-43
lines changed

6 files changed

+80
-43
lines changed

src/cli/common.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ pub(crate) async fn list_toolchains(
418418
let default_toolchain_name = cfg.get_default()?;
419419
let active_toolchain_name: Option<ToolchainName> =
420420
if let Ok(Some((LocalToolchainName::Named(toolchain), _reason))) =
421-
cfg.find_active_toolchain().await
421+
cfg.find_active_toolchain(None).await
422422
{
423423
Some(toolchain)
424424
} else {

src/cli/rustup_mode.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -753,7 +753,7 @@ async fn default_(
753753
}
754754
};
755755

756-
if let Some((toolchain, reason)) = cfg.find_active_toolchain().await? {
756+
if let Some((toolchain, reason)) = cfg.find_active_toolchain(None).await? {
757757
if !matches!(reason, ActiveReason::Default) {
758758
info!("note that the toolchain '{toolchain}' is currently in use ({reason})");
759759
}
@@ -964,7 +964,7 @@ async fn show(cfg: &Cfg<'_>, verbose: bool) -> Result<utils::ExitCode> {
964964
let installed_toolchains = cfg.list_toolchains()?;
965965
let active_toolchain_and_reason: Option<(ToolchainName, ActiveReason)> =
966966
if let Ok(Some((LocalToolchainName::Named(toolchain_name), reason))) =
967-
cfg.find_active_toolchain().await
967+
cfg.find_active_toolchain(None).await
968968
{
969969
Some((toolchain_name, reason))
970970
} else {
@@ -1084,7 +1084,7 @@ async fn show(cfg: &Cfg<'_>, verbose: bool) -> Result<utils::ExitCode> {
10841084

10851085
#[tracing::instrument(level = "trace", skip_all)]
10861086
async fn show_active_toolchain(cfg: &Cfg<'_>, verbose: bool) -> Result<utils::ExitCode> {
1087-
match cfg.find_active_toolchain().await? {
1087+
match cfg.find_active_toolchain(None).await? {
10881088
Some((toolchain_name, reason)) => {
10891089
let toolchain = Toolchain::with_reason(cfg, toolchain_name.clone(), &reason)?;
10901090
writeln!(
@@ -1316,7 +1316,7 @@ async fn toolchain_link(
13161316
async fn toolchain_remove(cfg: &mut Cfg<'_>, opts: UninstallOpts) -> Result<utils::ExitCode> {
13171317
let default_toolchain = cfg.get_default().ok().flatten();
13181318
let active_toolchain = cfg
1319-
.find_active_toolchain()
1319+
.find_active_toolchain(Some(false))
13201320
.await
13211321
.ok()
13221322
.flatten()

src/config.rs

+58-10
Original file line numberDiff line numberDiff line change
@@ -516,15 +516,63 @@ impl<'a> Cfg<'a> {
516516

517517
pub(crate) async fn find_active_toolchain(
518518
&self,
519+
force_install_active: Option<bool>,
519520
) -> Result<Option<(LocalToolchainName, ActiveReason)>> {
520-
Ok(
521-
if let Some((override_config, reason)) = self.find_override_config()? {
522-
Some((override_config.into_local_toolchain_name(), reason))
523-
} else {
524-
self.get_default()?
525-
.map(|x| (x.into(), ActiveReason::Default))
526-
},
527-
)
521+
let (components, targets, profile, toolchain, reason) = match self.find_override_config()? {
522+
Some((
523+
OverrideCfg::Official {
524+
components,
525+
targets,
526+
profile,
527+
toolchain,
528+
},
529+
reason,
530+
)) => (components, targets, profile, toolchain, reason),
531+
Some((override_config, reason)) => {
532+
return Ok(Some((override_config.into_local_toolchain_name(), reason)));
533+
}
534+
None => {
535+
return Ok(self
536+
.get_default()?
537+
.map(|x| (x.into(), ActiveReason::Default)));
538+
}
539+
};
540+
541+
let should_install_active = force_install_active.unwrap_or_else(|| {
542+
self.process
543+
.var("RUSTUP_AUTO_INSTALL")
544+
.map_or(true, |it| it != "0")
545+
});
546+
547+
if !should_install_active {
548+
return Ok(Some(((&toolchain).into(), reason)));
549+
}
550+
551+
let components = components.iter().map(AsRef::as_ref).collect::<Vec<_>>();
552+
let targets = targets.iter().map(AsRef::as_ref).collect::<Vec<_>>();
553+
match DistributableToolchain::new(self, toolchain.clone()) {
554+
Err(RustupError::ToolchainNotInstalled { .. }) => {
555+
DistributableToolchain::install(
556+
self,
557+
&toolchain,
558+
&components,
559+
&targets,
560+
profile.unwrap_or_default(),
561+
false,
562+
)
563+
.await?;
564+
}
565+
Ok(mut distributable) => {
566+
if !distributable.components_exist(&components, &targets)? {
567+
distributable
568+
.update(&components, &targets, profile.unwrap_or_default())
569+
.await?;
570+
}
571+
}
572+
Err(e) => return Err(e.into()),
573+
};
574+
575+
Ok(Some(((&toolchain).into(), reason)))
528576
}
529577

530578
fn find_override_config(&self) -> Result<Option<(OverrideCfg, ActiveReason)>> {
@@ -709,7 +757,7 @@ impl<'a> Cfg<'a> {
709757
self.set_toolchain_override(&ResolvableToolchainName::try_from(&t[1..])?);
710758
}
711759

712-
let Some((name, _)) = self.find_active_toolchain().await? else {
760+
let Some((name, _)) = self.find_active_toolchain(None).await? else {
713761
return Ok(None);
714762
};
715763
Ok(Some(Toolchain::new(self, name)?.rustc_version()))
@@ -739,7 +787,7 @@ impl<'a> Cfg<'a> {
739787
let toolchain = match name {
740788
Some(tc) => tc,
741789
None => {
742-
self.find_active_toolchain()
790+
self.find_active_toolchain(None)
743791
.await?
744792
.ok_or_else(|| no_toolchain_error(self.process))?
745793
.0

tests/suite/cli_rustup.rs

+8-12
Original file line numberDiff line numberDiff line change
@@ -1052,12 +1052,12 @@ async fn show_toolchain_override_not_installed() {
10521052
.expect_ok(&["rustup", "toolchain", "remove", "nightly"])
10531053
.await;
10541054
let out = cx.config.run("rustup", ["show"], &[]).await;
1055-
assert!(!out.ok);
1055+
assert!(out.ok);
10561056
assert!(
1057-
out.stderr
1057+
!out.stderr
10581058
.contains("is not installed: the directory override for")
10591059
);
1060-
assert!(!out.stderr.contains("info: installing component 'rustc'"));
1060+
assert!(out.stderr.contains("info: installing component 'rustc'"));
10611061
}
10621062

10631063
#[tokio::test]
@@ -1137,7 +1137,7 @@ async fn show_toolchain_env_not_installed() {
11371137
.run("rustup", ["show"], &[("RUSTUP_TOOLCHAIN", "nightly")])
11381138
.await;
11391139

1140-
assert!(!out.ok);
1140+
assert!(out.ok);
11411141

11421142
let expected_out = for_host_and_home!(
11431143
cx.config,
@@ -1149,17 +1149,13 @@ installed toolchains
11491149
11501150
active toolchain
11511151
----------------
1152+
name: nightly-{0}
1153+
active because: overridden by environment variable RUSTUP_TOOLCHAIN
1154+
installed targets:
1155+
{0}
11521156
"
11531157
);
11541158
assert!(&out.stdout == expected_out);
1155-
assert!(
1156-
out.stderr
1157-
== format!(
1158-
"error: override toolchain 'nightly-{}' is not installed: \
1159-
the RUSTUP_TOOLCHAIN environment variable specifies an uninstalled toolchain\n",
1160-
this_host_triple()
1161-
)
1162-
);
11631159
}
11641160

11651161
#[tokio::test]

tests/suite/cli_v1.rs

+3-7
Original file line numberDiff line numberDiff line change
@@ -182,14 +182,10 @@ async fn remove_override_toolchain_err_handling() {
182182
.expect_ok(&["rustup", "toolchain", "remove", "beta"])
183183
.await;
184184
cx.config
185-
.expect_err_ex(
185+
.expect_ok_contains(
186186
&["rustc", "--version"],
187-
"",
188-
for_host!(
189-
r"error: toolchain 'beta-{0}' is not installed
190-
help: run `rustup toolchain install beta-{0}` to install it
191-
"
192-
),
187+
"1.2.0 (hash-beta-1.2.0)",
188+
"info: downloading component 'rust'",
193189
)
194190
.await;
195191
}

tests/suite/cli_v2.rs

+6-9
Original file line numberDiff line numberDiff line change
@@ -327,14 +327,10 @@ async fn remove_override_toolchain_err_handling() {
327327
.expect_ok(&["rustup", "toolchain", "remove", "beta"])
328328
.await;
329329
cx.config
330-
.expect_err_ex(
330+
.expect_ok_contains(
331331
&["rustc", "--version"],
332-
"",
333-
for_host!(
334-
r"error: toolchain 'beta-{0}' is not installed
335-
help: run `rustup toolchain install beta-{0}` to install it
336-
"
337-
),
332+
"1.2.0 (hash-beta-1.2.0)",
333+
"info: downloading component 'rustc'",
338334
)
339335
.await;
340336
}
@@ -346,9 +342,10 @@ async fn file_override_toolchain_err_handling() {
346342
let toolchain_file = cwd.join("rust-toolchain");
347343
rustup::utils::raw::write_file(&toolchain_file, "beta").unwrap();
348344
cx.config
349-
.expect_err(
345+
.expect_ok_contains(
350346
&["rustc", "--version"],
351-
for_host!("toolchain 'beta-{0}' is not installed"),
347+
"1.2.0 (hash-beta-1.2.0)",
348+
"info: downloading component 'rustc'",
352349
)
353350
.await;
354351
}

0 commit comments

Comments
 (0)