Skip to content
Open
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
57 changes: 27 additions & 30 deletions src/dist/download.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,11 +285,15 @@ impl<'a> DownloadCfg<'a> {
Ok(Some((file, partial_hash)))
}

pub(crate) fn status_for(&self, component: impl Into<Cow<'static, str>>) -> DownloadStatus {
pub(crate) fn status_for(
&self,
component: impl Into<Cow<'static, str>>,
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})",
&format!("{{msg:>{}.bold}} downloading [{{bar:15}}] {{total_bytes:>11}} ({{bytes_per_sec}}, ETA: {{eta}})", name_width)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I think it's clearer to use the new style format!() both here and in other places, e.g. "{{msg:>{name_width}.bold}} ...

)
.unwrap()
.progress_chars("## "),
Expand All @@ -300,6 +304,7 @@ impl<'a> DownloadCfg<'a> {
DownloadStatus {
progress,
retry_time: Mutex::new(None),
name_width,
}
}

Expand Down Expand Up @@ -343,9 +348,16 @@ 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<Option<Instant>>,
/// The dynamic maximum width of the component names for alignment
name_width: usize,
}

impl DownloadStatus {
fn style(&self, suffix: &str) -> ProgressStyle {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Consider extracting this to a standalone function and to be used above as well, since the only dependency on &self is self.name_width().

You can make this clearer by extracting this function in the first commit which is separate from other changes with a fix named_width = 13, and then add the name_width parameter.

let template = format!("{{msg:>{}.bold}} {}", self.name_width, suffix);
ProgressStyle::with_template(&template).unwrap()
}

pub(crate) fn received_length(&self, len: u64) {
self.progress.reset();
self.progress.set_length(len);
Expand All @@ -360,63 +372,48 @@ 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})",
)
.unwrap()
.progress_chars("## "),
self.style("downloading [{bar:15}] {total_bytes:>11} ({bytes_per_sec}, ETA: {eta})")
.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(self.style("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(self.style("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(self.style("retrying download..."));
}

pub(crate) fn unpack<T: Read>(&self, inner: T) -> ProgressBarIter<T> {
self.progress.reset();
self.progress.set_style(
ProgressStyle::with_template(
"{msg:>13.bold} unpacking [{bar:15}] {total_bytes:>11} ({bytes_per_sec}, ETA: {eta})",
)
.unwrap()
.progress_chars("## "),
self.style("unpacking [{bar:15}] {total_bytes:>11} ({bytes_per_sec}, ETA: {eta})")
.progress_chars("## "),
);
self.progress.wrap_read(inner)
}

pub(crate) fn installing(&self) {
self.progress.set_style(
ProgressStyle::with_template(
"{msg:>13.bold} installing {spinner:.green} {total_bytes:>28}",
)
.unwrap()
.tick_chars(r"|/-\ "),
self.style("installing {spinner:.green} {total_bytes:>28}")
.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(self.style("installed {total_bytes:>31}"));
self.progress.finish();
}
}
Expand Down
18 changes: 15 additions & 3 deletions src/dist/manifestation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,22 @@ impl Manifestation {
}
}

const DEFAULT_MIN_NAME_WIDTH: usize = 15;
let max_name_width = update
.components_to_install
.iter()
.map(|component| new_manifest.short_name(component).len())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: This implementation implicitly relied on the fact that .short_name() will be used in ComponentBinary for the component name.

Suggest extracting a function ComponentBinary::(component: Component, manifest: &'a Manifest) and use that on both sides instead.

.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::<Result<Vec<_>>>()?;

const DEFAULT_CONCURRENT_DOWNLOADS: usize = 2;
Expand Down Expand Up @@ -408,7 +419,7 @@ impl Manifestation {
.unwrap()
.replace(DEFAULT_DIST_SERVER, dl_cfg.tmp_cx.dist_server.as_str());

let status = dl_cfg.status_for("rust");
let status = dl_cfg.status_for("rust", 15);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think given the fact that the only component name is "rust" in v1, we'd just do:

let component = "rust"; let status = dl_cfg.status_for(component, component.len());

let dl = dl_cfg
.download_and_check(&url, Some(update_hash), Some(&status), ".tar.gz")
.await?;
Expand Down Expand Up @@ -741,14 +752,15 @@ impl<'a> ComponentBinary<'a> {
component: Component,
manifest: &'a Manifest,
download_cfg: &'a DownloadCfg<'a>,
name_width: usize,
) -> Option<Result<Self>> {
Some(Ok(ComponentBinary {
binary: match manifest.binary(&component) {
Ok(Some(b)) => b,
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,
Expand Down
Loading