diff --git a/src/dist/download.rs b/src/dist/download.rs index a662483ac6..74c5aa3249 100644 --- a/src/dist/download.rs +++ b/src/dist/download.rs @@ -285,21 +285,26 @@ impl<'a> DownloadCfg<'a> { Ok(Some((file, partial_hash))) } - pub(crate) fn status_for(&self, component: impl Into>) -> DownloadStatus { + pub(crate) fn status_for( + &self, + component_name: impl Into>, + name_width: usize, + ) -> DownloadStatus { let progress = ProgressBar::hidden(); progress.set_style( - ProgressStyle::with_template( - "{msg:>13.bold} downloading [{bar:15}] {total_bytes:>11} ({bytes_per_sec}, ETA: {eta})", + DownloadStatus::progress_style( + name_width, + "downloading [{bar:15}] {total_bytes:>11} ({bytes_per_sec}, ETA: {eta})", ) - .unwrap() .progress_chars("## "), ); - progress.set_message(component); + progress.set_message(component_name); self.tracker.multi_progress_bars.add(progress.clone()); DownloadStatus { progress, retry_time: Mutex::new(None), + name_width, } } @@ -343,6 +348,8 @@ pub(crate) struct DownloadStatus { /// bar would reappear immediately, not allowing the user to correctly see the message, /// before the progress bar starts again. retry_time: Mutex>, + /// The dynamic maximum width of the component names for alignment + name_width: usize, } impl DownloadStatus { @@ -360,43 +367,45 @@ impl DownloadStatus { *retry_time = None; self.progress.set_style( - ProgressStyle::with_template( - "{msg:>13.bold} downloading [{bar:15}] {total_bytes:>11} ({bytes_per_sec}, ETA: {eta})", + DownloadStatus::progress_style( + self.name_width, + "downloading [{bar:15}] {total_bytes:>11} ({bytes_per_sec}, ETA: {eta})", ) - .unwrap() .progress_chars("## "), ); } pub(crate) fn finished(&self) { - self.progress.set_style( - ProgressStyle::with_template("{msg:>13.bold} pending installation {total_bytes:>20}") - .unwrap(), - ); + self.progress.set_style(DownloadStatus::progress_style( + self.name_width, + "pending installation {total_bytes:>20}", + )); self.progress.tick(); // A tick is needed for the new style to appear, as it is static. } pub(crate) fn failed(&self) { - self.progress.set_style( - ProgressStyle::with_template("{msg:>13.bold} download failed after {elapsed}").unwrap(), - ); + self.progress.set_style(DownloadStatus::progress_style( + self.name_width, + "download failed after {elapsed}", + )); self.progress.finish(); } pub(crate) fn retrying(&self) { *self.retry_time.lock().unwrap() = Some(Instant::now()); - self.progress.set_style( - ProgressStyle::with_template("{msg:>13.bold} retrying download...").unwrap(), - ); + self.progress.set_style(DownloadStatus::progress_style( + self.name_width, + "retrying download...", + )); } pub(crate) fn unpack(&self, inner: T) -> ProgressBarIter { self.progress.reset(); self.progress.set_style( - ProgressStyle::with_template( - "{msg:>13.bold} unpacking [{bar:15}] {total_bytes:>11} ({bytes_per_sec}, ETA: {eta})", + DownloadStatus::progress_style( + self.name_width, + "unpacking [{bar:15}] {total_bytes:>11} ({bytes_per_sec}, ETA: {eta})", ) - .unwrap() .progress_chars("## "), ); self.progress.wrap_read(inner) @@ -404,21 +413,27 @@ impl DownloadStatus { pub(crate) fn installing(&self) { self.progress.set_style( - ProgressStyle::with_template( - "{msg:>13.bold} installing {spinner:.green} {total_bytes:>28}", + DownloadStatus::progress_style( + self.name_width, + "installing {spinner:.green} {total_bytes:>28}", ) - .unwrap() .tick_chars(r"|/-\ "), ); self.progress.enable_steady_tick(Duration::from_millis(100)); } pub(crate) fn installed(&self) { - self.progress.set_style( - ProgressStyle::with_template("{msg:>13.bold} installed {total_bytes:>31}").unwrap(), - ); + self.progress.set_style(DownloadStatus::progress_style( + self.name_width, + "installed {total_bytes:>31}", + )); self.progress.finish(); } + + fn progress_style(name_width: usize, suffix: &str) -> ProgressStyle { + let template = format!("{{msg:>{name_width}.bold}} {suffix}"); + ProgressStyle::with_template(&template).unwrap() + } } fn file_hash(path: &Path) -> Result { diff --git a/src/dist/manifestation.rs b/src/dist/manifestation.rs index 4b97074efb..c620b0184b 100644 --- a/src/dist/manifestation.rs +++ b/src/dist/manifestation.rs @@ -161,11 +161,24 @@ impl Manifestation { } } + const DEFAULT_MIN_NAME_WIDTH: usize = 13; + let max_name_width = update + .components_to_install + .iter() + // The same as the component name's length used in `ComponentBinary::new` + // As it's used for status output + .map(|component| new_manifest.short_name(component).len()) + .max() + .unwrap_or(0) + .max(DEFAULT_MIN_NAME_WIDTH); + // Download component packages and validate hashes let components = update .components_to_install .into_iter() - .filter_map(|component| ComponentBinary::new(component, &new_manifest, download_cfg)) + .filter_map(|component| { + ComponentBinary::new(component, &new_manifest, download_cfg, max_name_width) + }) .collect::>>()?; const DEFAULT_CONCURRENT_DOWNLOADS: usize = 2; @@ -416,7 +429,8 @@ impl Manifestation { .unwrap() .replace(DEFAULT_DIST_SERVER, dl_cfg.tmp_cx.dist_server.as_str()); - let status = dl_cfg.status_for("rust"); + let component_name = "rust"; + let status = dl_cfg.status_for(component_name, component_name.len()); let dl = dl_cfg .download_and_check(&url, Some(update_hash), Some(&status), ".tar.gz") .await?; @@ -752,6 +766,7 @@ impl<'a> ComponentBinary<'a> { component: Component, manifest: &'a Manifest, download_cfg: &'a DownloadCfg<'a>, + name_width: usize, ) -> Option> { Some(Ok(ComponentBinary { binary: match manifest.binary(&component) { @@ -759,7 +774,7 @@ impl<'a> ComponentBinary<'a> { Ok(None) => return None, Err(e) => return Some(Err(e)), }, - status: download_cfg.status_for(manifest.short_name(&component).to_owned()), + status: download_cfg.status_for(manifest.short_name(&component).to_owned(), name_width), component, manifest, download_cfg,