prune,ui: show the removal pass, prefix the sizing spinner
Confirming a 500 GiB prune went silent under "Removing:" for minutes: drive an indicatif bar from the plan's sizes through a new apply_with_progress observer, in the deb live view's layout — the running count behind the spinner on the first line, the byte bar with its counters on the second. The removed path is not rendered: it fights the bar on a narrow terminal, and the failed-removal errors name the paths that matter. --force plans no sizes and gets the count line only. The dry-run size spinner lacked the "> " prompt prefix the other one-line waits carry; wait_spinner renders it too now.
This commit is contained in:
@@ -7,6 +7,7 @@ pub mod deb;
|
||||
/// yes/no confirmation
|
||||
pub mod prompt;
|
||||
|
||||
use crossterm::terminal;
|
||||
#[cfg(test)]
|
||||
use indicatif::ProgressDrawTarget;
|
||||
use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
|
||||
@@ -41,16 +42,59 @@ pub(crate) fn transfer_style() -> ProgressStyle {
|
||||
}
|
||||
|
||||
/// A standalone spinner for one-line waits outside a build view (the
|
||||
/// prune size pass): braille frames over the message, drawn only on
|
||||
/// terminals. Callers finish it with [`ProgressBar::finish_and_clear`].
|
||||
/// prune size pass): braille frames over the message behind the `> `
|
||||
/// prompt prefix, drawn only on terminals. Callers finish it with
|
||||
/// [`ProgressBar::finish_and_clear`].
|
||||
pub fn wait_spinner(msg: &str) -> ProgressBar {
|
||||
let pb = ProgressBar::new_spinner();
|
||||
pb.set_style(ProgressStyle::with_template("{spinner:.blue} {msg}").expect("spinner template"));
|
||||
pb.set_style(
|
||||
ProgressStyle::with_template("> {spinner:.blue} {msg}").expect("spinner template"),
|
||||
);
|
||||
pb.set_message(msg.to_string());
|
||||
pb.enable_steady_tick(Duration::from_millis(120));
|
||||
pb
|
||||
}
|
||||
|
||||
/// Width of the terminal in columns, or `None` when it cannot be determined
|
||||
pub(crate) fn terminal_width() -> Option<usize> {
|
||||
terminal::size().ok().map(|(cols, _)| cols as usize)
|
||||
}
|
||||
|
||||
/// Removal progress bar of `pkh prune`, in the deb live view's layout:
|
||||
/// the running count behind the spinner on the first line, the byte bar
|
||||
/// with its counters on the second when the plan carries sizes (`--force`
|
||||
/// skips the sizing and gets the count line only). The removed path is
|
||||
/// deliberately not rendered — it fights the bar on a narrow terminal,
|
||||
/// and the failed-removal errors name the paths that matter. Drive it
|
||||
/// with [`removal_progress`]; finish it with
|
||||
/// [`ProgressBar::finish_and_clear`].
|
||||
pub fn removal_bar(multi: &MultiProgress, total_bytes: u64) -> ProgressBar {
|
||||
let pb = multi.add(ProgressBar::new(total_bytes));
|
||||
let template = if total_bytes > 0 {
|
||||
"> {spinner:.blue} {prefix}\n [{bar:24.cyan/blue}] {bytes}/{total_bytes}"
|
||||
} else {
|
||||
"> {spinner:.blue} {prefix}"
|
||||
};
|
||||
pb.set_style(
|
||||
ProgressStyle::with_template(template)
|
||||
.expect("removal template")
|
||||
.progress_chars("=> "),
|
||||
);
|
||||
pb.enable_steady_tick(Duration::from_millis(120));
|
||||
pb
|
||||
}
|
||||
|
||||
/// Advance the removal bar to the `idx`-th of `count` artifact;
|
||||
/// `done` bytes already freed
|
||||
pub fn removal_progress(bar: &ProgressBar, idx: usize, count: usize, done: u64) {
|
||||
bar.set_prefix(format!("Removing {}/{}", idx + 1, count));
|
||||
if let Some(total) = bar.length()
|
||||
&& total > 0
|
||||
{
|
||||
bar.set_position(done.min(total));
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a spinner-style progress bar attached to `multi`, returning the bar
|
||||
/// and a callback compatible with [`crate::ProgressCallback`]
|
||||
pub fn create_progress_bar(
|
||||
|
||||
Reference in New Issue
Block a user