Compare commits

..

2 Commits

Author SHA1 Message Date
andy.boot
0d0206a5a5 Version: New version 2022-08-25 10:18:18 +01:00
andy.boot
dfce0eec66 Fix: Warn if configuring threads fails
User reported this unwrap could fail, so log an error instead of using a
naked unwrap.
2022-08-25 08:59:15 +01:00
14 changed files with 37 additions and 168 deletions

32
Cargo.lock generated
View File

@@ -118,12 +118,6 @@ dependencies = [
"toml",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
[[package]]
name = "crossbeam-channel"
version = "0.5.6"
@@ -207,7 +201,6 @@ version = "0.8.3"
dependencies = [
"ansi_term",
"assert_cmd",
"atty",
"clap",
"clap_complete",
"config-file",
@@ -217,7 +210,6 @@ dependencies = [
"regex",
"serde",
"stfu8",
"sysinfo",
"tempfile",
"terminal_size",
"thousands",
@@ -330,15 +322,6 @@ dependencies = [
"autocfg",
]
[[package]]
name = "ntapi"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc51db7b362b205941f71232e56c625156eb9a929f8cf74a428fd5bc094a4afc"
dependencies = [
"winapi",
]
[[package]]
name = "num_cpus"
version = "1.13.1"
@@ -535,21 +518,6 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "sysinfo"
version = "0.26.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c375d5fd899e32847b8566e10598d6e9f1d9b55ec6de3cdf9e7da4bdc51371bc"
dependencies = [
"cfg-if",
"core-foundation-sys",
"libc",
"ntapi",
"once_cell",
"rayon",
"winapi",
]
[[package]]
name = "tempfile"
version = "3.3.0"

View File

@@ -28,7 +28,6 @@ strip = true
[dependencies]
ansi_term = "0.12"
atty = "0.2.14"
clap = "3.2.17"
lscolors = "0.7"
terminal_size = "0.1"
@@ -40,7 +39,6 @@ regex = "1"
config-file = "0.2"
serde = { version = "1.0", features = ["derive"] }
directories = "4"
sysinfo = "0.26"
[target.'cfg(windows)'.dependencies]
winapi-util = "0.1"

View File

@@ -30,10 +30,6 @@ Because I want an easy way to see where my disk is being used.
- `pacstall -I dust-bin`
#### [deb-get](https://github.com/wimpysworld/deb-get) (Debian/Ubuntu)
- `deb-get install du-dust`
#### Windows:
- Windows GNU version - works
@@ -63,7 +59,6 @@ Usage: dust -p (full-path - Show fullpath of the subdirectories)
Usage: dust -s (apparent-size - shows the length of the file as opposed to the amount of disk space it uses)
Usage: dust -n 30 (Shows 30 directories instead of the default [default is terminal height])
Usage: dust -d 3 (Shows 3 levels of subdirectories)
Usage: dust -D (Show only directories (eg dust -D))
Usage: dust -r (reverse order of output)
Usage: dust -H (si print sizes in powers of 1000 instead of 1024)
Usage: dust -X ignore (ignore all files and directories with the name 'ignore')

View File

@@ -35,10 +35,6 @@ _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]' \
@@ -58,8 +54,6 @@ _dust() {
'(-d --depth)--file_types[show only these file types]' \
'-H[print sizes in powers of 1000 (e.g., 1.1G)]' \
'--si[print sizes in powers of 1000 (e.g., 1.1G)]' \
'-D[Only directories will be displayed.]' \
'--only-dir[Only directories will be displayed.]' \
'*::inputs:' \
&& ret=0
}

View File

@@ -41,10 +41,6 @@ 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')
@@ -64,8 +60,6 @@ Register-ArgumentCompleter -Native -CommandName 'dust' -ScriptBlock {
[CompletionResult]::new('--file_types', 'file_types', [CompletionResultType]::ParameterName, 'show only these file types')
[CompletionResult]::new('-H', 'H', [CompletionResultType]::ParameterName, 'print sizes in powers of 1000 (e.g., 1.1G)')
[CompletionResult]::new('--si', 'si', [CompletionResultType]::ParameterName, 'print sizes in powers of 1000 (e.g., 1.1G)')
[CompletionResult]::new('-D', 'D', [CompletionResultType]::ParameterName, 'Only directories will be displayed.')
[CompletionResult]::new('--only-dir', 'only-dir', [CompletionResultType]::ParameterName, 'Only directories will be displayed.')
break
}
})

View File

@@ -19,7 +19,7 @@ _dust() {
case "${cmd}" in
dust)
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 <inputs>..."
opts="-h -V -d -n -p -X -x -s -r -c -b -z -f -i -v -e -t -w -H --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 <inputs>..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0

View File

@@ -38,10 +38,6 @@ 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'
@@ -61,8 +57,6 @@ set edit:completion:arg-completer[dust] = {|@words|
cand --file_types 'show only these file types'
cand -H 'print sizes in powers of 1000 (e.g., 1.1G)'
cand --si 'print sizes in powers of 1000 (e.g., 1.1G)'
cand -D 'Only directories will be displayed.'
cand --only-dir 'Only directories will be displayed.'
}
]
$completions[$command]

View File

@@ -8,8 +8,6 @@ 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)'
@@ -20,4 +18,3 @@ complete -c dust -s f -l filecount -d 'Directory \'size\' is number of child fil
complete -c dust -s i -l ignore_hidden -d 'Do not display hidden files'
complete -c dust -s t -l file_types -d 'show only these file types'
complete -c dust -s H -l si -d 'print sizes in powers of 1000 (e.g., 1.1G)'
complete -c dust -s D -l only-dir -d 'Only directories will be displayed.'

View File

@@ -34,20 +34,6 @@ 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')
@@ -145,11 +131,5 @@ pub fn build_cli() -> Command<'static> {
.long("si")
.help("print sizes in powers of 1000 (e.g., 1.1G)")
)
.arg(Arg::new("inputs").multiple_occurrences(true))
.arg(
Arg::new("only_dir")
.short('D')
.long("only-dir")
.help("Only directories will be displayed."),
)
.arg(Arg::new("inputs").multiple_occurrences(true).default_value("."))
}

View File

@@ -19,7 +19,6 @@ pub struct Config {
pub ignore_hidden: Option<bool>,
pub iso: Option<bool>,
pub min_size: Option<String>,
pub only_dir: Option<bool>,
}
impl Config {
@@ -62,9 +61,6 @@ impl Config {
size_from_param
}
}
pub fn get_only_dir(&self, options: &ArgMatches) -> bool {
Some(true) == self.only_dir || options.is_present("only_dir")
}
}
fn convert_min_size(input: &str, iso: bool) -> Option<usize> {

View File

@@ -26,8 +26,6 @@ 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<PathBuf>, walk_data: WalkData) -> (Vec<Node>, bool) {
@@ -143,27 +141,24 @@ 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) {
return None;
}
if let Ok(data) = entry.file_type() {
if data.is_symlink() && walk_data.ignore_links {
return None;
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 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);

View File

@@ -88,7 +88,7 @@ impl DrawData<'_> {
let mut num_not_my_bar = (chars_in_bar as i32) - num_bars as i32;
let mut new_bar = "".to_string();
let idx = 5 - level.clamp(1, 4);
let idx = 5 - min(4, max(1, level));
for c in self.percent_bar.chars() {
num_not_my_bar -= 1;
@@ -141,10 +141,10 @@ pub fn draw_it(
let longest_string_length =
find_longest_dir_name(root_node, num_indent_chars, allowed_width, !use_full_path);
let max_bar_length = if no_percent_bars || longest_string_length + 7 >= allowed_width {
let max_bar_length = if no_percent_bars || longest_string_length + 7 >= allowed_width as usize {
0
} else {
allowed_width - longest_string_length - 7
allowed_width as usize - longest_string_length - 7
};
let first_size_bar = repeat(BLOCKS[0]).take(max_bar_length).collect();

View File

@@ -8,7 +8,6 @@ use std::path::PathBuf;
pub fn get_biggest(
top_level_nodes: Vec<Node>,
min_size: Option<usize>,
only_dir: bool,
n: usize,
depth: usize,
using_a_filter: bool,
@@ -24,14 +23,14 @@ pub fn get_biggest(
let mut allowed_nodes = HashSet::new();
allowed_nodes.insert(root.name.as_path());
heap = add_children(using_a_filter, min_size, only_dir, &root, depth, heap);
heap = add_children(using_a_filter, min_size, &root, depth, heap);
for _ in number_top_level_nodes..n {
let line = heap.pop();
match line {
Some(line) => {
allowed_nodes.insert(line.name.as_path());
heap = add_children(using_a_filter, min_size, only_dir, line, depth, heap);
heap = add_children(using_a_filter, min_size, line, depth, heap);
}
None => break,
}
@@ -42,22 +41,15 @@ pub fn get_biggest(
fn add_children<'a>(
using_a_filter: bool,
min_size: Option<usize>,
only_dir: bool,
file_or_folder: &'a Node,
depth: usize,
mut heap: BinaryHeap<&'a Node>,
) -> BinaryHeap<&'a Node> {
if depth > file_or_folder.depth {
heap.extend(
file_or_folder
.children
.iter()
.filter(|c| match min_size {
Some(ms) => c.size > ms as u64,
None => !using_a_filter || c.name.is_file() || c.size > 0,
})
.filter(|c| if only_dir { c.name.is_dir() } else { true }),
)
heap.extend(file_or_folder.children.iter().filter(|c| match min_size {
Some(ms) => c.size > ms as u64,
None => !using_a_filter || c.name.is_file() || c.size > 0,
}))
}
heap
}

View File

@@ -11,9 +11,7 @@ mod utils;
use crate::cli::build_cli;
use std::collections::HashSet;
use std::io::BufRead;
use std::process;
use sysinfo::{System, SystemExt};
use self::display::draw_it;
use clap::Values;
@@ -21,7 +19,6 @@ use config::get_config;
use dir_walker::{walk_it, WalkData};
use filter::get_biggest;
use filter_type::get_all_file_types;
use rayon::ThreadPoolBuildError;
use regex::Regex;
use std::cmp::max;
use std::path::PathBuf;
@@ -92,28 +89,14 @@ fn get_regex_value(maybe_value: Option<Values>) -> Vec<Regex> {
.collect()
}
// Returns a list of lines from stdin or `None` if there's nothing to read
fn get_lines_from_stdin() -> Option<Vec<String>> {
atty::isnt(atty::Stream::Stdin).then(|| {
std::io::stdin()
.lock()
.lines()
.collect::<Result<_, _>>()
.expect("Error reading from stdin")
})
}
fn main() {
let options = build_cli().get_matches();
let config = get_config();
let stdin_lines = get_lines_from_stdin();
let target_dirs = match options.values_of("inputs") {
Some(values) => values.collect(),
None => stdin_lines.as_ref().map_or(vec!["."], |lines| {
lines.iter().map(String::as_str).collect()
}),
};
let target_dirs = options
.values_of("inputs")
.expect("Should be a default value here")
.collect();
let summarize_file_types = options.is_present("types");
@@ -152,8 +135,6 @@ 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
@@ -169,13 +150,15 @@ 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),
};
let _rayon = init_rayon();
// Larger stack size to handle cases with lots of nested directories
rayon::ThreadPoolBuilder::new()
.stack_size(usize::pow(1024, 3))
.build_global()
.unwrap_or_else(|e| eprintln!("Warning: Could not configure threads {:?}", e));
let iso = config.get_iso(&options);
let (top_level_nodes, has_errors) = walk_it(simplified_dirs, walk_data);
@@ -185,7 +168,6 @@ fn main() {
false => get_biggest(
top_level_nodes,
config.get_min_size(&options, iso),
config.get_only_dir(&options),
number_of_lines,
depth,
options.values_of("filter").is_some() || options.value_of("invert_filter").is_some(),
@@ -209,19 +191,3 @@ fn main() {
)
}
}
fn init_rayon() -> Result<(), ThreadPoolBuildError> {
let large_stack = usize::pow(1024, 3);
let mut s = System::new();
s.refresh_memory();
let available = s.available_memory();
if available > large_stack.try_into().unwrap() {
// Larger stack size to handle cases with lots of nested directories
rayon::ThreadPoolBuilder::new()
.stack_size(large_stack)
.build_global()
} else {
Ok(())
}
}