From d97edba041cf3ceab46bde10c14fb6c1b5ed54fc Mon Sep 17 00:00:00 2001 From: "andy.boot" Date: Sat, 18 Jan 2020 23:12:01 +0000 Subject: [PATCH] Add option to ignore directories https://github.com/bootandy/dust/issues/46 Add -X flag used to ignore any file or directory that matches the provided substring. This means that -X e will ignore any file or directory with an 'e' in it. --- src/main.rs | 9 +++++++++ src/tests.rs | 32 ++++++++++++++++++++++++++++++++ src/utils/mod.rs | 11 +++++++++++ 3 files changed, 52 insertions(+) diff --git a/src/main.rs b/src/main.rs index a4bf17e..ffeef54 100644 --- a/src/main.rs +++ b/src/main.rs @@ -54,6 +54,13 @@ fn main() { .long("full-paths") .help("If set sub directories will not have their path shortened"), ) + .arg( + Arg::with_name("ignore_directory") + .short("X") + .long("ignore-directory") + .takes_value(true) + .help("Exclude any file or directory with contains this substring."), + ) .arg( Arg::with_name("limit_filesystem") .short("x") @@ -128,10 +135,12 @@ fn main() { let use_apparent_size = options.is_present("display_apparent_size"); let limit_filesystem = options.is_present("limit_filesystem"); + let ignore_directory = options.value_of("ignore_directory"); let simplified_dirs = simplify_dir_names(target_dirs); let (permissions, nodes) = get_dir_tree( &simplified_dirs, + ignore_directory, use_apparent_size, limit_filesystem, threads, diff --git a/src/tests.rs b/src/tests.rs index dfe93e9..3a0f980 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -299,3 +299,35 @@ fn no_substring_of_names_output() -> String { " .into() } + +// Check against directories and files whos names are substrings of each other +#[test] +pub fn test_ignore_dir() { + assert_cli::Assert::main_binary() + .with_args(&["-c", "-X", "dir_substring", "src/test_dir2"]) + .stdout() + .is(ignore_dir_output().as_str()) + .unwrap(); +} + +#[cfg(target_os = "linux")] +fn ignore_dir_output() -> String { + " + 16K ─┬ test_dir2 + 8.0K ├─┬ dir + 4.0K │ └── hello + 4.0K └── dir_name_clash + " + .into() +} + +#[cfg(target_os = "macos")] +fn ignore_dir_output() -> String { + " + 8.0K ─┬ test_dir2 + 4.0K ├─┬ dir + 4.0K │ └── hello + 4.0K └── dir_name_clash + " + .into() +} diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 0f42788..105ef32 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -70,6 +70,7 @@ pub fn simplify_dir_names(filenames: Vec<&str>) -> HashSet { pub fn get_dir_tree( top_level_names: &HashSet, + ignore_directory: Option<&str>, apparent_size: bool, limit_filesystem: bool, threads: Option, @@ -88,6 +89,7 @@ pub fn get_dir_tree( &b, apparent_size, &restricted_filesystems, + &ignore_directory, &mut inodes, &mut data, &mut permissions, @@ -118,6 +120,7 @@ fn examine_dir( top_dir: &str, apparent_size: bool, filesystems: &Option>, + ignore_directory: &Option<&str>, inodes: &mut HashSet<(u64, u64)>, data: &mut HashMap, file_count_no_permission: &mut u64, @@ -132,6 +135,14 @@ fn examine_dir( for entry in iter { if let Ok(e) = entry { let maybe_size_and_inode = get_metadata(&e, apparent_size); + match ignore_directory { + Some(d) => { + if e.path().to_string_lossy().contains(*d) { + continue; + } + } + _ => {} + } match maybe_size_and_inode { Some((size, maybe_inode)) => {