diff --git a/doc/src/developers/style.md b/doc/src/developers/style.md index 996429b..b0bb84a 100644 --- a/doc/src/developers/style.md +++ b/doc/src/developers/style.md @@ -5,5 +5,3 @@ **Row's** [pre-commit](https://pre-commit.com/) configuration applies style fixes with `rustfmt` checks for common errors with `clippy`. - -TODO: Investigate clippy configuration and see if more stringent rules can be applied. diff --git a/src/cli/submit.rs b/src/cli/submit.rs index 3e33aed..6f5d0a4 100644 --- a/src/cli/submit.rs +++ b/src/cli/submit.rs @@ -175,7 +175,7 @@ pub fn submit( if std::io::stdout().is_terminal() && !args.yes { let mut input = String::new(); - multi_progress.multi_progress.suspend(|| { + multi_progress.suspend(|| { print!("Proceed? [Y/n]: "); io::stdout().flush().expect("Can flush stdout"); io::stdin() @@ -199,8 +199,7 @@ pub fn submit( // stdin and stdout directly. project.close(multi_progress)?; - multi_progress.progress_bars.clear(); - multi_progress.multi_progress.clear().unwrap(); + multi_progress.clear().unwrap(); // Install the Ctrl-C signal handler to gracefully kill spawned processes // and save the pending scheduled job cache before exiting. Allow the user diff --git a/src/lib.rs b/src/lib.rs index 5bcaba7..6bacf0e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,7 +16,7 @@ pub mod state; pub mod workflow; pub mod workspace; -use indicatif::{MultiProgress, ProgressBar}; +use indicatif::{MultiProgress, ProgressBar, ProgressDrawTarget}; use serde_json::{self, Value}; use std::io; use std::path::PathBuf; @@ -36,8 +36,8 @@ const SUBMITTED_CACHE_FILE_NAME: &str = "submitted.postcard"; /// removed from [MultiProgress](https://github.com/console-rs/indicatif/issues/614) /// pub struct MultiProgressContainer { - pub progress_bars: Vec, - pub multi_progress: MultiProgress, + progress_bars: Vec, + multi_progress: MultiProgress, } /// Errors that may be encountered when using the row crate. @@ -186,3 +186,45 @@ pub enum Error { // #[error("Evalexpr error: {0}")] // Evalexpr(#[from] EvalexprError), } + +impl MultiProgressContainer { + /// Create a new multi-progress container. + pub fn new(multi_progress: MultiProgress) -> MultiProgressContainer { + MultiProgressContainer { + progress_bars: Vec::new(), + multi_progress, + } + } + + /// Add a progress bar to the container or hide it. + pub fn add_or_hide(&mut self, mut progress_bar: ProgressBar, hide: bool) -> ProgressBar { + if hide { + progress_bar.set_draw_target(ProgressDrawTarget::hidden()); + } else { + progress_bar = self.multi_progress.add(progress_bar); + self.progress_bars.push(progress_bar.clone()); + } + + progress_bar + } + + /// Add a progress bar to the container. + pub fn add(&mut self, progress_bar: ProgressBar) -> ProgressBar { + self.progress_bars.push(progress_bar.clone()); + self.multi_progress.add(progress_bar) + } + + /// Clear all progress bars + /// + /// # Errors + /// Forwards the error from `indicatif::MultiProgress::clear`. + pub fn clear(&mut self) -> Result<(), std::io::Error> { + self.progress_bars.clear(); + self.multi_progress.clear() + } + + /// Suspend the progress bar updates while executing f. + pub fn suspend R, R>(&self, f: F) -> R { + self.multi_progress.suspend(f) + } +} diff --git a/src/main.rs b/src/main.rs index 349dfc4..cd4f9cd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -63,10 +63,7 @@ fn main_detail() -> Result<(), Box> { LogWrapper::new(multi_progress.clone(), logger).try_init()?; - let mut multi_progress_container = MultiProgressContainer { - progress_bars: Vec::new(), - multi_progress: multi_progress.clone(), - }; + let mut multi_progress_container = MultiProgressContainer::new(multi_progress.clone()); match options.command { Some(Commands::Show(show)) => match show { diff --git a/src/project.rs b/src/project.rs index d8d72a9..4d7d91c 100644 --- a/src/project.rs +++ b/src/project.rs @@ -1,4 +1,4 @@ -use indicatif::{ProgressBar, ProgressDrawTarget}; +use indicatif::ProgressBar; use log::{debug, trace, warn}; use serde_json::Value; use std::cmp::Ordering; @@ -93,15 +93,9 @@ impl Project { let jobs = state.jobs_submitted_on(&cluster_name); let mut progress = ProgressBar::new_spinner().with_message("Checking submitted job statuses"); - if jobs.is_empty() { - progress.set_draw_target(ProgressDrawTarget::hidden()); - // TODO: Refactor these types of code blocks into the MultiProgressContainer? - } else { - progress = multi_progress.multi_progress.add(progress); - multi_progress.progress_bars.push(progress.clone()); - progress.enable_steady_tick(Duration::from_millis(progress_styles::STEADY_TICK)); - } + progress = multi_progress.add_or_hide(progress, jobs.is_empty()); + progress.enable_steady_tick(Duration::from_millis(progress_styles::STEADY_TICK)); progress.set_style(progress_styles::uncounted_spinner()); progress.tick(); diff --git a/src/state.rs b/src/state.rs index a84d98e..09fb8c3 100644 --- a/src/state.rs +++ b/src/state.rs @@ -1,4 +1,4 @@ -use indicatif::{ProgressBar, ProgressDrawTarget}; +use indicatif::ProgressBar; use log::{debug, trace, warn}; use serde::{Deserialize, Serialize}; use serde_json::Value; @@ -322,12 +322,10 @@ impl State { // Then remove the staged files. let mut progress = ProgressBar::new(self.completed_file_names.len() as u64) .with_message("Removing staged completed actions"); - if self.completed_file_names.len() >= MIN_PROGRESS_BAR_SIZE { - progress = multi_progress.multi_progress.add(progress); - multi_progress.progress_bars.push(progress.clone()); - } else { - progress.set_draw_target(ProgressDrawTarget::hidden()); - } + progress = multi_progress.add_or_hide( + progress, + self.completed_file_names.len() < MIN_PROGRESS_BAR_SIZE, + ); progress.set_style(progress_styles::counted_bar()); progress.tick(); @@ -606,12 +604,10 @@ impl State { let mut progress = ProgressBar::new(self.completed_file_names.len() as u64) .with_message("Reading staged completed actions"); - if self.completed_file_names.len() >= MIN_PROGRESS_BAR_SIZE { - progress = multi_progress.multi_progress.add(progress); - multi_progress.progress_bars.push(progress.clone()); - } else { - progress.set_draw_target(ProgressDrawTarget::hidden()); - } + progress = multi_progress.add_or_hide( + progress, + self.completed_file_names.len() < MIN_PROGRESS_BAR_SIZE, + ); progress.set_style(progress_styles::counted_bar()); progress.tick(); diff --git a/src/workspace.rs b/src/workspace.rs index e5f7e8a..39bc722 100644 --- a/src/workspace.rs +++ b/src/workspace.rs @@ -1,4 +1,4 @@ -use indicatif::{ProgressBar, ProgressDrawTarget}; +use indicatif::ProgressBar; use log::debug; use serde_json::Value; use std::collections::{HashMap, HashSet}; @@ -24,10 +24,7 @@ pub fn list_directories( ) -> Result, Error> { let workspace_path = workflow.root.join(&workflow.workspace.path); - let progress = multi_progress - .multi_progress - .add(ProgressBar::new_spinner().with_message("Listing workspace")); - multi_progress.progress_bars.push(progress.clone()); + let progress = multi_progress.add(ProgressBar::new_spinner().with_message("Listing workspace")); progress.set_style(progress_styles::counted_spinner()); progress.enable_steady_tick(Duration::from_millis(progress_styles::STEADY_TICK)); @@ -96,13 +93,7 @@ pub fn find_completed_directories( ) -> CompletedDirectories { let mut progress = ProgressBar::new(directories.len() as u64).with_message("Scanning directories"); - if directories.len() >= MIN_PROGRESS_BAR_SIZE { - progress = multi_progress.multi_progress.add(progress); - multi_progress.progress_bars.push(progress.clone()); - } else { - progress.set_draw_target(ProgressDrawTarget::hidden()); - } - + progress = multi_progress.add_or_hide(progress, directories.len() < MIN_PROGRESS_BAR_SIZE); progress.set_style(progress_styles::counted_bar()); progress.tick(); @@ -253,12 +244,7 @@ pub(crate) fn read_values( let (sender, receiver) = mpsc::channel(); let mut progress = ProgressBar::new(directories.len() as u64).with_message("Reading values"); - if directories.len() >= MIN_PROGRESS_BAR_SIZE { - progress = multi_progress.multi_progress.add(progress); - multi_progress.progress_bars.push(progress.clone()); - } else { - progress.set_draw_target(ProgressDrawTarget::hidden()); - } + progress = multi_progress.add_or_hide(progress, directories.len() < MIN_PROGRESS_BAR_SIZE); progress.set_style(progress_styles::counted_bar()); progress.tick();