diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..5cd7d81 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,2 @@ +[build] +rustflags = ["-C", "target-feature=+aes,+sse2"] diff --git a/Cargo.lock b/Cargo.lock index da2b2b3..5d03f1d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -273,7 +273,7 @@ dependencies = [ [[package]] name = "deduplicator" -version = "0.3.1" +version = "0.3.2" dependencies = [ "anyhow", "bytesize", diff --git a/Cargo.toml b/Cargo.toml index 1079533..9cd1ed1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "deduplicator" -version = "0.3.1" +version = "0.3.2" edition = "2021" description = "find,filter and delete duplicate files" repository = "https://github.com/sreedevk/deduplicator" diff --git a/README.md b/README.md index 2135e00..e9f0ae5 100644 --- a/README.md +++ b/README.md @@ -155,6 +155,8 @@ dust 'bench_artifacts' ## proposed - [ ] parallelization - [ ] scanning + processing sw + processing hw + formatting + printing +- [ ] user supplied cache file path for faster re-runs +- [ ] hardlinks / symlinks support - [ ] max file path size should use the last set of duplicates - [ ] add more unit tests - [ ] test against different filesystems @@ -177,6 +179,9 @@ dust 'bench_artifacts' - [ ] append the offset between the last initial page hashed and the first final page hashed in the content passed to the hasher. - [ ] fix: --exclude-types and --types flag behave identically. +## v0.3.2 +- [x] fix: single file groups are printed to screen + ## v0.3.1 - [x] parallelization - [x] (scanning + processing sw + processing hw) & formatting & printing diff --git a/src/formatter.rs b/src/formatter.rs index 731f644..793e498 100644 --- a/src/formatter.rs +++ b/src/formatter.rs @@ -4,6 +4,7 @@ use chrono::{DateTime, Utc}; use dashmap::DashMap; use pathdiff::diff_paths; use rayon::prelude::*; +use std::sync::atomic::AtomicU64; use std::{path::PathBuf, sync::Arc}; const YELLOW: &str = "\x1b[33m"; @@ -39,26 +40,34 @@ impl Formatter { if raw.is_empty() { println!("No duplicates found matching your search criteria."); } else { + let printed_count: AtomicU64 = AtomicU64::new(0); + raw.par_iter().for_each(|sref| { - let mut ostring = format!("{}{:32x}{}\n", YELLOW, sref.key(), RESET); - let subfields = sref - .value() - .par_iter() - .map(|finfo| { - format!( - "├─ {}\t{}\t{}\n", - Self::human_path(finfo, aargs, max_path_len as usize) - .expect("path formatting failed."), - Self::human_filesize(finfo).expect("filesize formatting failed."), - Self::human_mtime(finfo).expect("modified time formatting failed.") - ) - }) - .collect::(); + if sref.value().len() > 1 { + printed_count.fetch_add(1, std::sync::atomic::Ordering::Relaxed); + let mut ostring = format!("{}{:32x}{}\n", YELLOW, sref.key(), RESET); + let subfields = sref + .value() + .par_iter() + .map(|finfo| { + format!( + "├─ {}\t{}\t{}\n", + Self::human_path(finfo, aargs, max_path_len as usize) + .expect("path formatting failed."), + Self::human_filesize(finfo).expect("filesize formatting failed."), + Self::human_mtime(finfo).expect("modified time formatting failed.") + ) + }) + .collect::(); - ostring.push_str(&subfields); - - println!("{ostring}"); + ostring.push_str(&subfields); + println!("{ostring}"); + } }); + + if printed_count.load(std::sync::atomic::Ordering::Relaxed) < 1 { + println!("No duplicates found matching your search criteria."); + } } } } diff --git a/src/interactive.rs b/src/interactive.rs index 51dbf6c..3cb20cd 100644 --- a/src/interactive.rs +++ b/src/interactive.rs @@ -2,6 +2,7 @@ use crate::{fileinfo::FileInfo, formatter::Formatter, params::Params}; use anyhow::Result; use dashmap::DashMap; use prettytable::{format, row, Table}; +use std::sync::atomic::AtomicU64; use std::{ io::{self, Write}, sync::Arc, @@ -11,12 +12,19 @@ pub struct Interactive; impl Interactive { pub fn init(result: Arc>>, app_args: &Params) -> Result<()> { - result - .clone() + let store = result.clone(); + if store.is_empty() { + println!("No duplicates found matching your search criteria."); + } + + let printed_count: AtomicU64 = AtomicU64::new(0); + + store .iter() .filter(|i| i.value().len() > 1) .enumerate() .for_each(|(gindex, i)| { + printed_count.fetch_add(1, std::sync::atomic::Ordering::Relaxed); let group = i.value(); let mut itable = Table::new(); itable.set_format(*format::consts::FORMAT_NO_BORDER_LINE_SEPARATOR); @@ -40,6 +48,10 @@ impl Interactive { Self::process_group_action(group, gindex, result.len(), itable); }); + if printed_count.load(std::sync::atomic::Ordering::Relaxed) < 1 { + println!("No duplicates found matching your search criteria."); + } + Ok(()) }