diff --git a/src/cli/common.rs b/src/cli/common.rs index f4ce794e5f..28d5bd857f 100644 --- a/src/cli/common.rs +++ b/src/cli/common.rs @@ -16,9 +16,9 @@ use tracing_subscriber::{EnvFilter, Registry, reload::Handle}; use crate::{ config::Cfg, - dist::{TargetTriple, ToolchainDesc}, + dist::{DistOptions, TargetTriple, ToolchainDesc}, errors::RustupError, - install::UpdateStatus, + install::{InstallMethod, UpdateStatus}, process::Process, toolchain::{LocalToolchainName, Toolchain, ToolchainName}, utils, @@ -215,7 +215,20 @@ pub(crate) async fn update_all_channels( cfg: &Cfg<'_>, force_update: bool, ) -> Result { - let toolchains = cfg.update_all_channels(force_update).await?; + let profile = cfg.get_profile()?; + let mut toolchains = Vec::new(); + for (desc, distributable) in cfg.list_channels()? { + let options = DistOptions::new(&[], &[], &desc, profile, force_update, cfg)? + .for_update(&distributable, false); + let result = InstallMethod::Dist(options).install().await; + + if let Err(e) = &result { + error!("{e}"); + } + + toolchains.push((desc, result)); + } + let has_update_error = toolchains.iter().any(|(_, r)| r.is_err()); let exit_code = utils::ExitCode(if has_update_error { 1 } else { 0 }); diff --git a/src/cli/rustup_mode.rs b/src/cli/rustup_mode.rs index fd2c4906c9..48e865eb78 100644 --- a/src/cli/rustup_mode.rs +++ b/src/cli/rustup_mode.rs @@ -41,7 +41,7 @@ use crate::{ command, component_for_bin, config::{ActiveSource, Cfg}, dist::{ - AutoInstallMode, PartialToolchainDesc, Profile, TargetTriple, + AutoInstallMode, DistOptions, PartialToolchainDesc, Profile, TargetTriple, download::DownloadCfg, manifest::{Component, ComponentStatus}, }, @@ -960,26 +960,23 @@ async fn update( let components = opts.component.iter().map(|s| &**s).collect::>(); let targets = opts.target.iter().map(|s| &**s).collect::>(); + let dist_opts = DistOptions::new( + &components, + &targets, + &desc, + cfg.get_profile()?, + opts.force, + cfg, + )?; - let force = opts.force; - let allow_downgrade = opts.allow_downgrade; - let profile = cfg.get_profile()?; let status = match DistributableToolchain::new(cfg, desc.clone()) { - Ok(mut d) => { - d.update_extra(&components, &targets, profile, force, allow_downgrade) + Ok(d) => { + InstallMethod::Dist(dist_opts.for_update(&d, opts.allow_downgrade)) + .install() .await? } Err(RustupError::ToolchainNotInstalled { .. }) => { - DistributableToolchain::install( - cfg, - &desc, - &components, - &targets, - profile, - force, - ) - .await? - .0 + DistributableToolchain::install(dist_opts).await?.0 } Err(e) => Err(e)?, }; @@ -1519,10 +1516,8 @@ async fn override_add( Err(e @ RustupError::ToolchainNotInstalled { .. }) => match &toolchain_name { ToolchainName::Custom(_) => Err(e)?, ToolchainName::Official(desc) => { - let status = - DistributableToolchain::install(cfg, desc, &[], &[], cfg.get_profile()?, false) - .await? - .0; + let options = DistOptions::new(&[], &[], desc, cfg.get_profile()?, false, cfg)?; + let status = DistributableToolchain::install(options).await?.0; writeln!(cfg.process.stdout().lock())?; common::show_channel_update( cfg, diff --git a/src/cli/self_update.rs b/src/cli/self_update.rs index aec46b141c..2e70b187d9 100644 --- a/src/cli/self_update.rs +++ b/src/cli/self_update.rs @@ -59,10 +59,13 @@ use crate::{ markdown::md, }, config::Cfg, - dist::{PartialToolchainDesc, Profile, TargetTriple, ToolchainDesc, download::DownloadCfg}, + dist::{ + DistOptions, PartialToolchainDesc, Profile, TargetTriple, ToolchainDesc, + download::DownloadCfg, + }, download::download_file, errors::RustupError, - install::UpdateStatus, + install::{InstallMethod, UpdateStatus}, process::Process, toolchain::{ DistributableToolchain, MaybeOfficialToolchainName, ResolvableToolchainName, Toolchain, @@ -996,6 +999,7 @@ async fn maybe_install_rust(opts: InstallOpts<'_>, cfg: &mut Cfg<'_>) -> Result< let (components, targets) = (opts.components, opts.targets); let toolchain = opts.install(cfg)?; if let Some(desc) = &toolchain { + let options = DistOptions::new(components, targets, desc, cfg.get_profile()?, true, cfg)?; let status = if Toolchain::exists(cfg, &desc.into())? { warn!("Updating existing toolchain, profile choice will be ignored"); // If we have a partial install we might not be able to read content here. We could: @@ -1003,21 +1007,12 @@ async fn maybe_install_rust(opts: InstallOpts<'_>, cfg: &mut Cfg<'_>) -> Result< // - silently ignore it (and provide inconsistent metadata for reporting the install/update change) // - delete the partial install and start over // For now, we error. - let mut toolchain = DistributableToolchain::new(cfg, desc.clone())?; - toolchain - .update(components, targets, cfg.get_profile()?) + let toolchain = DistributableToolchain::new(cfg, desc.clone())?; + InstallMethod::Dist(options.for_update(&toolchain, false)) + .install() .await? } else { - DistributableToolchain::install( - cfg, - desc, - components, - targets, - cfg.get_profile()?, - true, - ) - .await? - .0 + DistributableToolchain::install(options).await?.0 }; check_proxy_sanity(cfg.process, components, desc)?; diff --git a/src/config.rs b/src/config.rs index 9cf90d2a38..bbba13a075 100644 --- a/src/config.rs +++ b/src/config.rs @@ -6,16 +6,17 @@ use std::str::FromStr; use anyhow::{Context, Result, anyhow, bail}; use serde::Deserialize; use thiserror::Error as ThisError; -use tokio_stream::StreamExt; use tracing::{debug, error, info, trace, warn}; -use crate::dist::AutoInstallMode; use crate::{ cli::{common, self_update::SelfUpdateMode}, - dist::{self, PartialToolchainDesc, Profile, TargetTriple, ToolchainDesc, temp}, + dist::{ + self, AutoInstallMode, DistOptions, PartialToolchainDesc, Profile, TargetTriple, + ToolchainDesc, temp, + }, errors::RustupError, fallback_settings::FallbackSettings, - install::UpdateStatus, + install::{InstallMethod, UpdateStatus}, process::Process, settings::{MetadataVersion, Settings, SettingsFile}, toolchain::{ @@ -788,28 +789,31 @@ impl<'a> Cfg<'a> { } let components: Vec<_> = components.iter().map(AsRef::as_ref).collect(); let targets: Vec<_> = targets.iter().map(AsRef::as_ref).collect(); - let profile = match profile { - Some(profile) => profile, - None => self.get_profile()?, - }; + let mut options = DistOptions::new( + &components, + &targets, + toolchain, + match profile { + Some(p) => p, + None => self.get_profile()?, + }, + false, + self, + )?; + let (status, toolchain) = match DistributableToolchain::new(self, toolchain.clone()) { Err(RustupError::ToolchainNotInstalled { .. }) => { - DistributableToolchain::install( - self, - toolchain, - &components, - &targets, - profile, - false, - ) - .await? + DistributableToolchain::install(options).await? } - Ok(mut distributable) => { + Ok(distributable) => { if verbose { info!("using existing install for {toolchain}"); } let status = if !distributable.components_exist(&components, &targets)? { - distributable.update(&components, &targets, profile).await? + options.force = true; + InstallMethod::Dist(options.for_update(&distributable, false)) + .install() + .await? } else { UpdateStatus::Unchanged }; @@ -893,28 +897,6 @@ impl<'a> Cfg<'a> { }) } - pub(crate) async fn update_all_channels( - &self, - force_update: bool, - ) -> Result)>> { - let channels = self.list_channels()?; - let channels = channels.into_iter(); - let profile = self.get_profile()?; - - // Update toolchains and collect the results - let channels = tokio_stream::iter(channels).then(|(desc, mut distributable)| async move { - let st = distributable - .update_extra(&[], &[], profile, force_update, false) - .await; - if let Err(e) = &st { - error!("{e}"); - } - (desc, st) - }); - - Ok(channels.collect().await) - } - pub(crate) fn set_default_host_triple(&self, host_triple: String) -> Result<()> { // Ensure that the provided host_triple is capable of resolving // against the 'stable' toolchain. This provides early errors @@ -944,7 +926,7 @@ impl<'a> Cfg<'a> { /// The root path of the release server, without the `/dist` suffix. /// By default, it points to [`dist::DEFAULT_DIST_SERVER`]. -pub(crate) fn dist_root_server(process: &Process) -> Result { +fn dist_root_server(process: &Process) -> Result { if let Some(s) = process.var_opt("RUSTUP_DIST_SERVER")? { trace!("`RUSTUP_DIST_SERVER` has been set to `{s}`"); return Ok(s); diff --git a/src/dist/manifestation.rs b/src/dist/manifestation.rs index 85b839bd5c..b99775fe8b 100644 --- a/src/dist/manifestation.rs +++ b/src/dist/manifestation.rs @@ -361,7 +361,7 @@ impl Manifestation { pub(crate) async fn update_v1( &self, new_manifest: &[String], - update_hash: Option<&Path>, + update_hash: &Path, dl_cfg: &DownloadCfg<'_>, ) -> Result> { // If there's already a v2 installation then something has gone wrong @@ -387,7 +387,7 @@ impl Manifestation { let status = dl_cfg.status_for("rust"); let dl = dl_cfg - .download_and_check(&url, update_hash, Some(&status), ".tar.gz") + .download_and_check(&url, Some(update_hash), Some(&status), ".tar.gz") .await?; if dl.is_none() { return Ok(None); diff --git a/src/dist/mod.rs b/src/dist/mod.rs index d9af808a53..7691447f62 100644 --- a/src/dist/mod.rs +++ b/src/dist/mod.rs @@ -1,7 +1,13 @@ //! Installation from a Rust distribution server use std::{ - collections::HashSet, env, fmt, io::Write, ops::Deref, path::Path, str::FromStr, sync::LazyLock, + collections::HashSet, + env, fmt, + io::Write, + ops::Deref, + path::{Path, PathBuf}, + str::FromStr, + sync::LazyLock, }; use anyhow::{Context, Result, anyhow, bail}; @@ -14,10 +20,10 @@ use thiserror::Error as ThisError; use tracing::{debug, info, warn}; use crate::{ - config::{Cfg, dist_root_server}, + config::Cfg, errors::RustupError, process::Process, - toolchain::ToolchainName, + toolchain::{DistributableToolchain, ToolchainName}, utils, }; @@ -876,24 +882,74 @@ impl fmt::Display for Profile { } } -pub(crate) struct DistOptions<'a> { - pub(crate) cfg: &'a Cfg<'a>, - pub(crate) toolchain: &'a ToolchainDesc, - pub(crate) profile: Profile, - pub(crate) update_hash: Option<&'a Path>, - pub(crate) dl_cfg: DownloadCfg<'a>, +pub(crate) struct DistOptions<'cfg, 'a> { + pub(super) cfg: &'cfg Cfg<'cfg>, + pub(super) toolchain: &'a ToolchainDesc, + profile: Profile, + pub(super) update_hash: PathBuf, + dl_cfg: DownloadCfg<'cfg>, /// --force bool is whether to force an update/install - pub(crate) force: bool, + pub(super) force: bool, /// --allow-downgrade - pub(crate) allow_downgrade: bool, + pub(super) allow_downgrade: bool, /// toolchain already exists - pub(crate) exists: bool, + pub(super) exists: bool, /// currently installed date and version - pub(crate) old_date_version: Option<(String, String)>, + pub(super) old_date_version: Option<(String, String)>, /// Extra components to install from dist - pub(crate) components: &'a [&'a str], + components: &'a [&'a str], /// Extra targets to install from dist - pub(crate) targets: &'a [&'a str], + targets: &'a [&'a str], +} + +impl<'cfg, 'a> DistOptions<'cfg, 'a> { + pub(super) fn new( + components: &'a [&'a str], + targets: &'a [&'a str], + toolchain: &'a ToolchainDesc, + profile: Profile, + force: bool, + cfg: &'cfg Cfg<'cfg>, + ) -> Result { + Ok(Self { + cfg, + toolchain, + profile, + update_hash: cfg.get_hash_file(toolchain, true)?, + dl_cfg: DownloadCfg::new(cfg), + force, + allow_downgrade: false, + exists: false, + old_date_version: None, + components, + targets, + }) + } + + pub(super) fn for_update( + mut self, + toolchain: &'a DistributableToolchain<'cfg>, + allow_downgrade: bool, + ) -> Self { + self.allow_downgrade = allow_downgrade; + self.exists = true; + self.old_date_version = + // Ignore a missing manifest: we can't report the old version + // correctly, and it probably indicates an incomplete install, so do + // not report an old rustc version either. + toolchain.get_manifest() + .map(|m| { + ( + m.date, + // should rustc_version be a free function on a trait? + // note that prev_version can be junk if the rustc component is missing ... + toolchain.toolchain.rustc_version(), + ) + }) + .ok(); + + self + } } // Installs or updates a toolchain from a dist server. If an initial @@ -901,21 +957,19 @@ pub(crate) struct DistOptions<'a> { // an upgrade then all the existing components will be upgraded. // // Returns the manifest's hash if anything changed. -#[tracing::instrument(level = "trace", err(level = "trace"), skip_all, fields(profile=format!("{:?}", opts.profile), prefix=prefix.path().to_string_lossy().to_string()))] +#[tracing::instrument(level = "trace", err(level = "trace"), skip_all, fields(profile = ?opts.profile, prefix = %prefix.path().display()))] pub(crate) async fn update_from_dist( prefix: &InstallPrefix, - opts: &DistOptions<'_>, + opts: &DistOptions<'_, '_>, ) -> Result> { let fresh_install = !prefix.path().exists(); - if let Some(hash) = opts.update_hash { - // fresh_install means the toolchain isn't present, but hash_exists means there is a stray hash file - if fresh_install && Path::exists(hash) { - warn!( - "removing stray hash file in order to continue: {}", - hash.display() - ); - std::fs::remove_file(hash)?; - } + // fresh_install means the toolchain isn't present, but hash_exists means there is a stray hash file + if fresh_install && opts.update_hash.exists() { + warn!( + "removing stray hash file in order to continue: {}", + opts.update_hash.display() + ); + std::fs::remove_file(&opts.update_hash)?; } let mut fetched = String::new(); @@ -968,7 +1022,7 @@ pub(crate) async fn update_from_dist( let res = loop { let result = try_update_from_dist_( &opts.dl_cfg, - opts.update_hash, + &opts.update_hash, &toolchain, match opts.exists { false => Some(opts.profile), @@ -979,7 +1033,7 @@ pub(crate) async fn update_from_dist( opts.components, opts.targets, &mut fetched, - &opts.cfg.dist_root_url, + opts.cfg, ) .await; @@ -1068,7 +1122,7 @@ pub(crate) async fn update_from_dist( #[allow(clippy::too_many_arguments)] async fn try_update_from_dist_( download: &DownloadCfg<'_>, - update_hash: Option<&Path>, + update_hash: &Path, toolchain: &ToolchainDesc, profile: Option, prefix: &InstallPrefix, @@ -1076,7 +1130,7 @@ async fn try_update_from_dist_( components: &[&str], targets: &[&str], fetched: &mut String, - dist_root: &str, + cfg: &Cfg<'_>, ) -> Result> { let toolchain_str = toolchain.to_string(); let manifestation = Manifestation::open(prefix.clone(), toolchain.target.clone())?; @@ -1084,17 +1138,17 @@ async fn try_update_from_dist_( // TODO: Add a notification about which manifest version is going to be used info!("syncing channel updates for {toolchain_str}"); match dl_v2_manifest( - dist_root, download, // Even if manifest has not changed, we must continue to install requested components. // So if components or targets is not empty, we skip passing `update_hash` so that // we essentially degenerate to `rustup component add` / `rustup target add` if components.is_empty() && targets.is_empty() { - update_hash + Some(update_hash) } else { None }, toolchain, + cfg, ) .await { @@ -1192,7 +1246,7 @@ async fn try_update_from_dist_( } // If the v2 manifest is not found then try v1 - let manifest = match dl_v1_manifest(dist_root, download, toolchain).await { + let manifest = match dl_v1_manifest(&cfg.dist_root_url, download, toolchain).await { Ok(m) => m, Err(err) => match err.downcast_ref::() { Some(RustupError::ChecksumFailed { .. }) => return Err(err), @@ -1229,12 +1283,12 @@ async fn try_update_from_dist_( } pub(crate) async fn dl_v2_manifest( - dist_root: &str, download: &DownloadCfg<'_>, update_hash: Option<&Path>, toolchain: &ToolchainDesc, + cfg: &Cfg<'_>, ) -> Result> { - let manifest_url = toolchain.manifest_v2_url(dist_root, download.process); + let manifest_url = toolchain.manifest_v2_url(&cfg.dist_root_url, download.process); match download .download_and_check(&manifest_url, update_hash, None, ".toml") .await @@ -1260,15 +1314,15 @@ pub(crate) async fn dl_v2_manifest( // Manifest checksum mismatched. warn!("{err}"); - let server = dist_root_server(download.process)?; - if server == DEFAULT_DIST_SERVER { + if cfg.dist_root_url.starts_with(DEFAULT_DIST_SERVER) { info!( "this is likely due to an ongoing update of the official release server, please try again later" ); info!("see for more details"); } else { info!( - "this might indicate an issue with the third-party release server '{server}'" + "this might indicate an issue with the third-party release server '{}'", + cfg.dist_root_url ); info!("see for more details"); } diff --git a/src/install.rs b/src/install.rs index f1650778d0..a7147e76f1 100644 --- a/src/install.rs +++ b/src/install.rs @@ -20,30 +20,30 @@ pub(crate) enum UpdateStatus { Unchanged, } -pub(crate) enum InstallMethod<'a> { +pub(crate) enum InstallMethod<'cfg, 'a> { Copy { src: &'a Path, dest: &'a CustomToolchainName, - cfg: &'a Cfg<'a>, + cfg: &'cfg Cfg<'cfg>, }, Link { src: &'a Path, dest: &'a CustomToolchainName, - cfg: &'a Cfg<'a>, + cfg: &'cfg Cfg<'cfg>, }, - Dist(DistOptions<'a>), + Dist(DistOptions<'cfg, 'a>), } -impl InstallMethod<'_> { +impl InstallMethod<'_, '_> { // Install a toolchain #[tracing::instrument(level = "trace", err(level = "trace"), skip_all)] - pub(crate) async fn install(&self) -> Result { + pub(crate) async fn install(self) -> Result { // Initialize rayon for use by the remove_dir_all crate limiting the number of threads. // This will error if rayon is already initialized but it's fine to ignore that. let _ = rayon::ThreadPoolBuilder::new() .num_threads(self.cfg().process.io_thread_count()?) .build_global(); - match self { + match &self { InstallMethod::Copy { .. } | InstallMethod::Link { .. } | InstallMethod::Dist(DistOptions { @@ -63,7 +63,7 @@ impl InstallMethod<'_> { } true => { debug!("toolchain {} installed", self.dest_basename()); - match self { + match &self { InstallMethod::Dist(DistOptions { old_date_version: Some((_, v)), .. @@ -107,10 +107,7 @@ impl InstallMethod<'_> { let maybe_new_hash = dist::update_from_dist(prefix, opts).await?; if let Some(hash) = maybe_new_hash { - if let Some(hash_file) = opts.update_hash { - utils::write_file("update hash", hash_file, &hash)?; - } - + utils::write_file("update hash", &opts.update_hash, &hash)?; Ok(true) } else { Ok(false) diff --git a/src/toolchain.rs b/src/toolchain.rs index 827d6152b2..f13ef0aaf3 100644 --- a/src/toolchain.rs +++ b/src/toolchain.rs @@ -23,7 +23,7 @@ use crate::{ RustupError, config::{ActiveSource, Cfg, InstalledPath}, dist::{ - PartialToolchainDesc, TargetTriple, + DistOptions, PartialToolchainDesc, TargetTriple, component::{Component, Components}, prefix::InstallPrefix, }, @@ -61,12 +61,8 @@ impl<'a> Toolchain<'a> { name: ToolchainName::Official(desc), .. }) if install_if_missing => { - Ok( - DistributableToolchain::install(cfg, &desc, &[], &[], cfg.get_profile()?, true) - .await? - .1 - .toolchain, - ) + let options = DistOptions::new(&[], &[], &desc, cfg.get_profile()?, true, cfg)?; + Ok(DistributableToolchain::install(options).await?.1.toolchain) } Err(e) => Err(e.into()), } diff --git a/src/toolchain/distributable.rs b/src/toolchain/distributable.rs index 6bee499390..93c6d3bed0 100644 --- a/src/toolchain/distributable.rs +++ b/src/toolchain/distributable.rs @@ -1,6 +1,6 @@ #[cfg(windows)] use std::fs; -use std::{convert::Infallible, env::consts::EXE_SUFFIX, ffi::OsStr, path::Path, process::Command}; +use std::{convert::Infallible, env::consts::EXE_SUFFIX, ffi::OsStr, process::Command}; #[cfg(windows)] use anyhow::Context; @@ -11,7 +11,7 @@ use crate::{ RustupError, component_for_bin, config::{ActiveSource, Cfg}, dist::{ - DistOptions, PartialToolchainDesc, Profile, ToolchainDesc, + DistOptions, PartialToolchainDesc, ToolchainDesc, config::Config, download::DownloadCfg, manifest::{Component, ComponentStatus, Manifest}, @@ -29,11 +29,20 @@ use super::{ /// An official toolchain installed on the local disk #[derive(Debug)] pub(crate) struct DistributableToolchain<'a> { - pub(super) toolchain: Toolchain<'a>, + pub(crate) toolchain: Toolchain<'a>, desc: ToolchainDesc, } impl<'a> DistributableToolchain<'a> { + #[tracing::instrument(level = "trace", err(level = "trace"), skip_all)] + pub(crate) async fn install( + options: DistOptions<'a, '_>, + ) -> anyhow::Result<(UpdateStatus, Self)> { + let (cfg, toolchain) = (options.cfg, options.toolchain); + let status = InstallMethod::Dist(options).install().await?; + Ok((status, Self::new(cfg, toolchain.clone())?)) + } + pub(crate) async fn from_partial( toolchain: Option<(PartialToolchainDesc, ActiveSource)>, cfg: &'a Cfg<'a>, @@ -336,93 +345,6 @@ impl<'a> DistributableToolchain<'a> { InstallPrefix::from(self.toolchain.path().to_owned()).guess_v1_manifest() } - #[tracing::instrument(level = "trace", err(level = "trace"), skip_all)] - pub(crate) async fn install( - cfg: &'a Cfg<'a>, - toolchain: &ToolchainDesc, - components: &[&str], - targets: &[&str], - profile: Profile, - force: bool, - ) -> anyhow::Result<(UpdateStatus, DistributableToolchain<'a>)> { - let hash_path = cfg.get_hash_file(toolchain, true)?; - let update_hash = Some(&hash_path as &Path); - - let status = InstallMethod::Dist(DistOptions { - cfg, - toolchain, - profile, - update_hash, - dl_cfg: DownloadCfg::new(cfg), - force, - allow_downgrade: false, - exists: false, - old_date_version: None, - components, - targets, - }) - .install() - .await?; - Ok((status, Self::new(cfg, toolchain.clone())?)) - } - - #[tracing::instrument(level = "trace", err(level = "trace"), skip_all)] - pub(crate) async fn update( - &mut self, - components: &[&str], - targets: &[&str], - profile: Profile, - ) -> anyhow::Result { - self.update_extra(components, targets, profile, true, false) - .await - } - - /// Update a toolchain with control over the channel behaviour - #[tracing::instrument(level = "trace", err(level = "trace"), skip_all)] - pub(crate) async fn update_extra( - &mut self, - components: &[&str], - targets: &[&str], - profile: Profile, - force: bool, - allow_downgrade: bool, - ) -> anyhow::Result { - let old_date_version = - // Ignore a missing manifest: we can't report the old version - // correctly, and it probably indicates an incomplete install, so do - // not report an old rustc version either. - self.get_manifest() - .map(|m| { - ( - m.date, - // should rustc_version be a free function on a trait? - // note that prev_version can be junk if the rustc component is missing ... - self.toolchain.rustc_version(), - ) - }) - .ok(); - - let cfg = self.toolchain.cfg; - let hash_path = cfg.get_hash_file(&self.desc, true)?; - let update_hash = Some(&hash_path as &Path); - - InstallMethod::Dist(DistOptions { - cfg, - toolchain: &self.desc, - profile, - update_hash, - dl_cfg: DownloadCfg::new(cfg), - force, - allow_downgrade, - exists: true, - old_date_version, - components, - targets, - }) - .install() - .await - } - pub fn recursion_error(&self, binary_lossy: String) -> Result { let prefix = InstallPrefix::from(self.toolchain.path()); let manifestation = Manifestation::open(prefix, self.desc.target.clone())?; @@ -523,12 +445,13 @@ impl<'a> DistributableToolchain<'a> { } pub async fn show_dist_version(&self) -> anyhow::Result> { - let dist_root = &self.toolchain.cfg.dist_root_url; - let update_hash = self.toolchain.cfg.get_hash_file(&self.desc, false)?; - let download_cfg = DownloadCfg::new(self.toolchain.cfg); - - match crate::dist::dl_v2_manifest(dist_root, &download_cfg, Some(&update_hash), &self.desc) - .await? + match crate::dist::dl_v2_manifest( + &DownloadCfg::new(self.toolchain.cfg), + Some(&self.toolchain.cfg.get_hash_file(&self.desc, false)?), + &self.desc, + self.toolchain.cfg, + ) + .await? { Some((manifest, _)) => Ok(Some(manifest.get_rust_version()?.to_string())), None => Ok(None),