Compare commits

..

38 Commits

Author SHA1 Message Date
andy.boot
352c0f7d90 Increment version number 2020-01-19 09:32:49 +00:00
andy.boot
842a8ec673 Clean up clippy warnings 2020-01-19 09:32:35 +00:00
andy.boot
d97edba041 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.
2020-01-19 09:23:13 +00:00
andy boot
f64e0094f1 Merge pull request #53 from bootandy/single_cpu
Fix dust for single core machines
2020-01-18 23:06:28 +00:00
andy.boot
3d2477e554 Allow dust to run on single core machines
Force dust to use 2 threads if there is only 1 cpu
JWalk breaks if it tries to run on a single cpu

https://github.com/jessegrosjean/jwalk/issues/15

This is a hack because I can't figure out how to fix JWalk.
This code and the num_cpu crate can be removed when the bug is fixed

Also I have conflated cpus with cores while describing this issue. It is
very difficult to test as I don't have a single core machine.
2020-01-18 22:04:08 +00:00
andy.boot
350d695f7c Add num_cpus as Cargo dependency
Will be used to detect single core computers which crash Jwalk
2020-01-18 21:57:11 +00:00
andy boot
f8b8b8a788 Merge pull request #51 from bootandy/ab-exclude
Support excluding filesystems with -x
2020-01-18 21:54:41 +00:00
andy.boot
b9c27f9838 get_filesystem returns Result instead of option
Removes unwrap and returns a Result instead of panicing if an invalid
path is given.
Previously if the flag: '-x' was provided with an argument of an
invalid directory the code would crash here
2020-01-16 23:50:56 +00:00
andy.boot
5541df6a73 Refactor code
Reduce complexity of examine_dir.

No logic changes
2020-01-15 20:10:33 +00:00
andy.boot
bdc3d404ef Support excluding filesystems with -x
https://github.com/bootandy/dust/issues/50

Add optional -x flag to limit search to the current filesystem.

Add (untested) support for windows for the equivalent of inode and
device.
2020-01-15 19:51:16 +00:00
andy boot
f395a7d768 Merge pull request #49 from bootandy/ab-upgrade
Upgrade libraries. Fix assert_cli
2019-12-30 22:07:04 +00:00
andy.boot
a36eec6cae Increment version number 2019-12-30 21:40:30 +00:00
Adam Lesperance
38938e005e Fix colors on windows
* Initialize ansi_term if we're on windows
* Silence build warning on non-unix targets
* Update ansi-term which has windows specific fixes (and assert_cli while I'm at it)
2019-12-30 21:36:49 +00:00
andy.boot
da61b15715 Upgrade libraries. Fix assert_cli
New assert_cli library requires we cast the param passed to 'is()' as
it can no longer cast implicitly. I am guessing this is because it is
due to confusion between whether to cast to u8 or str
2019-12-30 21:23:53 +00:00
andy boot
0b22d0a977 Merge pull request #47 from bootandy/ab-bug-fix
Ab bug fix
2019-12-30 21:12:37 +00:00
andy.boot
356d14ac0f Hack fix around JWalk behaviour.
Jwalk returns '/' as a child of the current node which breaks things.
https://github.com/jessegrosjean/jwalk/issues/13
2019-12-23 15:51:12 +00:00
andy.boot
311bc45388 Verify that '/' is parent of everything
Bug could occur when run with '/' as it wasn't considered the parent of
'/usr' due to having the same number of '/'s in the name
2019-12-23 15:50:01 +00:00
andy.boot
ef66fb3938 Remove useless sort
The data coming in is already sorted. We should not need to sort it a
second time
2019-12-23 15:49:26 +00:00
andy.boot
b934445e04 Pin jwalk to dependency version
https://github.com/jessegrosjean/jwalk/issues/13
Having raised the above issue I don't want it fixed in a minor version
as I have added a work around
2019-12-23 15:48:38 +00:00
andy boot
a6839c020f Merge pull request #43 from bootandy/no_color
Add flag for No color, refactor tests
2019-12-08 23:50:58 +00:00
andy.boot
7e47d5b47a Increment version number 2019-12-08 23:36:48 +00:00
andy.boot
6a65570f3f Refactor tests
Make use of the 'is' more to test the entire output.

Add test for no_color mode.

Replace several calls to format_string with calls that build a string
directly. I feel format_string is becoming unweildly and this simplfies
the tests
2019-12-08 23:34:28 +00:00
andy.boot
a4ca78dbe4 Add option flag for no colors
https://github.com/bootandy/dust/issues/37
2019-12-08 14:46:45 +00:00
andy boot
bfbe8a57ae Merge pull request #42 from bootandy/cleanup
Cleanup code & fix issue
2019-12-07 09:16:51 +00:00
andy.boot
b4b73e45f3 Cargo update 2019-12-05 21:51:04 +00:00
andy.boot
78119aba0f Mark function as ignored by clippy
We don't want to collapse this if - it is easier to reason about this
way
2019-12-05 21:50:26 +00:00
andy.boot
5535478fe8 Fix substring bug
When one directory was a substring of another the directory would appear
as a subdirectory instead of a sibling

Fixed originally by this: 6e03dd77e6
Broken by this: db6c8a019d

Added integration test as this has bitten me before
2019-12-05 21:35:15 +00:00
andy.boot
7ba91a4a22 Rename variable
cpu -> threads. threads more accurately represents the number of threads
we will start to run
2019-12-04 20:49:45 +00:00
andy boot
79416fd5fc Merge pull request #40 from AdminXVII/parallel-walk
Use jwalk instead of walkdir: parallel walking for performance boost
2019-12-04 20:45:25 +00:00
Xavier L'Heureux
b66523cff3 Apply clippy lints 2019-12-03 18:34:47 -05:00
Xavier L'Heureux
19a41aa382 Add CLI option for the number of threads to spawn 2019-12-03 18:27:02 -05:00
Xavier L'Heureux
62ac9b623a Make sure to count the hidden directories 2019-11-26 08:31:52 -05:00
Xavier L'Heureux
bf28d42483 Update Performance section of README 2019-11-26 08:31:52 -05:00
Xavier L'Heureux
f8ce6c97bf Use more rusty patterns and preallocate enough space 2019-11-26 08:31:52 -05:00
Xavier L'Heureux
86b3cccaf6 perf(IO): use parallel walkdir (jwalk) for super faster traversal 2019-11-26 08:31:52 -05:00
andy boot
3c920431fa Merge pull request #38 from lespea/update_deps
Latest deps
2019-11-25 23:32:09 +00:00
Adam Lesperance
a1ece05af5 Testing deps should only be used when testing 2019-11-21 00:05:53 -06:00
Adam Lesperance
cef2c588b7 Latest deps 2019-11-20 23:05:57 -06:00
11 changed files with 693 additions and 481 deletions

455
Cargo.lock generated
View File

@@ -9,29 +9,33 @@ dependencies = [
]
[[package]]
name = "approx"
version = "0.1.1"
name = "ansi_term"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "assert_cli"
version = "0.5.4"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"colored 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"colored 1.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
"difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"environment 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
"skeptic 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "atty"
version = "0.2.13"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -42,12 +46,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "backtrace"
version = "0.3.40"
version = "0.3.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -56,8 +60,8 @@ name = "backtrace-sys"
version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -65,11 +69,6 @@ name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bytecount"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "c2-chacha"
version = "0.2.3"
@@ -78,21 +77,9 @@ dependencies = [
"ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cargo_metadata"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cc"
version = "1.0.46"
version = "1.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -100,102 +87,171 @@ name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cgmath"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"approx 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "clap"
version = "2.33.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "colored"
version = "1.8.0"
version = "1.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam-channel"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam-deque"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam-epoch"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam-queue"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam-utils"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winconsole 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "difference"
version = "1.0.0"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "du-dust"
version = "0.4.1"
version = "0.4.4"
dependencies = [
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"assert_cli 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
"ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
"assert_cli 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
"jwalk 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "either"
version = "1.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "environment"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "error-chain"
version = "0.11.0"
name = "failure"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)",
"backtrace 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)",
"failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "error-chain"
version = "0.12.1"
name = "failure_derive"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)",
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
"synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fuchsia-cprng"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "getrandom"
version = "0.1.13"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "glob"
version = "0.2.11"
name = "hermit-abi"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "itoa"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "jwalk"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
@@ -203,23 +259,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
version = "0.2.65"
version = "0.2.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "num-traits"
version = "0.1.43"
name = "memoffset"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-traits"
version = "0.2.8"
name = "num_cpus"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -229,47 +286,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "proc-macro2"
version = "1.0.6"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "pulldown-cmark"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "quote"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand"
version = "0.4.6"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -284,25 +321,12 @@ dependencies = [
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_core"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_core"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -314,11 +338,25 @@ dependencies = [
]
[[package]]
name = "rdrand"
version = "0.4.0"
name = "rayon"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rayon-core"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -334,28 +372,28 @@ dependencies = [
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rgb"
version = "0.8.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rustc-demangle"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rustc_version"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ryu"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "same-file"
version = "1.0.5"
name = "scopeguard"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "semver"
@@ -363,7 +401,6 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -373,42 +410,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
version = "1.0.102"
version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde_derive"
version = "1.0.102"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_json"
version = "1.0.41"
version = "1.0.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "skeptic"
version = "0.13.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytecount 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cargo_metadata 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"pulldown-cmark 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -418,21 +430,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "syn"
version = "1.0.7"
version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tempdir"
version = "0.3.7"
name = "synstructure"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -441,8 +455,8 @@ version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
"remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -453,12 +467,12 @@ name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-width"
version = "0.1.6"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -471,24 +485,9 @@ name = "vec_map"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "version_check"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "walkdir"
version = "2.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wasi"
version = "0.7.0"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -505,96 +504,72 @@ name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-util"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winconsole"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cgmath 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rgb 0.8.14 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[metadata]
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
"checksum approx 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08abcc3b4e9339e33a3d0a5ed15d84a687350c05689d825e0f6655eef9e76a94"
"checksum assert_cli 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "72342c21057a3cb5f7c2d849bf7999a83795434dd36d74fa8c24680581bd1930"
"checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90"
"checksum ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
"checksum assert_cli 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a29ab7c0ed62970beb0534d637a8688842506d0ff9157de83286dacd065c8149"
"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
"checksum backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)" = "924c76597f0d9ca25d762c25a4d369d51267536465dc5064bdf0eb073ed477ea"
"checksum backtrace 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b4b1549d804b6c73f4817df2ba073709e96e426f12987127c48e6745568c350b"
"checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491"
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
"checksum bytecount 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b92204551573580e078dc80017f36a213eb77a0450e4ddd8cfa0f3f2d1f0178f"
"checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb"
"checksum cargo_metadata 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e5d1b4d380e1bab994591a24c2bdd1b054f64b60bef483a8c598c7c345bc3bbe"
"checksum cc 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)" = "0213d356d3c4ea2c18c40b037c3be23cd639825c18f25ee670ac7813beeef99c"
"checksum cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd"
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
"checksum cgmath 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "64a4b57c8f4e3a2e9ac07e0f6abc9c24b6fc9e1b54c3478cfb598f3d0023e51c"
"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
"checksum colored 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6cdb90b60f2927f8d76139c72dbde7e10c3a2bc47c8594c9c7a66529f2687c03"
"checksum difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3304d19798a8e067e48d8e69b2c37f0b5e9b4e462504ad9e27e9f3fce02bba8"
"checksum colored 1.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8815e2ab78f3a59928fc32e141fbeece88320a240e43f47b2fd64ea3a88a5b3d"
"checksum crossbeam 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "69323bff1fb41c635347b8ead484a5ca6c3f11914d784170b158d8449ab07f8e"
"checksum crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "acec9a3b0b3559f15aee4f90746c4e5e293b701c0f7d3925d24e01645267b68c"
"checksum crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3aa945d63861bfe624b55d153a39684da1e8c0bc8fba932f7ee3a3c16cea3ca"
"checksum crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac"
"checksum crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db"
"checksum crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4"
"checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
"checksum environment 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f4b14e20978669064c33b4c1e0fb4083412e40fe56cbea2eae80fd7591503ee"
"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
"checksum error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ab49e9dcb602294bc42f9a7dfc9bc6e936fca4418ea300dbfb84fe16de0b7d9"
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
"checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407"
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
"checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9"
"checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08"
"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
"checksum hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772"
"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
"checksum jwalk 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2b3dbf0a8f61baee43a2918ff50ac6a2d3b2c105bc08ed53bc298779f1263409"
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
"checksum libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "1a31a0627fdf1f6a39ec0dd577e101440b7db22672c0901fe00a9a6fbb5c24e8"
"checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
"checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9"
"checksum num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6"
"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
"checksum proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27"
"checksum pulldown-cmark 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eef52fac62d0ea7b9b4dc7da092aa64ea7ec3d90af6679422d3d7e0e14b6ee15"
"checksum proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548"
"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
"checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
"checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412"
"checksum rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853"
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
"checksum rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098"
"checksum rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9"
"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
"checksum rgb 0.8.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2089e4031214d129e201f8c3c8c2fe97cd7322478a0d1cdf78e7029b0042efdb"
"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
"checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8"
"checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421"
"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d"
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4b39bd9b0b087684013a792c59e3e07a46a01d2322518d8a1104641a0b1be0"
"checksum serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)" = "ca13fc1a832f793322228923fbb3aba9f3f44444898f835d31ad1b74fa0a2bf8"
"checksum serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "2f72eb2a68a7dc3f9a691bfda9305a1c017a6215e5a4545c258500d2099a37c2"
"checksum skeptic 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fb8ed853fdc19ce09752d63f3a2e5b5158aeb261520cd75eb618bd60305165"
"checksum serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449"
"checksum serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)" = "48c575e0cc52bdd09b47f330f646cf59afc586e9c4e3ccd6fc1f625b8ea1dad7"
"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
"checksum syn 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0e7bedb3320d0f3035594b0b723c8a28d7d336a3eda3881db79e61d676fb644c"
"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
"checksum syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1e4ff033220a41d1a57d8125eab57bf5263783dfdcc18688b1dacc6ce9651ef8"
"checksum synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545"
"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
"checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20"
"checksum unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479"
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
"checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e"
"checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d"
"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
"checksum winconsole 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ef84b96d10db72dd980056666d7f1e7663ce93d82fa33b63e71c966f4cf5032"

View File

@@ -1,7 +1,7 @@
[package]
name = "du-dust"
description = "A more intuitive version of du"
version = "0.4.1"
version = "0.4.4"
authors = ["bootandy <bootandy@gmail.com>", "nebkor <code@ardent.nebcorp.com>"]
edition = "2018"
@@ -21,9 +21,11 @@ name = "dust"
path = "src/main.rs"
[dependencies]
ansi_term = "=0.11"
ansi_term = "=0.12"
clap = "=2.33"
assert_cli = "=0.5"
tempfile = "=3"
walkdir = "=2"
jwalk = "0.4.0"
num_cpus = "1.12"
[dev-dependencies]
assert_cli = "=0.6"
tempfile = "=3"

View File

@@ -63,7 +63,7 @@ djin:git/dust> dust
## Performance
Dust is currently about 4 times slower than du.
Dust uses a parallel fetching implementation that greatly improves performance for directory trees with reasonable amount of files (read more than 20) compared to du. This can be as much as 7x faster than du on a clean cache.
## Alternatives

View File

@@ -9,6 +9,7 @@ static UNITS: [char; 4] = ['T', 'G', 'M', 'K'];
pub struct DisplayData {
pub short_paths: bool,
pub is_reversed: bool,
pub colors_on: bool,
}
impl DisplayData {
@@ -20,6 +21,7 @@ impl DisplayData {
}
}
#[allow(clippy::collapsible_if)]
fn get_tree_chars(
&self,
num_siblings: u64,
@@ -61,34 +63,39 @@ impl DisplayData {
}
}
fn get_children_from_node(&self, node: Node) -> impl Iterator<Item = Box<Node>> {
fn get_children_from_node(&self, node: Node) -> impl Iterator<Item = Node> {
if self.is_reversed {
let n: Vec<Box<Node>> = node.children.into_iter().rev().map(|a| a).collect();
return n.into_iter();
let n: Vec<Node> = node.children.into_iter().rev().map(|a| a).collect();
n.into_iter()
} else {
return node.children.into_iter();
node.children.into_iter()
}
}
}
pub fn draw_it(permissions: bool, use_full_path: bool, is_reversed: bool, root_node: Node) {
pub fn draw_it(
permissions: bool,
use_full_path: bool,
is_reversed: bool,
no_colors: bool,
root_node: Node,
) {
if !permissions {
eprintln!("Did not have permissions for all directories");
}
let display_data = DisplayData {
short_paths: !use_full_path,
is_reversed,
colors_on: !no_colors,
};
for c in display_data.get_children_from_node(root_node) {
let first_tree_chars = display_data.get_first_chars();
display_node(*c, true, first_tree_chars, &display_data)
display_node(c, true, first_tree_chars, &display_data)
}
}
fn display_node(node: Node, is_biggest: bool, indent: &str, display_data: &DisplayData) {
let short = display_data.short_paths;
let mut num_siblings = node.children.len() as u64;
let max_sibling = num_siblings;
let new_indent = clean_indentation_string(indent);
@@ -96,19 +103,19 @@ fn display_node(node: Node, is_biggest: bool, indent: &str, display_data: &Displ
let size = node.size;
if !display_data.is_reversed {
print_this_node(&*name, size, is_biggest, short, indent);
print_this_node(&*name, size, is_biggest, display_data, indent);
}
for c in display_data.get_children_from_node(node) {
num_siblings -= 1;
let chars = display_data.get_tree_chars(num_siblings, max_sibling, c.children.len() > 0);
let chars = display_data.get_tree_chars(num_siblings, max_sibling, !c.children.is_empty());
let is_biggest = display_data.is_biggest(num_siblings, max_sibling);
let full_indent = new_indent.clone() + chars;
display_node(*c, is_biggest, &*full_indent, display_data)
display_node(c, is_biggest, &*full_indent, display_data)
}
if display_data.is_reversed {
print_this_node(&*name, size, is_biggest, short, indent);
print_this_node(&*name, size, is_biggest, display_data, indent);
}
}
@@ -129,23 +136,29 @@ fn clean_indentation_string(s: &str) -> String {
is
}
fn print_this_node(name: &str, size: u64, is_biggest: bool, short_paths: bool, indentation: &str) {
fn print_this_node(
name: &str,
size: u64,
is_biggest: bool,
display_data: &DisplayData,
indentation: &str,
) {
let pretty_size = format!("{:>5}", human_readable_number(size),);
println!(
"{}",
format_string(name, is_biggest, short_paths, &*pretty_size, indentation)
format_string(name, is_biggest, display_data, &*pretty_size, indentation)
)
}
pub fn format_string(
dir_name: &str,
is_biggest: bool,
short_paths: bool,
display_data: &DisplayData,
size: &str,
indentation: &str,
) -> String {
let printable_name = {
if short_paths {
if display_data.short_paths {
dir_name.split('/').last().unwrap_or(dir_name)
} else {
dir_name
@@ -153,7 +166,7 @@ pub fn format_string(
};
format!(
"{} {} {}",
if is_biggest {
if is_biggest && display_data.colors_on {
Fixed(196).paint(size)
} else {
Style::new().paint(size)

View File

@@ -1,9 +1,8 @@
#[macro_use]
extern crate clap;
extern crate assert_cli;
extern crate walkdir;
use self::display::draw_it;
use crate::utils::is_a_parent_of;
use clap::{App, AppSettings, Arg};
use utils::{find_big_ones, get_dir_tree, simplify_dir_names, sort, trim_deep_ones, Node};
@@ -12,7 +11,16 @@ mod utils;
static DEFAULT_NUMBER_OF_LINES: usize = 20;
#[cfg(windows)]
fn init_color() {
ansi_term::enable_ansi_support().expect("Couldn't enable color support");
}
#[cfg(not(windows))]
fn init_color() {}
fn main() {
init_color();
let def_num_str = DEFAULT_NUMBER_OF_LINES.to_string();
let options = App::new("Dust")
.about("Like du but more intuitive")
@@ -25,6 +33,13 @@ fn main() {
.help("Depth to show")
.takes_value(true),
)
.arg(
Arg::with_name("threads")
.short("t")
.long("threads")
.help("Number of threads to spawn simultaneously")
.takes_value(true),
)
.arg(
Arg::with_name("number_of_lines")
.short("n")
@@ -39,6 +54,19 @@ 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")
.long("limit-filesystem")
.help("Only count the files and directories in the same filesystem as the supplied directory"),
)
.arg(
Arg::with_name("display_apparent_size")
.short("s")
@@ -51,6 +79,12 @@ fn main() {
.long("reverse")
.help("If applied tree will be printed upside down (biggest lowest)"),
)
.arg(
Arg::with_name("no_colors")
.short("c")
.long("no_colors")
.help("If applied no colors will be printed (normally largest directories are marked in red"),
)
.arg(Arg::with_name("inputs").multiple(true))
.get_matches();
@@ -69,29 +103,48 @@ fn main() {
}
};
let depth = {
if options.is_present("depth") {
match value_t!(options.value_of("depth"), u64) {
Ok(v) => Some(v + 1),
Err(_) => {
eprintln!("Ignoring bad value for depth");
None
}
}
let temp_threads = options.value_of("threads").and_then(|threads| {
threads
.parse::<usize>()
.map_err(|_| eprintln!("Ignoring bad value for threads: {:?}", threads))
.ok()
});
// Bug in JWalk
// https://github.com/jessegrosjean/jwalk/issues/15
// We force it to use 2 threads if there is only 1 cpu
// as JWalk breaks if it tries to run on a single cpu
let threads = {
if temp_threads.is_none() && num_cpus::get() == 1 {
Some(2)
} else {
None
temp_threads
}
};
let depth = options.value_of("depth").and_then(|depth| {
depth
.parse::<u64>()
.map(|v| v + 1)
.map_err(|_| eprintln!("Ignoring bad value for depth"))
.ok()
});
if options.is_present("depth") && number_of_lines != DEFAULT_NUMBER_OF_LINES {
eprintln!("Use either -n or -d. Not both");
return;
}
let use_apparent_size = options.is_present("display_apparent_size");
let use_full_path = options.is_present("display_full_paths");
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, use_apparent_size);
let (permissions, nodes) = get_dir_tree(
&simplified_dirs,
ignore_directory,
use_apparent_size,
limit_filesystem,
threads,
);
let sorted_data = sort(nodes);
let biggest_ones = {
match depth {
@@ -100,31 +153,27 @@ fn main() {
}
};
let tree = build_tree(biggest_ones, depth);
//println!("{:?}", tree);
draw_it(
permissions,
use_full_path,
options.is_present("display_full_paths"),
options.is_present("reverse"),
options.is_present("no_colors"),
tree,
);
}
fn build_tree(biggest_ones: Vec<(String, u64)>, depth: Option<u64>) -> Node {
let mut top_parent = Node {
name: "".to_string(),
size: 0,
children: vec![],
};
let mut top_parent = Node::default();
// assume sorted order
for b in biggest_ones {
let n = Node {
name: b.0,
size: b.1,
children: vec![],
children: Vec::default(),
};
recursively_build_tree(&mut top_parent, n, depth)
recursively_build_tree(&mut top_parent, n, depth);
}
top_parent
}
@@ -135,13 +184,15 @@ fn recursively_build_tree(parent_node: &mut Node, new_node: Node, depth: Option<
Some(0) => return,
Some(d) => Some(d - 1),
};
for c in parent_node.children.iter_mut() {
if new_node.name.starts_with(&c.name) {
return recursively_build_tree(&mut *c, new_node, new_depth);
}
if let Some(c) = parent_node
.children
.iter_mut()
.find(|c| is_a_parent_of(&c.name, &new_node.name))
{
recursively_build_tree(c, new_node, new_depth);
} else {
parent_node.children.push(new_node);
}
let temp = Box::<Node>::new(new_node);
parent_node.children.push(temp);
}
#[cfg(test)]

1
src/test_dir2/dir/hello Normal file
View File

@@ -0,0 +1 @@
hello

View File

@@ -0,0 +1 @@
hello

View File

@@ -0,0 +1 @@
hello

View File

@@ -1,21 +1,21 @@
extern crate ansi_term;
extern crate tempfile;
use self::tempfile::Builder;
use self::tempfile::TempDir;
use super::*;
use crate::display::DisplayData;
use display::format_string;
use std::fs::File;
use std::io::Write;
use std::panic;
use std::path::PathBuf;
use std::process::Command;
use tempfile::Builder;
use tempfile::TempDir;
#[test]
pub fn test_main() {
assert_cli::Assert::main_binary()
.with_args(&["src/test_dir"])
.stdout()
.is(main_output(true))
.is(main_output(true).as_str())
.unwrap();
}
@@ -24,7 +24,7 @@ pub fn test_main_long_paths() {
assert_cli::Assert::main_binary()
.with_args(&["-p", "src/test_dir"])
.stdout()
.is(main_output(false))
.is(main_output(false).as_str())
.unwrap();
}
@@ -33,79 +33,95 @@ pub fn test_main_multi_arg() {
assert_cli::Assert::main_binary()
.with_args(&["src/test_dir/many/", "src/test_dir/", "src/test_dir"])
.stdout()
.is(main_output(true))
.is(main_output(true).as_str())
.unwrap();
}
#[cfg(target_os = "macos")]
fn main_output(short_paths: bool) -> String {
let d = DisplayData {
short_paths,
is_reversed: false,
colors_on: true,
};
format!(
"{}
{}
{}
{}",
format_string("src/test_dir", true, short_paths, " 4.0K", "─┬"),
format_string("src/test_dir/many", true, short_paths, " 4.0K", " └─┬",),
format_string(
"src/test_dir/many/hello_file",
true,
short_paths,
" 4.0K",
" ├──",
),
format_string(
"src/test_dir/many/a_file",
false,
short_paths,
" 0B",
" └──",
),
format_string("src/test_dir", true, &d, " 4.0K", "─┬"),
format_string("src/test_dir/many", true, &d, " 4.0K", " └─┬",),
format_string("src/test_dir/many/hello_file", true, &d, " 4.0K", " ├──",),
format_string("src/test_dir/many/a_file", false, &d, " 0B", " └──",),
)
}
#[cfg(target_os = "linux")]
fn main_output(short_paths: bool) -> String {
let d = DisplayData {
short_paths,
is_reversed: false,
colors_on: true,
};
format!(
"{}
{}
{}
{}",
format_string("src/test_dir", true, short_paths, " 12K", "─┬"),
format_string("src/test_dir/many", true, short_paths, " 8.0K", " └─┬",),
format_string(
"src/test_dir/many/hello_file",
true,
short_paths,
" 4.0K",
" ├──",
),
format_string(
"src/test_dir/many/a_file",
false,
short_paths,
" 0B",
" └──",
),
format_string("src/test_dir", true, &d, " 12K", "─┬"),
format_string("src/test_dir/many", true, &d, " 8.0K", " └─┬",),
format_string("src/test_dir/many/hello_file", true, &d, " 4.0K", " ├──",),
format_string("src/test_dir/many/a_file", false, &d, " 0B", " └──",),
)
}
#[test]
pub fn test_no_color_flag() {
assert_cli::Assert::main_binary()
.with_args(&["-c", "src/test_dir/"])
.stdout()
.is(no_color_flag_output().as_str())
.unwrap();
}
#[cfg(target_os = "macos")]
fn no_color_flag_output() -> String {
"
4.0K ─┬ test_dir
4.0K └─┬ many
4.0K ├── hello_file
0B └── a_file
"
.to_string()
}
#[cfg(target_os = "linux")]
fn no_color_flag_output() -> String {
"
12K ─┬ test_dir
8.0K └─┬ many
4.0K ├── hello_file
0B └── a_file
"
.to_string()
}
#[test]
pub fn test_apparent_size() {
let d = DisplayData {
short_paths: true,
is_reversed: false,
colors_on: true,
};
let r = format!(
"{}",
format_string(
"src/test_dir/many/hello_file",
true,
true,
" 6B",
" ├──",
),
format_string("src/test_dir/many/hello_file", true, &d, " 6B", " ├──",),
);
assert_cli::Assert::main_binary()
.with_args(&["-s", "src/test_dir"])
.stdout()
.contains(r)
.contains(r.as_str())
.unwrap();
}
@@ -140,7 +156,7 @@ pub fn test_d_flag_works() {
.unwrap();
}
fn build_temp_file(dir: &TempDir) -> (PathBuf) {
fn build_temp_file(dir: &TempDir) -> PathBuf {
let file_path = dir.path().join("notes.txt");
let mut file = File::create(&file_path).unwrap();
writeln!(file, "I am a temp file").unwrap();
@@ -163,41 +179,21 @@ pub fn test_soft_sym_link() {
.output();
assert!(c.is_ok());
let r = soft_sym_link_output(dir_s, file_path_s, link_name_s);
let a = format!(" ─┬ {}", dir_s);
let b = format!(" ├── {}", file_path_s);
let c = format!(" └── {}", link_name_s);
// We cannot guarantee which version will appear first.
// TODO: Consider adding predictable itteration order (sort file entries by name?)
assert_cli::Assert::main_binary()
.with_args(&[dir_s])
.with_args(&["-p", &dir_s])
.stdout()
.contains(r)
.contains(a.as_str())
.stdout()
.contains(b.as_str())
.stdout()
.contains(c.as_str())
.unwrap();
}
#[cfg(target_os = "macos")]
fn soft_sym_link_output(dir: &str, file_path: &str, link_name: &str) -> String {
format!(
"{}
{}
{}",
format_string(dir, true, true, " 8.0K", "─┬"),
format_string(file_path, true, true, " 4.0K", " ├──",),
format_string(link_name, false, true, " 4.0K", " └──",),
)
}
#[cfg(target_os = "linux")]
fn soft_sym_link_output(dir: &str, file_path: &str, link_name: &str) -> String {
format!(
"{}
{}
{}",
format_string(dir, true, true, " 8.0K", "─┬"),
format_string(file_path, true, true, " 4.0K", " ├──",),
format_string(link_name, false, true, " 0B", " └──",),
)
}
// Hard links are ignored as the inode is the same as the file
#[test]
pub fn test_hard_sym_link() {
@@ -214,62 +210,33 @@ pub fn test_hard_sym_link() {
.output();
assert!(c.is_ok());
let (r, r2) = hard_link_output(dir_s, file_path_s, link_name_s);
let a = format!(" ─┬ {}", dir_s);
let b = format!(" └── {}", link_name_s);
let b2 = format!(" └── {}", file_path_s);
// Because this is a hard link the file and hard link look identical. Therefore
// we cannot guarantee which version will appear first.
// TODO: Consider adding predictable iteration order (sort file entries by name?)
let result = panic::catch_unwind(|| {
assert_cli::Assert::main_binary()
.with_args(&[dir_s])
.with_args(&["-p", dir_s])
.stdout()
.contains(r)
.contains(a.as_str())
.stdout()
.contains(b.as_str())
.unwrap();
});
if result.is_err() {
assert_cli::Assert::main_binary()
.with_args(&[dir_s])
.with_args(&["-p", dir_s])
.stdout()
.contains(r2)
.contains(a.as_str())
.stdout()
.contains(b2.as_str())
.unwrap();
}
}
#[cfg(target_os = "macos")]
fn hard_link_output(dir_s: &str, file_path_s: &str, link_name_s: &str) -> (String, String) {
let r = format!(
"{}
{}",
format_string(dir_s, true, true, " 4.0K", "─┬"),
format_string(file_path_s, true, true, " 4.0K", " └──")
);
let r2 = format!(
"{}
{}",
format_string(dir_s, true, true, " 4.0K", "─┬"),
format_string(link_name_s, true, true, " 4.0K", " └──")
);
(r, r2)
}
#[cfg(target_os = "linux")]
fn hard_link_output(dir_s: &str, file_path_s: &str, link_name_s: &str) -> (String, String) {
let r = format!(
"{}
{}",
format_string(dir_s, true, true, " 8.0K", "─┬"),
format_string(file_path_s, true, true, " 4.0K", " └──")
);
let r2 = format!(
"{}
{}",
format_string(dir_s, true, true, " 8.0K", "─┬"),
format_string(link_name_s, true, true, " 4.0K", " └──")
);
(r, r2)
}
//Check we don't recurse down an infinite symlink tree
// Check we don't recurse down an infinite symlink tree
#[test]
pub fn test_recursive_sym_link() {
let dir = Builder::new().tempdir().unwrap();
@@ -285,28 +252,82 @@ pub fn test_recursive_sym_link() {
.output();
assert!(c.is_ok());
let a = format!(" ─┬ {}", dir_s);
let b = format!(" └── {}", link_name_s);
assert_cli::Assert::main_binary()
.with_args(&[dir_s])
.with_args(&["-p", dir_s])
.stdout()
.contains(recursive_sym_link_output(dir_s, link_name_s))
.contains(a.as_str())
.stdout()
.contains(b.as_str())
.unwrap();
}
#[cfg(target_os = "macos")]
fn recursive_sym_link_output(dir: &str, link_name: &str) -> String {
format!(
"{}
{}",
format_string(dir, true, true, " 4.0K", "─┬"),
format_string(link_name, true, true, " 4.0K", " └──",),
)
// Check against directories and files whos names are substrings of each other
#[test]
pub fn test_substring_of_names() {
assert_cli::Assert::main_binary()
.with_args(&["-c", "src/test_dir2"])
.stdout()
.is(no_substring_of_names_output().as_str())
.unwrap();
}
#[cfg(target_os = "linux")]
fn recursive_sym_link_output(dir: &str, link_name: &str) -> String {
format!(
"{}
{}",
format_string(dir, true, true, " 4.0K", "─┬"),
format_string(link_name, true, true, " 0B", " └──",),
)
fn no_substring_of_names_output() -> String {
"
24K ─┬ test_dir2
8.0K ├─┬ dir
4.0K │ └── hello
8.0K ├─┬ dir_substring
4.0K │ └── hello
4.0K └── dir_name_clash
"
.into()
}
#[cfg(target_os = "macos")]
fn no_substring_of_names_output() -> String {
"
12K ─┬ test_dir2
4.0K ├─┬ dir
4.0K │ └── hello
4.0K ├── dir_name_clash
4.0K └─┬ dir_substring
4.0K └── hello
"
.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()
}

View File

@@ -1,40 +1,67 @@
use jwalk::DirEntry;
use std::cmp::Ordering;
use std::collections::HashMap;
use std::collections::HashSet;
use walkdir::WalkDir;
use jwalk::WalkDir;
mod platform;
use self::platform::*;
#[derive(Debug)]
#[derive(Debug, Default, Eq)]
pub struct Node {
pub name: String,
pub size: u64,
pub children: Vec<Box<Node>>,
pub children: Vec<Node>,
}
impl Ord for Node {
fn cmp(&self, other: &Self) -> Ordering {
if self.size == other.size {
self.name.cmp(&other.name)
} else {
self.size.cmp(&other.size)
}
}
}
impl PartialOrd for Node {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl PartialEq for Node {
fn eq(&self, other: &Self) -> bool {
self.name == other.name && self.size == other.size && self.children == other.children
}
}
pub fn is_a_parent_of(parent: &str, child: &str) -> bool {
(child.starts_with(parent) && child.chars().nth(parent.chars().count()) == Some('/'))
|| parent == "/"
}
pub fn simplify_dir_names(filenames: Vec<&str>) -> HashSet<String> {
let mut top_level_names: HashSet<String> = HashSet::new();
let mut top_level_names: HashSet<String> = HashSet::with_capacity(filenames.len());
let mut to_remove: Vec<String> = Vec::with_capacity(filenames.len());
for t in filenames {
let top_level_name = ensure_end_slash(t);
let top_level_name = strip_end_slash(t);
let mut can_add = true;
let mut to_remove: Vec<String> = Vec::new();
for tt in top_level_names.iter() {
let temp = tt.to_string();
if top_level_name.starts_with(&temp) {
if is_a_parent_of(&top_level_name, tt) {
to_remove.push(tt.to_string());
} else if is_a_parent_of(tt, &top_level_name) {
can_add = false;
} else if tt.starts_with(&top_level_name) {
to_remove.push(temp);
}
}
for tr in to_remove {
top_level_names.remove(&tr);
}
to_remove.sort_unstable();
top_level_names.retain(|tr| to_remove.binary_search(tr).is_err());
to_remove.clear();
if can_add {
top_level_names.insert(strip_end_slash(t));
top_level_names.insert(strip_end_slash(t).to_owned());
}
}
@@ -43,30 +70,46 @@ pub fn simplify_dir_names(filenames: Vec<&str>) -> HashSet<String> {
pub fn get_dir_tree(
top_level_names: &HashSet<String>,
ignore_directory: Option<&str>,
apparent_size: bool,
limit_filesystem: bool,
threads: Option<usize>,
) -> (bool, HashMap<String, u64>) {
let mut permissions = 0;
let mut inodes: HashSet<(u64, u64)> = HashSet::new();
let mut data: HashMap<String, u64> = HashMap::new();
let restricted_filesystems = if limit_filesystem {
get_allowed_filesystems(top_level_names)
} else {
None
};
for b in top_level_names.iter() {
examine_dir(&b, apparent_size, &mut inodes, &mut data, &mut permissions);
examine_dir(
&b,
apparent_size,
&restricted_filesystems,
&ignore_directory,
&mut data,
&mut permissions,
threads,
);
}
(permissions == 0, data)
}
pub fn ensure_end_slash(s: &str) -> String {
let mut new_name = String::from(s);
while new_name.ends_with('/') || new_name.ends_with("/.") {
new_name.pop();
fn get_allowed_filesystems(top_level_names: &HashSet<String>) -> Option<HashSet<u64>> {
let mut limit_filesystems: HashSet<u64> = HashSet::new();
for file_name in top_level_names.iter() {
if let Ok(a) = get_filesystem(file_name) {
limit_filesystems.insert(a);
}
}
new_name + "/"
Some(limit_filesystems)
}
pub fn strip_end_slash(s: &str) -> String {
let mut new_name = String::from(s);
pub fn strip_end_slash(mut new_name: &str) -> &str {
while (new_name.ends_with('/') || new_name.ends_with("/.")) && new_name.len() > 1 {
new_name.pop();
new_name = &new_name[..new_name.len() - 1];
}
new_name
}
@@ -74,35 +117,32 @@ pub fn strip_end_slash(s: &str) -> String {
fn examine_dir(
top_dir: &str,
apparent_size: bool,
inodes: &mut HashSet<(u64, u64)>,
filesystems: &Option<HashSet<u64>>,
ignore_directory: &Option<&str>,
data: &mut HashMap<String, u64>,
file_count_no_permission: &mut u64,
threads: Option<usize>,
) {
for entry in WalkDir::new(top_dir) {
let mut inodes: HashSet<(u64, u64)> = HashSet::new();
let mut iter = WalkDir::new(top_dir)
.preload_metadata(true)
.skip_hidden(false);
if let Some(threads_to_start) = threads {
iter = iter.num_threads(threads_to_start);
}
for entry in iter {
if let Ok(e) = entry {
let maybe_size_and_inode = get_metadata(&e, apparent_size);
if let Some(d) = ignore_directory {
if e.path().to_string_lossy().contains(*d) {
continue;
}
}
match maybe_size_and_inode {
Some((size, maybe_inode)) => {
if !apparent_size {
if let Some(inode_dev_pair) = maybe_inode {
if inodes.contains(&inode_dev_pair) {
continue;
}
inodes.insert(inode_dev_pair);
}
}
// This path and all its parent paths have their counter incremented
let mut e_path = e.path().to_path_buf();
loop {
let path_name = e_path.to_string_lossy().to_string();
let s = data.entry(path_name.clone()).or_insert(0);
*s += size;
if path_name == *top_dir {
break;
}
assert!(path_name != "");
e_path.pop();
if !should_ignore_file(apparent_size, filesystems, &mut inodes, maybe_inode) {
process_file_with_size_and_inode(top_dir, data, e, size)
}
}
None => *file_count_no_permission += 1,
@@ -113,6 +153,55 @@ fn examine_dir(
}
}
fn should_ignore_file(
apparent_size: bool,
restricted_filesystems: &Option<HashSet<u64>>,
inodes: &mut HashSet<(u64, u64)>,
maybe_inode: Option<(u64, u64)>,
) -> bool {
if !apparent_size {
if let Some(inode_dev_pair) = maybe_inode {
// Ignore files on different devices (if flag applied)
if restricted_filesystems.is_some()
&& !restricted_filesystems
.as_ref()
.unwrap()
.contains(&inode_dev_pair.1)
{
return true;
}
// Ignore files already visited or symlinked
if inodes.contains(&inode_dev_pair) {
return true;
}
inodes.insert(inode_dev_pair);
}
}
false
}
fn process_file_with_size_and_inode(
top_dir: &str,
data: &mut HashMap<String, u64>,
e: DirEntry,
size: u64,
) {
// This path and all its parent paths have their counter incremented
for path_name in e.path().ancestors() {
// This is required due to bug in Jwalk that adds '/' to all sub dir lists
// see: https://github.com/jessegrosjean/jwalk/issues/13
if path_name.to_string_lossy() == "/" && top_dir != "/" {
continue;
}
let path_name = path_name.to_string_lossy();
let s = data.entry(path_name.to_string()).or_insert(0);
*s += size;
if path_name == top_dir {
break;
}
}
}
pub fn sort_by_size_first_name_second(a: &(String, u64), b: &(String, u64)) -> Ordering {
let result = b.1.cmp(&a.1);
if result == Ordering::Equal {
@@ -124,7 +213,7 @@ pub fn sort_by_size_first_name_second(a: &(String, u64), b: &(String, u64)) -> O
pub fn sort(data: HashMap<String, u64>) -> Vec<(String, u64)> {
let mut new_l: Vec<(String, u64)> = data.iter().map(|(a, b)| (a.clone(), *b)).collect();
new_l.sort_by(|a, b| sort_by_size_first_name_second(&a, &b));
new_l.sort_unstable_by(sort_by_size_first_name_second);
new_l
}
@@ -141,7 +230,7 @@ pub fn trim_deep_ones(
max_depth: u64,
top_level_names: &HashSet<String>,
) -> Vec<(String, u64)> {
let mut result: Vec<(String, u64)> = vec![];
let mut result: Vec<(String, u64)> = Vec::with_capacity(input.len() * top_level_names.len());
for name in top_level_names {
let my_max_depth = name.matches('/').count() + max_depth as usize;
@@ -196,4 +285,26 @@ mod tests {
correct.insert("src".to_string());
assert_eq!(simplify_dir_names(vec!["src/."]), correct);
}
#[test]
fn test_simplify_dir_substring_names() {
let mut correct = HashSet::new();
correct.insert("src".to_string());
correct.insert("src_v2".to_string());
assert_eq!(simplify_dir_names(vec!["src/", "src_v2"]), correct);
}
#[test]
fn test_is_a_parent_of() {
assert!(is_a_parent_of("/usr", "/usr/andy"));
assert!(is_a_parent_of("/usr", "/usr/andy/i/am/descendant"));
assert!(!is_a_parent_of("/usr/andy", "/usr"));
assert!(!is_a_parent_of("/usr/andy", "/usr/sibling"));
}
#[test]
fn test_is_a_parent_of_root() {
assert!(is_a_parent_of("/", "/usr/andy"));
assert!(is_a_parent_of("/", "/usr"));
}
}

View File

@@ -1,5 +1,8 @@
use walkdir::DirEntry;
use jwalk::DirEntry;
use std::fs;
use std::io;
#[cfg(target_family = "unix")]
fn get_block_size() -> u64 {
// All os specific implementations of MetatdataExt seem to define a block as 512 bytes
// https://doc.rust-lang.org/std/os/linux/fs/trait.MetadataExt.html#tymethod.st_blocks
@@ -9,17 +12,50 @@ fn get_block_size() -> u64 {
#[cfg(target_family = "unix")]
pub fn get_metadata(d: &DirEntry, use_apparent_size: bool) -> Option<(u64, Option<(u64, u64)>)> {
use std::os::unix::fs::MetadataExt;
d.metadata().ok().and_then(|md| {
d.metadata.as_ref().unwrap().as_ref().ok().map(|md| {
let inode = Some((md.ino(), md.dev()));
if use_apparent_size {
Some((md.len(), inode))
(md.len(), inode)
} else {
Some((md.blocks() * get_block_size(), inode))
(md.blocks() * get_block_size(), inode)
}
})
}
#[cfg(not(target_family = "unix"))]
pub fn get_metadata(d: &DirEntry, _apparent: bool) -> Option<(u64, Option<(u64, u64)>)> {
d.metadata().ok().map_or(None, |md| Some((md.len(), None)))
#[cfg(target_family = "windows")]
pub fn get_metadata(d: &DirEntry, use_apparent_size: bool) -> Option<(u64, Option<(u64, u64)>)> {
use std::os::windows::fs::MetadataExt;
d.metadata.as_ref().unwrap().as_ref().ok().map(|md| {
let windows_equivalent_of_inode = Some((md.file_index(), md.volume_serial_number()));
(md.file_size(), windows_equivalent_of_inode)
})
}
#[cfg(all(not(target_family = "windows"), not(target_family = "unix")))]
pub fn get_metadata(d: &DirEntry, _apparent: bool) -> Option<(u64, Option<(u64, u64)>)> {
d.metadata
.as_ref()
.unwrap()
.as_ref()
.ok()
.map(|md| (md.len(), None))
}
#[cfg(target_family = "unix")]
pub fn get_filesystem(file_path: &str) -> Result<u64, io::Error> {
use std::os::unix::fs::MetadataExt;
let metadata = fs::metadata(file_path)?;
Ok(metadata.dev())
}
#[cfg(target_family = "windows")]
pub fn get_device(file_path: &str) -> Result<u64, io::Error> {
use std::os::windows::fs::MetadataExt;
let metadata = fs::metadata(file_path)?;
Ok(metadata.volume_serial_number())
}
#[cfg(all(not(target_family = "windows"), not(target_family = "unix")))]
pub fn get_device(file_path: &str) -> Result<u64, io::Error> {
None
}