diff --git a/README.md b/README.md index b12501b..b0133dc 100644 --- a/README.md +++ b/README.md @@ -129,6 +129,6 @@ These benchmarks were run using [hyperfine](https://github.com/sharkdp/hyperfine - [ ] add an option to use a bloom filter for very large filesystems - [ ] max file path size should use the last set of duplicates - [-] add unit tests -- [ ] add silent mode +- [x] add silent mode - [ ] restore json output - [ ] update documentation diff --git a/src/formatter.rs b/src/formatter.rs index b0c5752..aaf8b42 100644 --- a/src/formatter.rs +++ b/src/formatter.rs @@ -42,10 +42,15 @@ impl Formatter { app_args: &Params, ) -> Result { let mut output_table = Table::new(); + output_table.set_titles(row!["hash", "duplicates"]); + let progress_bar = match app_args.progress { + true => ProgressBar::new_spinner(), + false => ProgressBar::hidden(), + }; + let progress_style = ProgressStyle::with_template("[{elapsed_precise}] {pos:>7} {msg}")?; - let progress_bar = ProgressBar::new_spinner(); progress_bar.set_style(progress_style); progress_bar.enable_steady_tick(Duration::from_millis(50)); progress_bar.set_message("generating output"); diff --git a/src/params.rs b/src/params.rs index 4026d1e..9d31f81 100644 --- a/src/params.rs +++ b/src/params.rs @@ -3,7 +3,7 @@ use std::{fs, path::PathBuf}; use anyhow::Result; use clap::{Parser, ValueHint}; -#[derive(Parser, Debug, Clone)] +#[derive(Parser, Debug, Default, Clone)] #[command(author, version, about, long_about = None)] pub struct Params { /// Filetypes to deduplicate [default = all] @@ -30,6 +30,9 @@ pub struct Params { /// Guarantees that two files are duplicate (performs a full hash) #[arg(long, short = 'f', default_value = "false")] pub strict: bool, + /// Show Progress spinners & metrics + #[arg(long, short = 'p', default_value = "false")] + pub progress: bool, } impl Params { diff --git a/src/processor.rs b/src/processor.rs index 71c61bc..1bf7809 100644 --- a/src/processor.rs +++ b/src/processor.rs @@ -18,9 +18,13 @@ impl Processor { sw_store: Arc>>, hw_store: Arc>>, ) -> Result<()> { + let progress_bar = match app_args.progress { + true => ProgressBar::new_spinner(), + false => ProgressBar::hidden(), + }; + let keys: Vec = sw_store.clone().iter().map(|i| *i.key()).collect(); let progress_style = ProgressStyle::with_template("[{elapsed_precise}] {pos:>7} {msg}")?; - let progress_bar = ProgressBar::new_spinner(); progress_bar.set_style(progress_style); progress_bar.enable_steady_tick(Duration::from_millis(50)); progress_bar.set_message("files grouped by hash."); @@ -60,13 +64,18 @@ impl Processor { } pub fn sizewise( + app_args: Arc, scanner_finished: Arc, store: Arc>>, files: Arc>>, max_file_size: Arc, ) -> Result<()> { + let progress_bar = match app_args.progress { + true => ProgressBar::new_spinner(), + false => ProgressBar::hidden(), + }; + let progress_style = ProgressStyle::with_template("[{elapsed_precise}] {pos:>7} {msg}")?; - let progress_bar = ProgressBar::new_spinner(); progress_bar.set_style(progress_style); progress_bar.enable_steady_tick(Duration::from_millis(50)); progress_bar.set_message("files grouped by size"); @@ -94,7 +103,10 @@ impl Processor { continue; } None => match scanner_finished.load(std::sync::atomic::Ordering::Relaxed) { - true => break Ok(()), + true => { + progress_bar.finish_with_message("files grouped by size"); + break Ok(()); + } false => continue, }, } @@ -113,7 +125,7 @@ mod tests { use std::sync::{Arc, Mutex}; use tempfile::TempDir; - use crate::fileinfo::FileInfo; + use crate::{fileinfo::FileInfo, params::Params}; use super::Processor; @@ -145,6 +157,7 @@ mod tests { let dupstore = Arc::new(DashMap::new()); Processor::sizewise( + Arc::new(Params::default()), Arc::new(AtomicBool::new(true)), dupstore.clone(), file_queue, diff --git a/src/scanner.rs b/src/scanner.rs index e5cf685..829aa94 100644 --- a/src/scanner.rs +++ b/src/scanner.rs @@ -14,6 +14,7 @@ pub struct Scanner { pub max_depth: Option, pub min_size: Option, pub follow_links: bool, + pub progress: bool, } impl Scanner { @@ -25,12 +26,14 @@ impl Scanner { max_depth: None, min_size: None, follow_links: true, + progress: false, } } pub fn build(app_args: Arc) -> Result { let mut scanner = Scanner::new(); scanner.directory = Some(app_args.get_directory()?); + scanner.progress = app_args.progress; if let Some(min_size) = app_args.get_min_size() { scanner.min_size = Some(min_size); @@ -100,8 +103,11 @@ impl Scanner { } pub fn scan(&self, files: Arc>>) -> Result<()> { + let progress_bar = match self.progress { + true => ProgressBar::new_spinner(), + false => ProgressBar::hidden(), + }; let progress_style = ProgressStyle::with_template("[{elapsed_precise}] {pos:>7} {msg}")?; - let progress_bar = ProgressBar::new_spinner(); progress_bar.set_style(progress_style); progress_bar.enable_steady_tick(Duration::from_millis(50)); progress_bar.set_message("paths mapped"); diff --git a/src/server.rs b/src/server.rs index a04afd4..f02bc41 100644 --- a/src/server.rs +++ b/src/server.rs @@ -57,6 +57,7 @@ impl Server { self.threadpool.execute(move || { Processor::sizewise( + app_args_clone_for_pr.clone(), sfin_pr_tr_cl, store_dupl_sw_for_sw, file_queue_clone_pr,