Compare commits

...

17 Commits
deps ... up

Author SHA1 Message Date
andy.boot
3d95773a99 Fix: windows build missed in nu_ansi_term upgrade 2026-01-08 20:01:29 +00:00
andy.boot
2208ee517f deps: update dependencies 2026-01-08 19:36:48 +00:00
Jeremy Bícha
d39224d670 deps: switch from ansi_term to nu_ansi_term 2026-01-08 19:32:58 +00:00
andy.boot
6c20fae3e8 docs: Update README.md
typos
2026-01-07 20:05:43 +00:00
andy.boot
3ab81fcd2f docs: Update README.md 2026-01-07 20:03:28 +00:00
andy.boot
0703784cab docs: Update README.md 2026-01-07 20:02:58 +00:00
andy.boot
f51bd0d6a3 docs: update image
better image
2026-01-07 20:00:55 +00:00
andy.boot
514bdcdc74 docs: Update README.md
using a new image
2026-01-07 19:59:26 +00:00
andy.boot
4b64585290 docs: Update README.md 2026-01-07 19:54:43 +00:00
andy.boot
10eba445c9 docs: update description of 'n'
Change sample image file
2026-01-07 19:51:47 +00:00
andy.boot
a0c0779849 tests: Update assert_cmd
Use new cargo_bin_cmd macro. Old way of building Commands is deprecated
2026-01-07 19:13:33 +00:00
andy.boot
62bf1e14de deps: update libraries 2025-11-24 21:15:44 +00:00
andy.boot
de2d748a88 chore: Retire directories library
Only used in one place (less dependencies = good).
Also directories has been retired as a github project. Easier to replace
with std::env::home() which has all the functionality we need
2025-11-20 23:46:34 +00:00
Benjamin A. Beasley
509d51e872 Update directories from 4 to 6 2025-11-20 22:46:40 +00:00
AminurAlam
f98b841d23 fix: dont format filecount when output is set to json 2025-10-13 19:49:24 +01:00
andy.boot
67d23e80ff style: fix clippy 2025-10-06 20:42:19 +01:00
andy.boot
968377eebd deps: cargo update 2025-10-06 20:42:19 +01:00
18 changed files with 500 additions and 574 deletions

789
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -27,11 +27,11 @@ lto = true
strip = true
[dependencies]
ansi_term = "0.12"
clap = { version = "4.4", features = ["derive"] }
lscolors = "0.13"
terminal_size = "0.2"
unicode-width = "0.1"
clap = { version = "4", features = ["derive"] }
lscolors = "0.21"
nu-ansi-term = "0.50"
terminal_size = "0.4"
unicode-width = "0.2"
rayon = "1"
thousands = "0.2"
stfu8 = "0.2"
@@ -39,9 +39,8 @@ regex = "1"
config-file = "0.2"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
directories = "4"
sysinfo = "0.27"
ctrlc = "3.4"
sysinfo = "0.37"
ctrlc = "3"
chrono = "0.4"
[target.'cfg(not(target_has_atomic = "64"))'.dependencies]

View File

@@ -13,6 +13,17 @@ Because I want an easy way to see where my disk is being used.
![Example](media/snap.png)
Study the above picture.
* We see `target` has 1.8G
* `target/debug` is the same size as `target` - so we know nearly all the disk usage of the 1.5G is in this folder
* `target/debug/deps` this is 1.2G - Note the bar jumps down to 70% to indicate that most disk usage is here but not all.
* `target/debug/deps/dust-e78c9f87a17f24f3` - This is the largest file in this folder, but it is only 46M - Note the bar jumps down to 3% to indicate the file is small.
From here we can conclude:
* `target/debug/deps` takes the majority of the space in `target` and that `target/debug/deps` has a large number of relatively small files.
## Install
#### Cargo <a href="https://repology.org/project/du-dust/versions"><img src="https://repology.org/badge/vertical-allrepos/du-dust.svg" alt="Packaging status" align="right"></a>
@@ -69,6 +80,8 @@ Dust will list a slightly-less-than-the-terminal-height number of the biggest su
The different colors on the bars: These represent the combined tree hierarchy & disk usage. The shades of grey are used to indicate which parent folder a subfolder belongs to. For instance, look at the above screenshot. `.steam` is a folder taking 44% of the space. From the `.steam` bar is a light grey line that goes up. All these folders are inside `.steam` so if you delete `.steam` all that stuff will be gone too.
If you are new to the tool I recommend to try tweaking the `-n` parameter. `dust -n 10`, `dust -n 50`.
## Usage
```
@@ -125,4 +138,14 @@ reverse=true
- [dirstat-rs](https://github.com/scullionw/dirstat-rs)
- `du -d 1 -h | sort -h`
Note: Apparent-size is calculated slightly differently in dust to gdu. In dust each hard link is counted as using file_length space. In gdu only the first entry is counted.
## Why to use Dust over the Alternatives
Dust simply Does The Right Thing when handling lots of small files & directories. Dust keeps the output simple by only showing large entries.
Tools like ncdu & baobab, give you a view of directory sizes but you have no idea where the largest files are. For example directory A could have a size larger than directory B, but in fact the largest file is in B and not A. Finding this out via these other tools is not trivial whereas Dust will show the large file clearly in the tree hierarchy
Dust will not count hard links multiple times (unless you want to `-s`).
Typing `dust -n 90` will show you your 90 largest entries. `-n` is not quite like `head -n` or `tail -n`, dust is intelligent and chooses the largest entries

View File

@@ -20,8 +20,8 @@ _dust() {
'-T+[Number of threads to use]:THREADS:_default' \
'--threads=[Number of threads to use]:THREADS:_default' \
'--config=[Specify a config file to use]:FILE:_files' \
'-n+[Number of lines of output to show. (Default is terminal_height - 10)]:NUMBER:_default' \
'--number-of-lines=[Number of lines of output to show. (Default is terminal_height - 10)]:NUMBER:_default' \
'-n+[Display the '\''n'\'' largest entries. (Default is terminal_height)]:NUMBER:_default' \
'--number-of-lines=[Display the '\''n'\'' largest entries. (Default is terminal_height)]:NUMBER:_default' \
'*-X+[Exclude any file or directory with this path]:PATH:_files' \
'*--ignore-directory=[Exclude any file or directory with this path]:PATH:_files' \
'-I+[Exclude any file or directory with a regex matching that listed in this file, the file entries will be added to the ignore regexs provided by --invert_filter]:FILE:_files' \

View File

@@ -26,8 +26,8 @@ Register-ArgumentCompleter -Native -CommandName 'dust' -ScriptBlock {
[CompletionResult]::new('-T', '-T ', [CompletionResultType]::ParameterName, 'Number of threads to use')
[CompletionResult]::new('--threads', '--threads', [CompletionResultType]::ParameterName, 'Number of threads to use')
[CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'Specify a config file to use')
[CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Number of lines of output to show. (Default is terminal_height - 10)')
[CompletionResult]::new('--number-of-lines', '--number-of-lines', [CompletionResultType]::ParameterName, 'Number of lines of output to show. (Default is terminal_height - 10)')
[CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Display the ''n'' largest entries. (Default is terminal_height)')
[CompletionResult]::new('--number-of-lines', '--number-of-lines', [CompletionResultType]::ParameterName, 'Display the ''n'' largest entries. (Default is terminal_height)')
[CompletionResult]::new('-X', '-X ', [CompletionResultType]::ParameterName, 'Exclude any file or directory with this path')
[CompletionResult]::new('--ignore-directory', '--ignore-directory', [CompletionResultType]::ParameterName, 'Exclude any file or directory with this path')
[CompletionResult]::new('-I', '-I ', [CompletionResultType]::ParameterName, 'Exclude any file or directory with a regex matching that listed in this file, the file entries will be added to the ignore regexs provided by --invert_filter')

View File

@@ -23,8 +23,8 @@ set edit:completion:arg-completer[dust] = {|@words|
cand -T 'Number of threads to use'
cand --threads 'Number of threads to use'
cand --config 'Specify a config file to use'
cand -n 'Number of lines of output to show. (Default is terminal_height - 10)'
cand --number-of-lines 'Number of lines of output to show. (Default is terminal_height - 10)'
cand -n 'Display the ''n'' largest entries. (Default is terminal_height)'
cand --number-of-lines 'Display the ''n'' largest entries. (Default is terminal_height)'
cand -X 'Exclude any file or directory with this path'
cand --ignore-directory 'Exclude any file or directory with this path'
cand -I 'Exclude any file or directory with a regex matching that listed in this file, the file entries will be added to the ignore regexs provided by --invert_filter'

View File

@@ -1,7 +1,7 @@
complete -c dust -s d -l depth -d 'Depth to show' -r
complete -c dust -s T -l threads -d 'Number of threads to use' -r
complete -c dust -l config -d 'Specify a config file to use' -r -F
complete -c dust -s n -l number-of-lines -d 'Number of lines of output to show. (Default is terminal_height - 10)' -r
complete -c dust -s n -l number-of-lines -d 'Display the \'n\' largest entries. (Default is terminal_height)' -r
complete -c dust -s X -l ignore-directory -d 'Exclude any file or directory with this path' -r -F
complete -c dust -s I -l ignore-all-in-file -d 'Exclude any file or directory with a regex matching that listed in this file, the file entries will be added to the ignore regexs provided by --invert_filter' -r -F
complete -c dust -s z -l min-size -d 'Minimum size file to include in output' -r

View File

@@ -25,4 +25,6 @@ skip-total=true
ignore-hidden=true
# print sizes in powers of 1000 (e.g., 1.1G)
output-format="si"
output-format="si"
number-of-lines=5

View File

@@ -9,25 +9,25 @@ Dust \- Like du but more intuitive
Like du but more intuitive
.SH OPTIONS
.TP
\fB\-d\fR, \fB\-\-depth\fR=\fIDEPTH\fR
\fB\-d\fR, \fB\-\-depth\fR \fI<DEPTH>\fR
Depth to show
.TP
\fB\-T\fR, \fB\-\-threads\fR=\fITHREADS\fR
\fB\-T\fR, \fB\-\-threads\fR \fI<THREADS>\fR
Number of threads to use
.TP
\fB\-\-config\fR=\fIFILE\fR
\fB\-\-config\fR \fI<FILE>\fR
Specify a config file to use
.TP
\fB\-n\fR, \fB\-\-number\-of\-lines\fR=\fINUMBER\fR
Number of lines of output to show. (Default is terminal_height \- 10)
\fB\-n\fR, \fB\-\-number\-of\-lines\fR \fI<NUMBER>\fR
Display the \*(Aqn\*(Aq largest entries. (Default is terminal_height)
.TP
\fB\-p\fR, \fB\-\-full\-paths\fR
Subdirectories will not have their path shortened
.TP
\fB\-X\fR, \fB\-\-ignore\-directory\fR=\fIPATH\fR
\fB\-X\fR, \fB\-\-ignore\-directory\fR \fI<PATH>\fR
Exclude any file or directory with this path
.TP
\fB\-I\fR, \fB\-\-ignore\-all\-in\-file\fR=\fIFILE\fR
\fB\-I\fR, \fB\-\-ignore\-all\-in\-file\fR \fI<FILE>\fR
Exclude any file or directory with a regex matching that listed in this file, the file entries will be added to the ignore regexs provided by \-\-invert_filter
.TP
\fB\-L\fR, \fB\-\-dereference\-links\fR
@@ -54,7 +54,7 @@ No percent bars or percentages will be displayed
\fB\-B\fR, \fB\-\-bars\-on\-right\fR
percent bars moved to right side of screen
.TP
\fB\-z\fR, \fB\-\-min\-size\fR=\fIMIN_SIZE\fR
\fB\-z\fR, \fB\-\-min\-size\fR \fI<MIN_SIZE>\fR
Minimum size file to include in output
.TP
\fB\-R\fR, \fB\-\-screen\-reader\fR
@@ -69,16 +69,16 @@ Directory \*(Aqsize\*(Aq is number of child files instead of disk size
\fB\-i\fR, \fB\-\-ignore\-hidden\fR
Do not display hidden files
.TP
\fB\-v\fR, \fB\-\-invert\-filter\fR=\fIREGEX\fR
\fB\-v\fR, \fB\-\-invert\-filter\fR \fI<REGEX>\fR
Exclude filepaths matching this regex. To ignore png files type: \-v "\\.png$"
.TP
\fB\-e\fR, \fB\-\-filter\fR=\fIREGEX\fR
\fB\-e\fR, \fB\-\-filter\fR \fI<REGEX>\fR
Only include filepaths matching this regex. For png files type: \-e "\\.png$"
.TP
\fB\-t\fR, \fB\-\-file\-types\fR
show only these file types
.TP
\fB\-w\fR, \fB\-\-terminal\-width\fR=\fIWIDTH\fR
\fB\-w\fR, \fB\-\-terminal\-width\fR \fI<WIDTH>\fR
Specify width of output overriding the auto detection of terminal width
.TP
\fB\-P\fR, \fB\-\-no\-progress\fR
@@ -93,7 +93,7 @@ Only directories will be displayed
\fB\-F\fR, \fB\-\-only\-file\fR
Only files will be displayed. (Finds your largest files)
.TP
\fB\-o\fR, \fB\-\-output\-format\fR=\fIFORMAT\fR
\fB\-o\fR, \fB\-\-output\-format\fR \fI<FORMAT>\fR
Changes output display size. si will print sizes in powers of 1000. b k m g t kb mb gb tb will print the whole tree in that size
.br
@@ -122,31 +122,31 @@ gb: gigabyte (GB)
tb: terabyte (TB)
.RE
.TP
\fB\-S\fR, \fB\-\-stack\-size\fR=\fISTACK_SIZE\fR
\fB\-S\fR, \fB\-\-stack\-size\fR \fI<STACK_SIZE>\fR
Specify memory to use as stack size \- use if you see: \*(Aqfatal runtime error: stack overflow\*(Aq (default low memory=1048576, high memory=1073741824)
.TP
\fB\-j\fR, \fB\-\-output\-json\fR
Output the directory tree as json to the current directory
.TP
\fB\-M\fR, \fB\-\-mtime\fR=\fIMTIME\fR
\fB\-M\fR, \fB\-\-mtime\fR \fI<MTIME>\fR
+/\-n matches files modified more/less than n days ago , and n matches files modified exactly n days ago, days are rounded down.That is +n => (−∞, curr(n+1)), n => [curr(n+1), currn), and \-n => (𝑐𝑢𝑟𝑟𝑛, +∞)
.TP
\fB\-A\fR, \fB\-\-atime\fR=\fIATIME\fR
\fB\-A\fR, \fB\-\-atime\fR \fI<ATIME>\fR
just like \-mtime, but based on file access time
.TP
\fB\-y\fR, \fB\-\-ctime\fR=\fICTIME\fR
\fB\-y\fR, \fB\-\-ctime\fR \fI<CTIME>\fR
just like \-mtime, but based on file change time
.TP
\fB\-\-files0\-from\fR=\fIFILES0_FROM\fR
\fB\-\-files0\-from\fR \fI<FILES0_FROM>\fR
Read NUL\-terminated paths from FILE (use `\-` for stdin)
.TP
\fB\-\-files\-from\fR=\fIFILES_FROM\fR
\fB\-\-files\-from\fR \fI<FILES_FROM>\fR
Read newline\-terminated paths from FILE (use `\-` for stdin)
.TP
\fB\-\-collapse\fR=\fICOLLAPSE\fR
\fB\-\-collapse\fR \fI<COLLAPSE>\fR
Keep these directories collapsed
.TP
\fB\-m\fR, \fB\-\-filetime\fR=\fIFILETIME\fR
\fB\-m\fR, \fB\-\-filetime\fR \fI<FILETIME>\fR
Directory \*(Aqsize\*(Aq is max filetime of child files instead of disk size. while a/c/m for last accessed/changed/modified time
.br

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 107 KiB

View File

@@ -21,7 +21,7 @@ pub struct Cli {
#[arg(long, value_name("FILE"), value_hint(ValueHint::FilePath))]
pub config: Option<String>,
/// Number of lines of output to show. (Default is terminal_height - 10)
/// Display the 'n' largest entries. (Default is terminal_height)
#[arg(short, long, value_name("NUMBER"))]
pub number_of_lines: Option<usize>,

View File

@@ -244,7 +244,7 @@ fn convert_min_size(input: &str) -> Option<usize> {
}
}
fn get_config_locations(base: &Path) -> Vec<PathBuf> {
fn get_config_locations(base: PathBuf) -> Vec<PathBuf> {
vec![
base.join(".dust.toml"),
base.join(".config").join("dust").join("config.toml"),
@@ -267,12 +267,12 @@ pub fn get_config(conf_path: Option<&String>) -> Config {
}
}
None => {
if let Some(home) = directories::BaseDirs::new() {
for path in get_config_locations(home.home_dir()) {
if path.exists() {
if let Ok(config) = Config::from_config_file(&path) {
return config;
}
if let Some(home) = std::env::home_dir() {
for path in get_config_locations(home) {
if path.exists()
&& let Ok(config) = Config::from_config_file(&path)
{
return config;
}
}
}

View File

@@ -69,12 +69,11 @@ pub fn walk_it(dirs: HashSet<PathBuf>, walk_data: &WalkData) -> Vec<Node> {
// Remove files which have the same inode, we don't want to double count them.
fn clean_inodes(x: Node, inodes: &mut HashSet<(u64, u64)>, walk_data: &WalkData) -> Option<Node> {
if !walk_data.use_apparent_size {
if let Some(id) = x.inode_device {
if !inodes.insert(id) {
return None;
}
}
if !walk_data.use_apparent_size
&& let Some(id) = x.inode_device
&& !inodes.insert(id)
{
return None;
}
// Sort Nodes so iteration order is predictable
@@ -156,10 +155,10 @@ fn ignore_file(entry: &DirEntry, walk_data: &WalkData) -> bool {
if !walk_data.allowed_filesystems.is_empty() {
let size_inode_device = get_metadata(entry.path(), false, follow_links);
if let Some((_size, Some((_id, dev)), _gunk)) = size_inode_device {
if !walk_data.allowed_filesystems.contains(&dev) {
return true;
}
if let Some((_size, Some((_id, dev)), _gunk)) = size_inode_device
&& !walk_data.allowed_filesystems.contains(&dev)
{
return true;
}
}
if walk_data.filter_accessed_time.is_some()
@@ -167,20 +166,19 @@ fn ignore_file(entry: &DirEntry, walk_data: &WalkData) -> bool {
|| walk_data.filter_changed_time.is_some()
{
let size_inode_device = get_metadata(entry.path(), false, follow_links);
if let Some((_, _, (modified_time, accessed_time, changed_time))) = size_inode_device {
if entry.path().is_file()
&& [
(&walk_data.filter_modified_time, modified_time),
(&walk_data.filter_accessed_time, accessed_time),
(&walk_data.filter_changed_time, changed_time),
]
.iter()
.any(|(filter_time, actual_time)| {
is_filtered_out_due_to_file_time(filter_time, *actual_time)
})
{
return true;
}
if let Some((_, _, (modified_time, accessed_time, changed_time))) = size_inode_device
&& entry.path().is_file()
&& [
(&walk_data.filter_modified_time, modified_time),
(&walk_data.filter_accessed_time, accessed_time),
(&walk_data.filter_changed_time, changed_time),
]
.iter()
.any(|(filter_time, actual_time)| {
is_filtered_out_due_to_file_time(filter_time, *actual_time)
})
{
return true;
}
}
@@ -222,32 +220,30 @@ fn walk(dir: PathBuf, walk_data: &WalkData, depth: usize) -> Option<Node> {
// return walk(entry.path(), walk_data, depth)
if !ignore_file(entry, walk_data) {
if let Ok(data) = entry.file_type() {
if data.is_dir()
|| (walk_data.follow_links && data.is_symlink())
{
return walk(entry.path(), walk_data, depth + 1);
}
let node = build_node(
entry.path(),
vec![],
data.is_symlink(),
data.is_file(),
depth,
walk_data,
);
prog_data.num_files.fetch_add(1, ORDERING);
if let Some(ref file) = node {
prog_data
.total_file_size
.fetch_add(file.size, ORDERING);
}
return node;
if !ignore_file(entry, walk_data)
&& let Ok(data) = entry.file_type()
{
if data.is_dir()
|| (walk_data.follow_links && data.is_symlink())
{
return walk(entry.path(), walk_data, depth + 1);
}
let node = build_node(
entry.path(),
vec![],
data.is_symlink(),
data.is_file(),
depth,
walk_data,
);
prog_data.num_files.fetch_add(1, ORDERING);
if let Some(ref file) = node {
prog_data.total_file_size.fetch_add(file.size, ORDERING);
}
return node;
}
}
Err(ref failed) => {

View File

@@ -1,8 +1,8 @@
use crate::display_node::DisplayNode;
use crate::node::FileTime;
use ansi_term::Colour::Red;
use lscolors::{LsColors, Style};
use nu_ansi_term::Color::Red;
use unicode_width::UnicodeWidthStr;
@@ -403,7 +403,7 @@ fn get_pretty_name(
.ls_colors
.style_for_path_with_metadata(&node.name, meta_result.as_ref().ok());
let ansi_style = directory_color
.map(Style::to_ansi_term_style)
.map(Style::to_nu_ansi_term_style)
.unwrap_or_default();
let out = ansi_style.paint(name_and_padding);
format!("{out}")
@@ -439,6 +439,9 @@ pub fn get_number_format(output_str: &str) -> Option<(u64, char)> {
}
pub fn human_readable_number(size: u64, output_str: &str) -> String {
if output_str == "count" {
return size.to_string();
};
match get_number_format(output_str) {
Some((x, u)) => {
format!("{}{}", (size / x), u)
@@ -539,6 +542,13 @@ mod tests {
assert_eq!(s, "short 3 4.0K 100%");
}
#[test]
fn test_machine_readable_filecount() {
assert_eq!(human_readable_number(1, "count"), "1");
assert_eq!(human_readable_number(1000, "count"), "1000");
assert_eq!(human_readable_number(1024, "count"), "1024");
}
#[test]
fn test_human_readable_number() {
assert_eq!(human_readable_number(1, ""), "1B");

View File

@@ -29,7 +29,7 @@ use std::panic;
use std::process;
use std::sync::Arc;
use std::sync::Mutex;
use sysinfo::{System, SystemExt};
use sysinfo::System;
use utils::canonicalize_absolute_path;
use self::display::draw_it;
@@ -69,7 +69,7 @@ fn should_init_color(no_color: bool, force_color: bool) -> bool {
{
// Required for windows 10
// Fails to resolve for windows 8 so disable color
match ansi_term::enable_ansi_support() {
match nu_ansi_term::enable_ansi_support() {
Ok(_) => true,
Err(_) => {
eprintln!("This version of Windows does not support ANSI colors");
@@ -319,7 +319,11 @@ fn print_output(
if config.get_output_json(&options) {
OUTPUT_TYPE.with(|wrapped| {
wrapped.replace(output_format);
if by_filecount {
wrapped.replace("count".to_string());
} else {
wrapped.replace(output_format);
}
});
println!("{}", serde_json::to_string(&tree).unwrap());
} else {
@@ -436,10 +440,10 @@ fn init_rayon(stack: &Option<usize>, threads: &Option<usize>) -> rayon::ThreadPo
None
} else {
let large_stack = usize::pow(1024, 3);
let mut s = System::new();
s.refresh_memory();
let mut sys = System::new_all();
sys.refresh_memory();
// Larger stack size if possible to handle cases with lots of nested directories
let available = s.available_memory();
let available = sys.available_memory();
if available > (large_stack * threads.unwrap_or(1)).try_into().unwrap() {
Some(large_stack)
} else {

View File

@@ -1,4 +1,4 @@
use assert_cmd::Command;
use assert_cmd::{Command, cargo_bin_cmd};
use std::ffi::OsStr;
use std::process::Output;
use std::sync::Once;
@@ -61,9 +61,11 @@ fn initialize() {
fn run_cmd<T: AsRef<OsStr>>(command_args: &[T]) -> Output {
initialize();
let mut to_run = &mut Command::cargo_bin("dust").unwrap();
let mut to_run = cargo_bin_cmd!("dust");
// Hide progress bar
to_run.arg("-P");
for p in command_args {
to_run = to_run.arg(p);
to_run.arg(p);
}
to_run.unwrap()
}

View File

@@ -1,4 +1,4 @@
use assert_cmd::Command;
use assert_cmd::cargo_bin_cmd;
use std::ffi::OsStr;
use std::str;
@@ -9,17 +9,16 @@ use std::str;
*/
fn build_command<T: AsRef<OsStr>>(command_args: Vec<T>) -> String {
let mut cmd = &mut Command::cargo_bin("dust").unwrap();
let mut cmd = cargo_bin_cmd!("dust");
// Hide progress bar
cmd = cmd.arg("-P");
cmd.arg("-P");
for p in command_args {
cmd = cmd.arg(p);
cmd.arg(p);
}
let finished = &cmd.unwrap();
let stderr = str::from_utf8(&finished.stderr).unwrap();
assert_eq!(stderr, "");
assert_eq!(str::from_utf8(&finished.stderr).unwrap(), "");
str::from_utf8(&finished.stdout).unwrap().into()
}
@@ -106,21 +105,27 @@ pub fn test_ignore_all_in_file() {
#[test]
pub fn test_files_from_flag_file() {
let output = build_command(vec!["--files-from", "tests/test_dir_files_from/files_from.txt"]);
let output = build_command(vec![
"--files-from",
"tests/test_dir_files_from/files_from.txt",
]);
assert!(output.contains("a_file"));
assert!(output.contains("hello_file"));
}
#[test]
pub fn test_files0_from_flag_file() {
let output = build_command(vec!["--files0-from", "tests/test_dir_files_from/files0_from.txt"]);
let output = build_command(vec![
"--files0-from",
"tests/test_dir_files_from/files0_from.txt",
]);
assert!(output.contains("a_file"));
assert!(output.contains("hello_file"));
}
#[test]
pub fn test_files_from_flag_stdin() {
let mut cmd = Command::cargo_bin("dust").unwrap();
let mut cmd = cargo_bin_cmd!("dust");
cmd.arg("-P").arg("--files-from").arg("-");
let input = b"tests/test_dir_files_from/a_file\ntests/test_dir_files_from/hello_file\n";
cmd.write_stdin(input.as_ref());
@@ -134,7 +139,7 @@ pub fn test_files_from_flag_stdin() {
#[test]
pub fn test_files0_from_flag_stdin() {
let mut cmd = Command::cargo_bin("dust").unwrap();
let mut cmd = cargo_bin_cmd!("dust");
cmd.arg("-P").arg("--files0-from").arg("-");
let input = b"tests/test_dir_files_from/a_file\0tests/test_dir_files_from/hello_file\0";
cmd.write_stdin(input.as_ref());
@@ -148,7 +153,7 @@ pub fn test_files0_from_flag_stdin() {
#[test]
pub fn test_with_bad_param() {
let mut cmd = Command::cargo_bin("dust").unwrap();
let mut cmd = cargo_bin_cmd!("dust");
cmd.arg("-P").arg("bad_place");
let output_error = cmd.unwrap_err();
let result = output_error.as_output().unwrap();

View File

@@ -1,4 +1,4 @@
use assert_cmd::Command;
use assert_cmd::{Command, cargo_bin_cmd};
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;
@@ -44,7 +44,7 @@ pub fn test_soft_sym_link() {
let b = format!(" ┌── {}", file_path_s);
let a = format!("─┴ {}", dir_s);
let mut cmd = Command::cargo_bin("dust").unwrap();
let mut cmd = cargo_bin_cmd!("dust");
// Mac test runners create long filenames in tmp directories
let output = cmd
.args(["-p", "-c", "-s", "-w", "999", dir_s])
@@ -72,7 +72,7 @@ pub fn test_hard_sym_link() {
let file_output = format!(" ┌── {}", file_path_s);
let dirs_output = format!("─┴ {}", dir_s);
let mut cmd = Command::cargo_bin("dust").unwrap();
let mut cmd = cargo_bin_cmd!("dust");
// Mac test runners create long filenames in tmp directories
let output = cmd.args(["-p", "-c", "-w", "999", dir_s]).unwrap().stdout;
@@ -96,7 +96,7 @@ pub fn test_hard_sym_link_no_dup_multi_arg() {
let link_name = dir_link.path().join("the_link");
let link_name_s = link_it(link_name, file_path_s, false);
let mut cmd = Command::cargo_bin("dust").unwrap();
let mut cmd = cargo_bin_cmd!("dust");
// Mac test runners create long filenames in tmp directories
let output = cmd
@@ -123,7 +123,7 @@ pub fn test_recursive_sym_link() {
let a = format!("─┬ {}", dir_s);
let b = format!(" └── {}", link_name_s);
let mut cmd = Command::cargo_bin("dust").unwrap();
let mut cmd = cargo_bin_cmd!("dust");
let output = cmd
.arg("-p")
.arg("-c")