pull,package_info,ui,cli: report the pull flow via BuildView
Retire the ProgressCallback option-of-closure, the one pre-port reporting idiom left in the tree: pull and package_info::lookup now take &dyn BuildView like every other core flow, and the announcements map onto message (unsized work), progress (item counts: series probes, git objects, extraction) and progress again for byte downloads, which the old callback carried in the same 4-argument shape. The terminal side swaps the (ProgressBar, closure) pair for PullView, a BuildView implementation owning one bar of the shared MultiProgress with the same spinner/transfer style switching; it releases the line on drop, which the CLI triggers explicitly on both outcomes since exit(1) skips destructors. Headless callers (tests, internal lookups) pass &report::Quiet. git clone sideband parsing is skipped entirely when the view is not enabled, matching the old None-callback shortcut.
This commit is contained in:
@@ -51,34 +51,56 @@ pub fn wait_spinner(msg: &str) -> ProgressBar {
|
||||
pb
|
||||
}
|
||||
|
||||
/// Create a spinner-style progress bar attached to `multi`, returning the bar
|
||||
/// and a callback compatible with [`crate::ProgressCallback`]
|
||||
pub fn create_progress_bar(
|
||||
multi: &MultiProgress,
|
||||
) -> (ProgressBar, impl Fn(&str, &str, usize, usize) + '_) {
|
||||
let pb = multi.add(ProgressBar::new(0));
|
||||
pb.enable_steady_tick(Duration::from_millis(50));
|
||||
pb.set_style(spinner_style());
|
||||
/// Terminal build view for the pull flow: one bar line attached to the
|
||||
/// shared [`MultiProgress`], spinner-style while the work is unsized,
|
||||
/// transfer-style once a byte or item total is known. The bar is created
|
||||
/// eagerly (an empty spinner, so the line exists from the first moment)
|
||||
/// and released on drop.
|
||||
pub struct PullView {
|
||||
multi: MultiProgress,
|
||||
pb: ProgressBar,
|
||||
}
|
||||
|
||||
let pb_clone = pb.clone();
|
||||
let callback = move |prefix: &str, msg: &str, progress: usize, total: usize| {
|
||||
let pb = &pb_clone;
|
||||
if progress != 0 && total != 0 {
|
||||
pb.set_style(transfer_style());
|
||||
impl PullView {
|
||||
/// Attach a pull view to `multi`
|
||||
pub fn new(multi: &MultiProgress) -> Self {
|
||||
let pb = multi.add(ProgressBar::new(0));
|
||||
pb.enable_steady_tick(Duration::from_millis(50));
|
||||
pb.set_style(spinner_style());
|
||||
Self {
|
||||
multi: multi.clone(),
|
||||
pb,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for PullView {
|
||||
fn drop(&mut self) {
|
||||
self.pb.finish_and_clear();
|
||||
self.multi.remove(&self.pb);
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::report::BuildView for PullView {
|
||||
fn message(&self, text: &str) {
|
||||
self.pb.set_style(spinner_style());
|
||||
self.pb.set_message(text.to_string());
|
||||
}
|
||||
|
||||
fn progress(&self, label: &str, pos: usize, total: usize) {
|
||||
if pos != 0 && total != 0 {
|
||||
self.pb.set_style(transfer_style());
|
||||
} else {
|
||||
pb.set_style(spinner_style());
|
||||
self.pb.set_style(spinner_style());
|
||||
}
|
||||
self.pb.set_message(label.to_string());
|
||||
self.pb.set_length(total as u64);
|
||||
self.pb.set_position(pos as u64);
|
||||
}
|
||||
|
||||
if !prefix.is_empty() {
|
||||
pb.set_prefix(prefix.to_string());
|
||||
}
|
||||
|
||||
pb.set_message(msg.to_string());
|
||||
pb.set_length(total as u64);
|
||||
pb.set_position(progress as u64);
|
||||
};
|
||||
|
||||
(pb, callback)
|
||||
fn is_enabled(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
/// Label of the interactive series selector, rendered by [`prompt::select`]
|
||||
|
||||
Reference in New Issue
Block a user