diff --git a/src/cli/proxy_mode.rs b/src/cli/proxy_mode.rs index 753579aa0c..de55f9a99c 100644 --- a/src/cli/proxy_mode.rs +++ b/src/cli/proxy_mode.rs @@ -32,6 +32,6 @@ pub async fn main(arg0: &str, current_dir: PathBuf, process: &Process) -> Result .collect(); let cfg = set_globals(current_dir, false, true, process)?; - let cmd = cfg.local_toolchain(toolchain).await?.command(arg0)?; + let cmd = cfg.resolve_local_toolchain(toolchain)?.command(arg0)?; run_command_for_dir(cmd, arg0, &cmd_args) } diff --git a/src/cli/rustup_mode.rs b/src/cli/rustup_mode.rs index 03a6470805..89fd348f23 100644 --- a/src/cli/rustup_mode.rs +++ b/src/cli/rustup_mode.rs @@ -908,7 +908,7 @@ async fn which( binary: &str, toolchain: Option, ) -> Result { - let binary_path = cfg.resolve_toolchain(toolchain).await?.binary_file(binary); + let binary_path = cfg.resolve_toolchain(toolchain)?.binary_file(binary); utils::assert_is_file(&binary_path)?; @@ -1097,7 +1097,7 @@ async fn target_list( quiet: bool, ) -> Result { // downcasting required because the toolchain files can name any toolchain - let distributable = DistributableToolchain::from_partial(toolchain, cfg).await?; + let distributable = DistributableToolchain::from_partial(toolchain, cfg)?; common::list_items( distributable, |c| { @@ -1124,7 +1124,7 @@ async fn target_add( // isn't a feature yet. // list_components *and* add_component would both be inappropriate for // custom toolchains. - let distributable = DistributableToolchain::from_partial(toolchain, cfg).await?; + let distributable = DistributableToolchain::from_partial(toolchain, cfg)?; let components = distributable.components()?; if targets.contains(&"all".to_string()) { @@ -1168,7 +1168,7 @@ async fn target_remove( targets: Vec, toolchain: Option, ) -> Result { - let distributable = DistributableToolchain::from_partial(toolchain, cfg).await?; + let distributable = DistributableToolchain::from_partial(toolchain, cfg)?; for target in targets { let target = TargetTriple::new(target); @@ -1204,7 +1204,7 @@ async fn component_list( quiet: bool, ) -> Result { // downcasting required because the toolchain files can name any toolchain - let distributable = DistributableToolchain::from_partial(toolchain, cfg).await?; + let distributable = DistributableToolchain::from_partial(toolchain, cfg)?; common::list_items( distributable, |c| Some(&c.name), @@ -1220,7 +1220,7 @@ async fn component_add( toolchain: Option, target: Option, ) -> Result { - let distributable = DistributableToolchain::from_partial(toolchain, cfg).await?; + let distributable = DistributableToolchain::from_partial(toolchain, cfg)?; let target = get_target(target, &distributable); for component in &components { @@ -1246,7 +1246,7 @@ async fn component_remove( toolchain: Option, target: Option, ) -> Result { - let distributable = DistributableToolchain::from_partial(toolchain, cfg).await?; + let distributable = DistributableToolchain::from_partial(toolchain, cfg)?; let target = get_target(target, &distributable); for component in &components { @@ -1447,7 +1447,7 @@ async fn doc( mut topic: Option<&str>, doc_page: &DocPage, ) -> Result { - let toolchain = cfg.toolchain_from_partial(toolchain).await?; + let toolchain = cfg.toolchain_from_partial(toolchain)?; if let Ok(distributable) = DistributableToolchain::try_from(&toolchain) { if let [_] = distributable @@ -1508,7 +1508,7 @@ async fn man( command: &str, toolchain: Option, ) -> Result { - let toolchain = cfg.toolchain_from_partial(toolchain).await?; + let toolchain = cfg.toolchain_from_partial(toolchain)?; let path = toolchain.man_path(); utils::assert_is_directory(&path)?; diff --git a/src/config.rs b/src/config.rs index 6cc1165948..52c26285fa 100644 --- a/src/config.rs +++ b/src/config.rs @@ -498,20 +498,18 @@ impl<'a> Cfg<'a> { .transpose()?) } - pub(crate) async fn toolchain_from_partial( + pub(crate) fn toolchain_from_partial( &self, toolchain: Option, ) -> anyhow::Result> { - match toolchain { + let toolchain = match toolchain { Some(toolchain) => { let desc = toolchain.resolve(&self.get_default_host_triple()?)?; - Ok(Toolchain::new( - self, - LocalToolchainName::Named(ToolchainName::Official(desc)), - )?) + Some(LocalToolchainName::Named(ToolchainName::Official(desc))) } - None => Ok(self.find_or_install_active_toolchain(false).await?.0), - } + None => None, + }; + self.local_toolchain(toolchain) } pub(crate) fn find_active_toolchain( @@ -709,31 +707,40 @@ impl<'a> Cfg<'a> { Ok(Some(Toolchain::new(self, name)?.rustc_version())) } - pub(crate) async fn resolve_toolchain( + pub(crate) fn resolve_toolchain( &self, name: Option, ) -> Result> { - Ok(match name { + let toolchain = match name { Some(name) => { let desc = name.resolve(&self.get_default_host_triple()?)?; - Toolchain::new(self, desc.into())? + Some(desc.into()) } - None => self.find_or_install_active_toolchain(false).await?.0, - }) + None => None, + }; + self.local_toolchain(toolchain) } - pub(crate) async fn local_toolchain( + pub(crate) fn resolve_local_toolchain( &self, name: Option, ) -> Result> { let local = name .map(|name| name.resolve(&self.get_default_host_triple()?)) .transpose()?; + self.local_toolchain(local) + } - Ok(match local { - Some(tc) => Toolchain::from_local(tc, false, self).await?, - None => self.find_or_install_active_toolchain(false).await?.0, - }) + fn local_toolchain(&self, name: Option) -> Result> { + let toolchain = match name { + Some(tc) => tc, + None => { + self.find_active_toolchain()? + .ok_or_else(|| no_toolchain_error(self.process))? + .0 + } + }; + Ok(Toolchain::new(self, toolchain)?) } #[tracing::instrument(level = "trace", skip_all)] diff --git a/src/toolchain/distributable.rs b/src/toolchain/distributable.rs index 45cfa4da05..49a6cb6700 100644 --- a/src/toolchain/distributable.rs +++ b/src/toolchain/distributable.rs @@ -33,13 +33,11 @@ pub(crate) struct DistributableToolchain<'a> { } impl<'a> DistributableToolchain<'a> { - pub(crate) async fn from_partial( + pub(crate) fn from_partial( toolchain: Option, cfg: &'a Cfg<'a>, ) -> anyhow::Result { - Ok(Self::try_from( - &cfg.toolchain_from_partial(toolchain).await?, - )?) + Ok(Self::try_from(&cfg.toolchain_from_partial(toolchain)?)?) } pub(crate) fn new(cfg: &'a Cfg<'a>, desc: ToolchainDesc) -> Result { diff --git a/tests/suite/cli_misc.rs b/tests/suite/cli_misc.rs index e8f3588d73..69a13983b1 100644 --- a/tests/suite/cli_misc.rs +++ b/tests/suite/cli_misc.rs @@ -1099,6 +1099,10 @@ async fn which_asking_uninstalled_toolchain() { #[tokio::test] async fn override_by_toolchain_on_the_command_line() { let mut cx = CliTestContext::new(Scenario::SimpleV2).await; + cx.config + .expect_ok(&["rustup", "toolchain", "install", "stable", "nightly"]) + .await; + #[cfg(windows)] cx.config .expect_stdout_ok( diff --git a/tests/suite/cli_rustup.rs b/tests/suite/cli_rustup.rs index b246fb9645..5eb5d3dd4b 100644 --- a/tests/suite/cli_rustup.rs +++ b/tests/suite/cli_rustup.rs @@ -932,47 +932,6 @@ async fn list_default_and_override_toolchain() { .await; } -#[tokio::test] -async fn heal_damaged_toolchain() { - let mut cx = CliTestContext::new(Scenario::SimpleV2).await; - cx.config.expect_ok(&["rustup", "default", "nightly"]).await; - cx.config - .expect_not_stderr_ok(&["rustup", "which", "rustc"], "syncing channel updates") - .await; - let manifest_path = format!( - "toolchains/nightly-{}/lib/rustlib/multirust-channel-manifest.toml", - this_host_triple() - ); - - let mut rustc_path = cx.config.rustupdir.join( - [ - "toolchains", - &format!("nightly-{}", this_host_triple()), - "bin", - "rustc", - ] - .iter() - .collect::(), - ); - - if cfg!(windows) { - rustc_path.set_extension("exe"); - } - - fs::remove_file(cx.config.rustupdir.join(manifest_path)).unwrap(); - cx.config - .expect_ok_ex( - &["rustup", "which", "rustc"], - &format!("{}\n", rustc_path.to_str().unwrap()), - for_host!("info: syncing channel updates for 'nightly-{0}'\n"), - ) - .await; - cx.config.expect_ok(&["rustup", "default", "nightly"]).await; - cx.config - .expect_stderr_ok(&["rustup", "which", "rustc"], "syncing channel updates") - .await; -} - #[tokio::test] #[ignore = "FIXME: Windows shows UNC paths"] async fn show_toolchain_override() { @@ -2133,7 +2092,7 @@ async fn file_override_toml_format_install_both_toolchain_and_components() { cx.config.expect_ok(&["rustup", "default", "stable"]).await; } - let cx = cx.with_dist_dir(Scenario::ArchivesV2_2015_01_01); + let mut cx = cx.with_dist_dir(Scenario::ArchivesV2_2015_01_01); cx.config .expect_stdout_ok(&["rustc", "--version"], "hash-stable-1.1.0") .await; @@ -2153,6 +2112,9 @@ components = [ "rust-src" ] ) .unwrap(); + cx.config + .expect_ok(&["rustup", "toolchain", "install"]) + .await; cx.config .expect_stdout_ok(&["rustc", "--version"], "hash-nightly-1") .await; @@ -2180,6 +2142,12 @@ components = [ "rust-src" ] ) .unwrap(); + cx.config + .expect_stderr_ok( + &["rustup", "toolchain", "install"], + "info: installing component 'rust-src'", + ) + .await; cx.config .expect_stdout_ok(&["rustup", "component", "list"], "rust-src (installed)") .await; @@ -2207,6 +2175,12 @@ targets = [ "arm-linux-androideabi" ] ) .unwrap(); + cx.config + .expect_stderr_ok( + &["rustup", "toolchain", "install"], + "info: installing component 'rust-std' for 'arm-linux-androideabi'", + ) + .await; cx.config .expect_stdout_ok( &["rustup", "component", "list"], @@ -2233,7 +2207,7 @@ components = [ "rust-bongo" ] cx.config .expect_stderr_ok( - &["rustc", "--version"], + &["rustup", "toolchain", "install"], "warn: Force-skipping unavailable component 'rust-bongo", ) .await; @@ -2263,6 +2237,9 @@ channel = "nightly" "#, ) .unwrap(); + cx.config + .expect_ok(&["rustup", "toolchain", "install"]) + .await; cx.config .expect_not_stdout_ok( &["rustup", "component", "list"], @@ -2789,7 +2766,7 @@ async fn dont_warn_on_partial_build() { /// Checks that `rust-toolchain.toml` files are considered #[tokio::test] async fn rust_toolchain_toml() { - let cx = CliTestContext::new(Scenario::SimpleV2).await; + let mut cx = CliTestContext::new(Scenario::SimpleV2).await; cx.config .expect_err( &["rustc", "--version"], @@ -2800,7 +2777,9 @@ async fn rust_toolchain_toml() { let cwd = cx.config.current_dir(); let toolchain_file = cwd.join("rust-toolchain.toml"); raw::write_file(&toolchain_file, "[toolchain]\nchannel = \"nightly\"").unwrap(); - + cx.config + .expect_ok(&["rustup", "toolchain", "install"]) + .await; cx.config .expect_stdout_ok(&["rustc", "--version"], "hash-nightly-2") .await; @@ -2831,7 +2810,7 @@ async fn warn_on_duplicate_rust_toolchain_file() { cx.config .expect_stderr_ok( - &["rustc", "--version"], + &["rustup", "toolchain", "install"], &format!( "warn: both `{0}` and `{1}` exist. Using `{0}`", toolchain_file_1.canonicalize().unwrap().display(), diff --git a/tests/suite/cli_v1.rs b/tests/suite/cli_v1.rs index 78eb492545..4806754221 100644 --- a/tests/suite/cli_v1.rs +++ b/tests/suite/cli_v1.rs @@ -169,18 +169,6 @@ async fn remove_toolchain() { .await; } -#[tokio::test] -async fn remove_default_toolchain_autoinstalls() { - let mut cx = CliTestContext::new(Scenario::SimpleV1).await; - cx.config.expect_ok(&["rustup", "default", "nightly"]).await; - cx.config - .expect_ok(&["rustup", "toolchain", "remove", "nightly"]) - .await; - cx.config - .expect_stderr_ok(&["rustc", "--version"], "info: installing component") - .await; -} - #[tokio::test] async fn remove_override_toolchain_err_handling() { let mut cx = CliTestContext::new(Scenario::SimpleV1).await; @@ -194,7 +182,15 @@ async fn remove_override_toolchain_err_handling() { .expect_ok(&["rustup", "toolchain", "remove", "beta"]) .await; cx.config - .expect_stderr_ok(&["rustc", "--version"], "info: installing component") + .expect_err_ex( + &["rustc", "--version"], + "", + for_host!( + r"error: toolchain 'beta-{0}' is not installed +help: run `rustup toolchain install beta-{0}` to install it +" + ), + ) .await; } diff --git a/tests/suite/cli_v2.rs b/tests/suite/cli_v2.rs index 63c50b3348..995094d298 100644 --- a/tests/suite/cli_v2.rs +++ b/tests/suite/cli_v2.rs @@ -311,18 +311,6 @@ async fn add_remove_multiple_toolchains() { } } -#[tokio::test] -async fn remove_default_toolchain_autoinstalls() { - let mut cx = CliTestContext::new(Scenario::SimpleV2).await; - cx.config.expect_ok(&["rustup", "default", "nightly"]).await; - cx.config - .expect_ok(&["rustup", "toolchain", "remove", "nightly"]) - .await; - cx.config - .expect_stderr_ok(&["rustc", "--version"], "info: installing component") - .await; -} - #[tokio::test] async fn remove_override_toolchain_err_handling() { let mut cx = CliTestContext::new(Scenario::SimpleV2).await; @@ -336,7 +324,15 @@ async fn remove_override_toolchain_err_handling() { .expect_ok(&["rustup", "toolchain", "remove", "beta"]) .await; cx.config - .expect_stderr_ok(&["rustc", "--version"], "info: installing component") + .expect_err_ex( + &["rustc", "--version"], + "", + for_host!( + r"error: toolchain 'beta-{0}' is not installed +help: run `rustup toolchain install beta-{0}` to install it +" + ), + ) .await; } @@ -347,7 +343,10 @@ async fn file_override_toolchain_err_handling() { let toolchain_file = cwd.join("rust-toolchain"); rustup::utils::raw::write_file(&toolchain_file, "beta").unwrap(); cx.config - .expect_stderr_ok(&["rustc", "--version"], "info: installing component") + .expect_err( + &["rustc", "--version"], + for_host!("toolchain 'beta-{0}' is not installed"), + ) .await; } @@ -423,12 +422,6 @@ async fn bad_manifest() { &format!("error: could not parse manifest file: '{}'", path.display()), ) .await; - cx.config - .expect_err( - &["cargo", "--help"], - &format!("error: could not parse manifest file: '{}'", path.display()), - ) - .await; } #[tokio::test]