diff --git a/completions/_dust b/completions/_dust index f9cf6597..838d3755 100644 --- a/completions/_dust +++ b/completions/_dust @@ -35,6 +35,10 @@ _dust() { '--version[Print version information]' \ '-p[Subdirectories will not have their path shortened]' \ '--full-paths[Subdirectories will not have their path shortened]' \ +'(-L --dereference-links)-l[Ignore links]' \ +'(-L --dereference-links)--ignore-links[Ignore links]' \ +'(-l --ignore-links)-L[dereference sym links - Treat sym links as directories and go into them]' \ +'(-l --ignore-links)--dereference-links[dereference sym links - Treat sym links as directories and go into them]' \ '-x[Only count the files and directories on the same filesystem as the supplied directory]' \ '--limit-filesystem[Only count the files and directories on the same filesystem as the supplied directory]' \ '-s[Use file length instead of blocks]' \ diff --git a/completions/_dust.ps1 b/completions/_dust.ps1 index 33c7fb2a..97628103 100644 --- a/completions/_dust.ps1 +++ b/completions/_dust.ps1 @@ -41,6 +41,10 @@ Register-ArgumentCompleter -Native -CommandName 'dust' -ScriptBlock { [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information') [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'Subdirectories will not have their path shortened') [CompletionResult]::new('--full-paths', 'full-paths', [CompletionResultType]::ParameterName, 'Subdirectories will not have their path shortened') + [CompletionResult]::new('-l', 'l', [CompletionResultType]::ParameterName, 'Ignore links') + [CompletionResult]::new('--ignore-links', 'ignore-links', [CompletionResultType]::ParameterName, 'Ignore links') + [CompletionResult]::new('-L', 'L', [CompletionResultType]::ParameterName, 'dereference sym links - Treat sym links as directories and go into them') + [CompletionResult]::new('--dereference-links', 'dereference-links', [CompletionResultType]::ParameterName, 'dereference sym links - Treat sym links as directories and go into them') [CompletionResult]::new('-x', 'x', [CompletionResultType]::ParameterName, 'Only count the files and directories on the same filesystem as the supplied directory') [CompletionResult]::new('--limit-filesystem', 'limit-filesystem', [CompletionResultType]::ParameterName, 'Only count the files and directories on the same filesystem as the supplied directory') [CompletionResult]::new('-s', 's', [CompletionResultType]::ParameterName, 'Use file length instead of blocks') diff --git a/completions/dust.bash b/completions/dust.bash index 92d0a87f..314b09ce 100644 --- a/completions/dust.bash +++ b/completions/dust.bash @@ -19,7 +19,7 @@ _dust() { case "${cmd}" in dust) - opts="-h -V -d -n -p -X -x -s -r -c -b -z -f -i -v -e -t -w -H -D --help --version --depth --number-of-lines --full-paths --ignore-directory --limit-filesystem --apparent-size --reverse --no-colors --no-percent-bars --min-size --skip-total --filecount --ignore_hidden --invert-filter --filter --file_types --terminal_width --si --only-dir ..." + opts="-h -V -d -n -p -X -l -L -x -s -r -c -b -z -f -i -v -e -t -w -H -D --help --version --depth --number-of-lines --full-paths --ignore-directory --ignore-links --dereference-links --limit-filesystem --apparent-size --reverse --no-colors --no-percent-bars --min-size --skip-total --filecount --ignore_hidden --invert-filter --filter --file_types --terminal_width --si --only-dir ..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 diff --git a/completions/dust.elv b/completions/dust.elv index a5429b1b..946d1ebd 100644 --- a/completions/dust.elv +++ b/completions/dust.elv @@ -38,6 +38,10 @@ set edit:completion:arg-completer[dust] = {|@words| cand --version 'Print version information' cand -p 'Subdirectories will not have their path shortened' cand --full-paths 'Subdirectories will not have their path shortened' + cand -l 'Ignore links' + cand --ignore-links 'Ignore links' + cand -L 'dereference sym links - Treat sym links as directories and go into them' + cand --dereference-links 'dereference sym links - Treat sym links as directories and go into them' cand -x 'Only count the files and directories on the same filesystem as the supplied directory' cand --limit-filesystem 'Only count the files and directories on the same filesystem as the supplied directory' cand -s 'Use file length instead of blocks' diff --git a/completions/dust.fish b/completions/dust.fish index 457e539c..2ea53e61 100644 --- a/completions/dust.fish +++ b/completions/dust.fish @@ -8,6 +8,8 @@ complete -c dust -s w -l terminal_width -d 'Specify width of output overriding t complete -c dust -s h -l help -d 'Print help information' complete -c dust -s V -l version -d 'Print version information' complete -c dust -s p -l full-paths -d 'Subdirectories will not have their path shortened' +complete -c dust -s l -l ignore-links -d 'Ignore links' +complete -c dust -s L -l dereference-links -d 'dereference sym links - Treat sym links as directories and go into them' complete -c dust -s x -l limit-filesystem -d 'Only count the files and directories on the same filesystem as the supplied directory' complete -c dust -s s -l apparent-size -d 'Use file length instead of blocks' complete -c dust -s r -l reverse -d 'Print tree upside down (biggest highest)' diff --git a/src/cli.rs b/src/cli.rs index c80fbac3..d55d02e5 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -34,6 +34,20 @@ pub fn build_cli() -> Command<'static> { .multiple_occurrences(true) .help("Exclude any file or directory with this name"), ) + .arg( + Arg::new("ignore_links") + .short('l') + .long("ignore-links") + .conflicts_with("dereference_links") + .help("Ignore links"), + ) + .arg( + Arg::new("dereference_links") + .short('L') + .long("dereference-links") + .conflicts_with("ignore_links") + .help("dereference sym links - Treat sym links as directories and go into them"), + ) .arg( Arg::new("limit_filesystem") .short('x') @@ -136,6 +150,6 @@ pub fn build_cli() -> Command<'static> { Arg::new("only_dir") .short('D') .long("only-dir") - .help("Only directories will be displayed."), + .help("Only directories will be displayed."), ) } diff --git a/src/dir_walker.rs b/src/dir_walker.rs index b9582376..5f619f3a 100644 --- a/src/dir_walker.rs +++ b/src/dir_walker.rs @@ -26,6 +26,8 @@ pub struct WalkData<'a> { pub use_apparent_size: bool, pub by_filecount: bool, pub ignore_hidden: bool, + pub ignore_links: bool, + pub follow_links: bool, } pub fn walk_it(dirs: HashSet, walk_data: WalkData) -> (Vec, bool) { @@ -141,24 +143,27 @@ fn walk( // return walk(entry.path(), permissions_flag, ignore_directories, allowed_filesystems, use_apparent_size, by_filecount, ignore_hidden); - if !ignore_file(entry, walk_data) { - if let Ok(data) = entry.file_type() { - return if data.is_dir() && !data.is_symlink() { - walk(entry.path(), permissions_flag, walk_data, depth + 1) - } else { - build_node( - entry.path(), - vec![], - walk_data.filter_regex, - walk_data.invert_filter_regex, - walk_data.use_apparent_size, - data.is_symlink(), - data.is_file(), - walk_data.by_filecount, - depth, - ) - }; + if ignore_file(entry, walk_data) { + return None; + } + if let Ok(data) = entry.file_type() { + if data.is_symlink() && walk_data.ignore_links { + return None; + } + if data.is_dir() || (walk_data.follow_links && data.is_symlink()) { + return walk(entry.path(), permissions_flag, walk_data, depth + 1); } + return build_node( + entry.path(), + vec![], + walk_data.filter_regex, + walk_data.invert_filter_regex, + walk_data.use_apparent_size, + data.is_symlink(), + data.is_file(), + walk_data.by_filecount, + depth, + ); } } else { permissions_flag.store(true, atomic::Ordering::Relaxed); diff --git a/src/main.rs b/src/main.rs index 19f69d55..11d859ce 100644 --- a/src/main.rs +++ b/src/main.rs @@ -152,6 +152,8 @@ fn main() { let by_filecount = options.is_present("by_filecount"); let limit_filesystem = options.is_present("limit_filesystem"); + let ignore_links = options.is_present("ignore_links"); + let follow_links = options.is_present("dereference_links"); let simplified_dirs = simplify_dir_names(target_dirs); let allowed_filesystems = limit_filesystem @@ -167,6 +169,8 @@ fn main() { filter_regex: &filter_regexs, invert_filter_regex: &invert_filter_regexs, allowed_filesystems, + ignore_links, + follow_links, use_apparent_size: config.get_apparent_size(&options), by_filecount, ignore_hidden: config.get_ignore_hidden(&options),