mirror of
https://github.com/bootandy/dust.git
synced 2026-06-08 11:29:05 +03:00
Compare commits
65 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ba04d4c42c | |||
| 6842526d2c | |||
| 4ac85d7dc9 | |||
| 8170a07886 | |||
| 0f1f823736 | |||
| e6c777fb8b | |||
| 0bded9698a | |||
| c7f0ea59f0 | |||
| 6d62cfb9ae | |||
| 803934d84b | |||
| 24c97ef92f | |||
| 270edf0a76 | |||
| 0c5b08e1d2 | |||
| 35aef4c837 | |||
| 95e7bb01eb | |||
| 247e55788a | |||
| bcab66ab8b | |||
| 2c87a21da1 | |||
| 74b9178017 | |||
| 2eb1633b77 | |||
| 3fd274ab36 | |||
| f3ab902811 | |||
| b3b1a867c4 | |||
| 32561ecb18 | |||
| 2fe3943ed5 | |||
| b8ad44b7f0 | |||
| 1a34bc3198 | |||
| 385ddb75e1 | |||
| 5c6165da8a | |||
| f39b09e79c | |||
| 778dbb44b3 | |||
| 69c79d5f95 | |||
| 61ab0e8f96 | |||
| 285fd62850 | |||
| 6a63cbe1bc | |||
| 8d98171b82 | |||
| 120b4e16e7 | |||
| 6198e3183f | |||
| ecf6c8f0e5 | |||
| f14a9789f4 | |||
| 4944d517f4 | |||
| cce656ab4c | |||
| 03a517a310 | |||
| 3796c39ac9 | |||
| 0357fc5e71 | |||
| aa3f411974 | |||
| eb69ad19a0 | |||
| c127580057 | |||
| c978c6cf93 | |||
| f72a67132c | |||
| 4d1f881c17 | |||
| e75a666a4c | |||
| 617b0d2971 | |||
| 8fa83e3836 | |||
| 7fa2ce3434 | |||
| b0e971891e | |||
| cef95fa415 | |||
| 381d286847 | |||
| aa963defda | |||
| 0faf795284 | |||
| b7271b1da2 | |||
| 99f462f023 | |||
| 1c80cbf28b | |||
| f802d7a6b4 | |||
| b4c6c68527 |
+1
-4
@@ -2,10 +2,7 @@
|
||||
# will have compiled files and executables
|
||||
/target/
|
||||
|
||||
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
|
||||
# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock
|
||||
Cargo.lock
|
||||
|
||||
# These are backup files generated by rustfmt
|
||||
**/*.rs.bk
|
||||
*.swp
|
||||
.vscode/*
|
||||
|
||||
@@ -19,17 +19,9 @@ matrix:
|
||||
# don't need
|
||||
include:
|
||||
# Linux
|
||||
- env: TARGET=aarch64-unknown-linux-gnu
|
||||
- env: TARGET=arm-unknown-linux-gnueabi
|
||||
- env: TARGET=armv7-unknown-linux-gnueabihf
|
||||
- env: TARGET=i686-unknown-linux-gnu
|
||||
- env: TARGET=i686-unknown-linux-musl
|
||||
- env: TARGET=x86_64-unknown-linux-gnu
|
||||
- env: TARGET=x86_64-unknown-linux-musl
|
||||
|
||||
# OSX
|
||||
- env: TARGET=i686-apple-darwin
|
||||
os: osx
|
||||
- env: TARGET=x86_64-apple-darwin
|
||||
os: osx
|
||||
|
||||
|
||||
Generated
+511
@@ -0,0 +1,511 @@
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "assert_cli"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"difference 1.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.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"skeptic 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backtrace-sys"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bytecount"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "cargo_metadata"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"semver 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.31.1"
|
||||
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.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "colored"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "difference"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "dtoa"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "du-dust"
|
||||
version = "0.2.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)",
|
||||
"clap 2.31.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempfile 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"walkdir 2.1.4 (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"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-zircon"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-zircon-sys"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "kernel32-sys"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pulldown-cmark"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "redox_termios"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "remove_dir_all"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.8.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.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive_internals 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive_internals"
|
||||
version = "0.23.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "skeptic"
|
||||
version = "0.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bytecount 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cargo_metadata 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"error-chain 0.11.0 (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.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempdir"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"remove_dir_all 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"remove_dir_all 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termion"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-build"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "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"
|
||||
|
||||
[metadata]
|
||||
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
||||
"checksum assert_cli 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "72342c21057a3cb5f7c2d849bf7999a83795434dd36d74fa8c24680581bd1930"
|
||||
"checksum atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "af80143d6f7608d746df1520709e5d141c96f240b0e62b0aa41bdfb53374d9d4"
|
||||
"checksum backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbbf59b1c43eefa8c3ede390fcc36820b4999f7914104015be25025e0d62af2"
|
||||
"checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661"
|
||||
"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
|
||||
"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
|
||||
"checksum bytecount 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "af27422163679dea46a1a7239dffff64d3dcdc3ba5fe9c49c789fbfe0eb949de"
|
||||
"checksum cargo_metadata 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1f56ec3e469bca7c276f2eea015aa05c5e381356febdbb0683c2580189604537"
|
||||
"checksum cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "2b4911e4bdcb4100c7680e7e854ff38e23f1b34d4d9e079efae3da2801341ffc"
|
||||
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
|
||||
"checksum clap 2.31.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dc18f6f4005132120d9711636b32c46a233fad94df6217fa1d81c5e97a9f200"
|
||||
"checksum colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b0aa3473e85a3161b59845d6096b289bb577874cafeaf75ea1b1beaa6572c7fc"
|
||||
"checksum difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3304d19798a8e067e48d8e69b2c37f0b5e9b4e462504ad9e27e9f3fce02bba8"
|
||||
"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
|
||||
"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 fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
|
||||
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
||||
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
|
||||
"checksum itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c069bbec61e1ca5a596166e55dfe4773ff745c3d16b700013bcaff9a6df2c682"
|
||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||
"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
|
||||
"checksum libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)" = "f54263ad99207254cf58b5f701ecb432c717445ea2ee8af387334bdd1a03fdff"
|
||||
"checksum num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dee092fcdf725aee04dd7da1d21debff559237d49ef1cb3e69bcb8ece44c7364"
|
||||
"checksum proc-macro2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "681c2c8e039ff358cb926dbc5151d561cbd0249089986ace39dfe8e405bb7511"
|
||||
"checksum pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fdf85cda6cadfae5428a54661d431330b312bc767ddbc57adbedc24da66e32"
|
||||
"checksum quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7b0ff51282f28dc1b53fd154298feaa2e77c5ea0dba68e1fd8b03b72fbe13d2a"
|
||||
"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
|
||||
"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd"
|
||||
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
|
||||
"checksum remove_dir_all 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dfc5b3ce5d5ea144bb04ebd093a9e14e9765bcfec866aecda9b6dec43b3d1e24"
|
||||
"checksum rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11fb43a206a04116ffd7cfcf9bcb941f8eb6cc7ff667272246b0a1c74259a3cb"
|
||||
"checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"
|
||||
"checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637"
|
||||
"checksum semver 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bee2bc909ab2d8d60dab26e8cad85b25d795b14603a0dcb627b78b9d30b6454b"
|
||||
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
"checksum serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "d3bcee660dcde8f52c3765dd9ca5ee36b4bf35470a738eb0bd5a8752b0389645"
|
||||
"checksum serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "f1711ab8b208541fa8de00425f6a577d90f27bb60724d2bb5fd911314af9668f"
|
||||
"checksum serde_derive_internals 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "89b340a48245bc03ddba31d0ff1709c118df90edc6adabaca4aac77aea181cce"
|
||||
"checksum serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "5c508584d9913df116b91505eec55610a2f5b16e9ed793c46e4d0152872b3e74"
|
||||
"checksum skeptic 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c8431f8fca168e2db4be547bd8329eac70d095dff1444fee4b0fa0fabc7df75a"
|
||||
"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
|
||||
"checksum syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "91b52877572087400e83d24b9178488541e3d535259e04ff17a63df1e5ceff59"
|
||||
"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
|
||||
"checksum tempfile 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "439d9a7c00f98b1b5ee730039bf5b1f9203d508690e3c76b509e7ad59f8f7c99"
|
||||
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
|
||||
"checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693"
|
||||
"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
|
||||
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||
"checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c"
|
||||
"checksum walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bb08f9e670fab86099470b97cd2b252d6527f0b3cc1401acdb595ffc9dd288ff"
|
||||
"checksum walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "63636bd0eb3d00ccb8b9036381b526efac53caf112b7783b730ab3f8e44da369"
|
||||
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
||||
"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3"
|
||||
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
+22
-2
@@ -1,8 +1,28 @@
|
||||
[package]
|
||||
name = "du-dust"
|
||||
description = "A more intuitive version of du"
|
||||
version = "0.3.0"
|
||||
authors = ["bootandy <bootandy@gmail.com>", "nebkor <code@ardent.nebcorp.com>"]
|
||||
|
||||
documentation = "https://github.com/bootandy/dust"
|
||||
homepage = "https://github.com/bootandy/dust"
|
||||
repository = "https://github.com/bootandy/dust"
|
||||
|
||||
keywords = ["du", "command-line", "disk", "disk-usage"]
|
||||
categories = ["command-line-utilities"]
|
||||
license = "Apache-2.0"
|
||||
|
||||
[badges]
|
||||
travis-ci = {repository = "https://travis-ci.org/bootandy/dust"}
|
||||
|
||||
[[bin]]
|
||||
name = "dust"
|
||||
version = "0.1.0"
|
||||
authors = ["bootandy <bootandy@gmail.com>"]
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
ansi_term = "0.11"
|
||||
clap = "2.31"
|
||||
assert_cli = "0.5"
|
||||
tempfile = "3"
|
||||
walkdir = "2"
|
||||
|
||||
|
||||
@@ -1,42 +1,72 @@
|
||||
|
||||
[](https://travis-ci.org/bootandy/dust)
|
||||
|
||||
|
||||
# Dust
|
||||
du + rust = dust. A rust alternative to du
|
||||
|
||||
Unlike du, dust is meant to give you an instant overview of which directories are using disk space without requiring sort or head. Dust does not count file system blocks; it uses file sizes instead. Dust will print a maximum of 1 'Did not have permissions message'.
|
||||
du + rust = dust. Like du but more intuitive
|
||||
|
||||
## Install
|
||||
|
||||
Dust will list the 15 biggest sub directories and will smartly recurse down the tree to find the larger ones. There is no need for a '-d' flag or a '-h' flag. The largest sub directory will have its size shown in red
|
||||
### Cargo
|
||||
|
||||
* cargo install du-dust
|
||||
|
||||
### Download
|
||||
|
||||
* Download linux / mac binary from [Releases](https://github.com/bootandy/dust/releases)
|
||||
* unzip file: tar -xvf _downloaded_file.tar.gz_
|
||||
* move file to executable path: sudo mv dust /usr/local/bin/
|
||||
|
||||
## Overview
|
||||
|
||||
Dust is meant to give you an instant overview of which directories are using disk space without requiring sort or head. Dust will print a maximum of 1 'Did not have permissions message'.
|
||||
|
||||
Dust will list the 20 biggest sub directories or files and will smartly recurse down the tree to find the larger ones. There is no need for a '-d' flag or a '-h' flag. The largest sub directory will have its size shown in *red*
|
||||
|
||||
## Why?
|
||||
|
||||
du has a number of ways of showing you what it finds, in terms of disk consumption, but really, there are only one or two ways you invoke it: with -h for “human readable” units, like 100G or 89k, or with -b for “bytes”. The former is generally used for a quick survey of a directory with a small number of things in it, and the latter for when you have a bunch and need to sort the output numerically, and you’re obligated to either further pass it into something like awk to turn bytes into the appropriate human-friendly unit like mega or gigabytes, or pipe thru sort and head while remembering the '-h' flag. Then once you have the top offenders, you recurse down into the largest one and repeat the process until you’ve found your cruft or gems and can move on.
|
||||
|
||||
Dust assumes that’s what you wanted to do in the first place, and takes care of tracking the largest offenders in terms of actual size, and showing them to you with human-friendly units and in-context within the filetree.
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
Usage: dust <dir>
|
||||
Usage: dust -n 30 <dir> (Shows 30 directories not 15)
|
||||
Usage: dust <dir> <another_dir> <and_more>
|
||||
Usage: dust -p <dir> (full-path - does not shorten the path of the subdirectories)
|
||||
Usage: dust -s <dir> (apparent-size - shows the length of the file as opposed to the amount of disk space it uses)
|
||||
Usage: dust -n 30 <dir> (Shows 30 directories not 20)
|
||||
Usage: dust -d 3 <dir> (Shows 3 levels of subdirectories)
|
||||
```
|
||||
|
||||
|
||||
```
|
||||
dust .
|
||||
161M .
|
||||
160M └── ./target
|
||||
123M ├── ./target/debug
|
||||
83M │ ├── ./target/debug/deps
|
||||
16M │ │ ├── ./target/debug/deps/libclap-82e6176feef5d4b7.rlib
|
||||
8.6M │ │ └── ./target/debug/deps/dust-993f7d919d92f0f8.dSYM
|
||||
8.6M │ │ └── ./target/debug/deps/dust-993f7d919d92f0f8.dSYM/Contents
|
||||
8.6M │ │ └── ./target/debug/deps/dust-993f7d919d92f0f8.dSYM/Contents/Resources
|
||||
27M │ ├── ./target/debug/incremental
|
||||
12M │ └── ./target/debug/build
|
||||
20M ├── ./target/x86_64-apple-darwin
|
||||
20M │ └── ./target/x86_64-apple-darwin/debug
|
||||
20M │ └── ./target/x86_64-apple-darwin/debug/deps
|
||||
16M │ └── ./target/x86_64-apple-darwin/debug/deps/libclap-7e3f8513c52cd558.rlib
|
||||
16M └── ./target/release
|
||||
13M └── ./target/release/deps
|
||||
djin:git/dust> dust
|
||||
1.2G target
|
||||
622M ├─┬ debug
|
||||
445M │ ├── deps
|
||||
70M │ ├── incremental
|
||||
56M │ └── build
|
||||
262M ├─┬ rls
|
||||
262M │ └─┬ debug
|
||||
203M │ ├── deps
|
||||
56M │ └── build
|
||||
165M ├─┬ package
|
||||
165M │ └─┬ du-dust-0.2.4
|
||||
165M │ └─┬ target
|
||||
165M │ └─┬ debug
|
||||
131M │ └── deps
|
||||
165M └─┬ release
|
||||
124M └── deps
|
||||
```
|
||||
|
||||
Performance: dust is currently about 4 times slower than du.
|
||||
## Performance
|
||||
|
||||
Dust is currently about 4 times slower than du.
|
||||
|
||||
## Alternatives
|
||||
|
||||
* [NCDU](https://dev.yorhel.nl/ncdu)
|
||||
* 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.
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
# Based on the "trust" template v0.1.2
|
||||
# https://github.com/japaric/trust/tree/v0.1.2
|
||||
|
||||
environment:
|
||||
global:
|
||||
# TODO This is the Rust channel that build jobs will use by default but can be
|
||||
# overridden on a case by case basis down below
|
||||
RUST_VERSION: stable
|
||||
|
||||
# TODO Update this to match the name of your project.
|
||||
CRATE_NAME: dust
|
||||
|
||||
# TODO These are all the build jobs. Adjust as necessary. Comment out what you
|
||||
# don't need
|
||||
matrix:
|
||||
# MinGW
|
||||
- TARGET: i686-pc-windows-gnu
|
||||
- TARGET: x86_64-pc-windows-gnu
|
||||
|
||||
# MSVC
|
||||
- TARGET: i686-pc-windows-msvc
|
||||
- TARGET: x86_64-pc-windows-msvc
|
||||
|
||||
# Testing other channels
|
||||
- TARGET: x86_64-pc-windows-gnu
|
||||
RUST_VERSION: nightly
|
||||
- TARGET: x86_64-pc-windows-msvc
|
||||
RUST_VERSION: nightly
|
||||
|
||||
install:
|
||||
- ps: >-
|
||||
If ($Env:TARGET -eq 'x86_64-pc-windows-gnu') {
|
||||
$Env:PATH += ';C:\msys64\mingw64\bin'
|
||||
} ElseIf ($Env:TARGET -eq 'i686-pc-windows-gnu') {
|
||||
$Env:PATH += ';C:\msys64\mingw32\bin'
|
||||
}
|
||||
- curl -sSf -o rustup-init.exe https://win.rustup.rs/
|
||||
- rustup-init.exe -y --default-host %TARGET% --default-toolchain %RUST_VERSION%
|
||||
- set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
|
||||
- rustc -Vv
|
||||
- cargo -V
|
||||
|
||||
# TODO This is the "test phase", tweak it as you see fit
|
||||
test_script:
|
||||
# we don't run the "test phase" when doing deploys
|
||||
- if [%APPVEYOR_REPO_TAG%]==[false] (
|
||||
cargo build --target %TARGET% &&
|
||||
cargo build --target %TARGET% --release &&
|
||||
cargo test --target %TARGET% &&
|
||||
cargo test --target %TARGET% --release &&
|
||||
cargo run --target %TARGET% &&
|
||||
cargo run --target %TARGET% --release
|
||||
)
|
||||
|
||||
before_deploy:
|
||||
# TODO Update this to build the artifacts that matter to you
|
||||
- cargo rustc --target %TARGET% --release --bin hello -- -C lto
|
||||
- ps: ci\before_deploy.ps1
|
||||
|
||||
deploy:
|
||||
artifact: /.*\.zip/
|
||||
# TODO update `auth_token.secure`
|
||||
# - Create a `public_repo` GitHub token. Go to: https://github.com/settings/tokens/new
|
||||
# - Encrypt it. Go to https://ci.appveyor.com/tools/encrypt
|
||||
# - Paste the output down here
|
||||
auth_token:
|
||||
secure: UlU73Td7Bkb2N88ws4YGLWR+4U0IMgiou9QQtMnmpouJFjeUNxtLSPMPODVXP7zq4sKt5HR5B3fX9MW4mKm351fvnQEoihETn06pKiXGnY//SlTPTt67MX9ZOYmd9ohJReMDOZDgqhnGLxfymycGtsLAmdjDZnAl+IMqgg0FMyVFj9Cl9aKxnn12lxQyX4zabHKk8TUKD3By8ZoEUnJMHt3gEtOmbDgS4brcTPeHCzqnYFw73LEnkqvz+JP0XwauJY7Cf8lminKm/klmjCkQji8T9SHI52v1g0Fxpx0ucp2o3vulQrLHXaHvZ6Fr7J0cSXXzaFF3rrGLt4t4jU/+9TZm1+n5k5XuPW4x4NTCC9NmIj/z0/z41t82E9qZhzhtm2Jdsg6H2tNk+C774TYqcmR6GCvfRadfjRp3cA5dh0UwDVjH2MJFxlHDVkl6la0mVVRsCGF3oBKZVk0BDl1womfnmI46o/uU+gLknHN6Ed6PHHPPYDViWd3VKdmHKT7XrkMMUF6HjZUtla689DWIOWZSiV++1dVPcl/1TV+6tTmN4bBtPcLuX7SHRuLp2PI2kATvRMECsa7gZRypW4jKpVn7b2yetX9TVI3i1zR5zkQJ3dPg8sATvYPL53aKH/WsqUg4rzoAlbk9so+++R4bQY69LhV3B511B7EAynoZFdM
|
||||
description: ''
|
||||
on:
|
||||
# TODO Here you can pick which targets will generate binary releases
|
||||
# In this example, there are some targets that are tested using the stable
|
||||
# and nightly channels. This condition makes sure there is only one release
|
||||
# for such targets and that's generated using the stable channel
|
||||
RUST_VERSION: stable
|
||||
appveyor_repo_tag: true
|
||||
provider: GitHub
|
||||
|
||||
cache:
|
||||
- C:\Users\appveyor\.cargo\registry
|
||||
- target
|
||||
|
||||
branches:
|
||||
only:
|
||||
# Release tags
|
||||
- /^v\d+\.\d+\.\d+.*$/
|
||||
- master
|
||||
|
||||
notifications:
|
||||
- provider: Email
|
||||
on_build_success: false
|
||||
|
||||
# Building is done in the test phase, so we disable Appveyor's build phase.
|
||||
build: false
|
||||
+193
@@ -0,0 +1,193 @@
|
||||
extern crate ansi_term;
|
||||
|
||||
use self::ansi_term::Colour::Fixed;
|
||||
|
||||
static UNITS: [char; 4] = ['T', 'G', 'M', 'K'];
|
||||
|
||||
pub fn draw_it(
|
||||
permissions: bool,
|
||||
short_paths: bool,
|
||||
depth: Option<u64>,
|
||||
base_dirs: Vec<String>,
|
||||
to_display: Vec<(String, u64)>,
|
||||
) -> () {
|
||||
if !permissions {
|
||||
eprintln!("Did not have permissions for all directories");
|
||||
}
|
||||
|
||||
for f in base_dirs {
|
||||
display_node(f, &to_display, true, short_paths, depth, "")
|
||||
}
|
||||
}
|
||||
|
||||
fn get_size(nodes: &Vec<(String, u64)>, node_to_print: &String) -> Option<u64> {
|
||||
for &(ref k, ref v) in nodes.iter() {
|
||||
if *k == *node_to_print {
|
||||
return Some(*v);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn display_node<S: Into<String>>(
|
||||
node_to_print: String,
|
||||
to_display: &Vec<(String, u64)>,
|
||||
is_biggest: bool,
|
||||
short_paths: bool,
|
||||
depth: Option<u64>,
|
||||
indentation_str: S,
|
||||
) {
|
||||
let new_depth = match depth {
|
||||
None => None,
|
||||
Some(0) => return,
|
||||
Some(d) => Some(d - 1),
|
||||
};
|
||||
match get_size(to_display, &node_to_print) {
|
||||
None => println!("Can not find path: {}", node_to_print),
|
||||
Some(size) => {
|
||||
let mut is = indentation_str.into();
|
||||
let ntp: &str = node_to_print.as_ref();
|
||||
|
||||
print_this_node(ntp, size, is_biggest, short_paths, is.as_ref());
|
||||
|
||||
is = is.replace("└─┬", " ");
|
||||
is = is.replace("└──", " ");
|
||||
is = is.replace("├──", "│ ");
|
||||
is = is.replace("├─┬", "│ ");
|
||||
|
||||
let printable_node_slashes = node_to_print.matches('/').count();
|
||||
|
||||
let mut num_siblings = to_display.iter().fold(0, |a, b| {
|
||||
if b.0.starts_with(ntp) && b.0.matches('/').count() == printable_node_slashes + 1 {
|
||||
a + 1
|
||||
} else {
|
||||
a
|
||||
}
|
||||
});
|
||||
|
||||
let mut is_biggest = true;
|
||||
for &(ref k, _) in to_display.iter() {
|
||||
if k.starts_with(ntp) && k.matches('/').count() == printable_node_slashes + 1 {
|
||||
num_siblings -= 1;
|
||||
|
||||
let mut has_children = false;
|
||||
if new_depth.is_none() || new_depth.unwrap() != 1 {
|
||||
for &(ref k2, _) in to_display.iter() {
|
||||
let kk: &str = k.as_ref();
|
||||
if k2.starts_with(kk)
|
||||
&& k2.matches('/').count() == printable_node_slashes + 2
|
||||
{
|
||||
has_children = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
display_node(
|
||||
k.to_string(),
|
||||
to_display,
|
||||
is_biggest,
|
||||
short_paths,
|
||||
new_depth,
|
||||
is.to_string() + get_tree_chars(num_siblings, has_children),
|
||||
);
|
||||
is_biggest = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_tree_chars(num_siblings: u64, has_children: bool) -> &'static str {
|
||||
if num_siblings == 0 {
|
||||
if has_children {
|
||||
"└─┬"
|
||||
} else {
|
||||
"└──"
|
||||
}
|
||||
} else {
|
||||
if has_children {
|
||||
"├─┬"
|
||||
} else {
|
||||
"├──"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn print_this_node(
|
||||
node_name: &str,
|
||||
size: u64,
|
||||
is_biggest: bool,
|
||||
short_paths: bool,
|
||||
indentation: &str,
|
||||
) {
|
||||
let pretty_size = format!("{:>5}", human_readable_number(size),);
|
||||
println!(
|
||||
"{}",
|
||||
format_string(
|
||||
node_name,
|
||||
is_biggest,
|
||||
short_paths,
|
||||
pretty_size.as_ref(),
|
||||
indentation
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
pub fn format_string(
|
||||
dir_name: &str,
|
||||
is_biggest: bool,
|
||||
short_paths: bool,
|
||||
size: &str,
|
||||
indentation: &str,
|
||||
) -> String {
|
||||
let printable_name = {
|
||||
if short_paths && dir_name.contains('/') {
|
||||
dir_name.split('/').last().unwrap()
|
||||
} else {
|
||||
dir_name
|
||||
}
|
||||
};
|
||||
format!(
|
||||
"{} {} {}",
|
||||
if is_biggest {
|
||||
Fixed(196).paint(size)
|
||||
} else {
|
||||
Fixed(7).paint(size)
|
||||
},
|
||||
indentation,
|
||||
printable_name,
|
||||
)
|
||||
}
|
||||
|
||||
fn human_readable_number(size: u64) -> String {
|
||||
for (i, u) in UNITS.iter().enumerate() {
|
||||
let marker = 1024u64.pow((UNITS.len() - i) as u32);
|
||||
if size >= marker {
|
||||
if size / marker < 10 {
|
||||
return format!("{:.1}{}", (size as f32 / marker as f32), u);
|
||||
} else {
|
||||
return format!("{}{}", (size / marker), u);
|
||||
}
|
||||
}
|
||||
}
|
||||
return format!("{}B", size);
|
||||
}
|
||||
|
||||
mod tests {
|
||||
#[allow(unused_imports)]
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_human_readable_number() {
|
||||
assert_eq!(human_readable_number(1), "1B");
|
||||
assert_eq!(human_readable_number(956), "956B");
|
||||
assert_eq!(human_readable_number(1004), "1004B");
|
||||
assert_eq!(human_readable_number(1024), "1.0K");
|
||||
assert_eq!(human_readable_number(1536), "1.5K");
|
||||
assert_eq!(human_readable_number(1024 * 512), "512K");
|
||||
assert_eq!(human_readable_number(1024 * 1024), "1.0M");
|
||||
assert_eq!(human_readable_number(1024 * 1024 * 1024 - 1), "1023M");
|
||||
assert_eq!(human_readable_number(1024 * 1024 * 1024 * 20), "20G");
|
||||
assert_eq!(human_readable_number(1024 * 1024 * 1024 * 1024), "1.0T");
|
||||
}
|
||||
}
|
||||
+63
-329
@@ -1,85 +1,48 @@
|
||||
// test:
|
||||
// recursive dirs that link to each other.
|
||||
// Pass in bad dir name
|
||||
// num to search for is less than num available
|
||||
// admin files.
|
||||
//
|
||||
extern crate ansi_term;
|
||||
#[macro_use]
|
||||
extern crate clap;
|
||||
extern crate assert_cli;
|
||||
extern crate walkdir;
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
use ansi_term::Colour::Fixed;
|
||||
use self::display::draw_it;
|
||||
use clap::{App, AppSettings, Arg};
|
||||
use std::io::{self, Write};
|
||||
use utils::{find_big_ones, get_dir_tree, sort};
|
||||
|
||||
use std::cmp;
|
||||
use std::cmp::Ordering;
|
||||
use std::fs;
|
||||
use std::fs::ReadDir;
|
||||
use std::io;
|
||||
mod display;
|
||||
mod utils;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct Node {
|
||||
dir: Dir,
|
||||
children: Vec<Node>,
|
||||
}
|
||||
impl Ord for Node {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
if self.dir.size > other.dir.size {
|
||||
Ordering::Less
|
||||
} else if self.dir.size < other.dir.size {
|
||||
Ordering::Greater
|
||||
} else {
|
||||
let my_slashes = self.dir.name.matches("/").count();
|
||||
let other_slashes = other.dir.name.matches("/").count();
|
||||
|
||||
if my_slashes > other_slashes {
|
||||
Ordering::Greater
|
||||
} else if my_slashes < other_slashes {
|
||||
Ordering::Less
|
||||
} else {
|
||||
if self.dir.name < other.dir.name {
|
||||
Ordering::Less
|
||||
} else if self.dir.name > other.dir.name {
|
||||
Ordering::Greater
|
||||
} else {
|
||||
Ordering::Equal
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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.dir.name, self.dir.size) == (&other.dir.name, other.dir.size)
|
||||
}
|
||||
}
|
||||
impl Eq for Node {}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct Dir {
|
||||
name: String,
|
||||
size: u64,
|
||||
}
|
||||
|
||||
static DEFAULT_NUMBER_OF_LINES: &'static str = &"15";
|
||||
static DEFAULT_NUMBER_OF_LINES: &'static str = "20";
|
||||
|
||||
fn main() {
|
||||
let options = App::new("Trailing args example")
|
||||
let options = App::new("Dust")
|
||||
.setting(AppSettings::TrailingVarArg)
|
||||
.arg(
|
||||
Arg::with_name("depth")
|
||||
.short("d")
|
||||
.long("depth")
|
||||
.help("Depth to show")
|
||||
.takes_value(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("number_of_lines")
|
||||
.short("n")
|
||||
.long("number-of-lines")
|
||||
.help("Number of lines of output to show")
|
||||
.takes_value(true)
|
||||
.default_value(DEFAULT_NUMBER_OF_LINES),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("display_full_paths")
|
||||
.short("p")
|
||||
.long("full-paths")
|
||||
.help("If set sub directories will not have their path shortened"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("display_apparent_size")
|
||||
.short("s")
|
||||
.long("apparent-size")
|
||||
.help("If set will use file length. Otherwise we use blocks"),
|
||||
)
|
||||
.arg(Arg::with_name("inputs").multiple(true))
|
||||
.get_matches();
|
||||
|
||||
@@ -89,276 +52,47 @@ fn main() {
|
||||
Some(r) => r.collect(),
|
||||
}
|
||||
};
|
||||
|
||||
let number_of_lines = value_t!(options.value_of("number_of_lines"), usize).unwrap();
|
||||
|
||||
let (permissions, results) = get_dir_tree(filenames);
|
||||
let slice_it = find_big_ones(&results, number_of_lines);
|
||||
display(permissions, slice_it);
|
||||
}
|
||||
|
||||
fn get_dir_tree(filenames: Vec<&str>) -> (bool, Vec<Node>) {
|
||||
let mut permissions = true;
|
||||
let mut results = vec![];
|
||||
for b in filenames {
|
||||
let mut new_name = String::from(b);
|
||||
while new_name.chars().last() == Some('/') && new_name.len() != 1 {
|
||||
new_name.pop();
|
||||
}
|
||||
let (hp, data) = examine_dir_str(new_name);
|
||||
permissions = permissions && hp;
|
||||
results.push(data);
|
||||
}
|
||||
(permissions, results)
|
||||
}
|
||||
|
||||
fn examine_dir_str(loc: String) -> (bool, Node) {
|
||||
let mut inodes: HashSet<u64> = HashSet::new();
|
||||
let (hp, result) = examine_dir(fs::read_dir(&loc), &mut inodes);
|
||||
|
||||
// This needs to be folded into the below recursive call somehow
|
||||
let new_size = result.iter().fold(0, |a, b| a + b.dir.size);
|
||||
(
|
||||
hp,
|
||||
Node {
|
||||
dir: Dir {
|
||||
name: loc,
|
||||
size: new_size,
|
||||
},
|
||||
children: result,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn get_metadata_blocks_and_inode(d: &std::fs::DirEntry) -> Option<(u64, u64)> {
|
||||
use std::os::linux::fs::MetadataExt;
|
||||
match d.metadata().ok() {
|
||||
Some(md) => Some((md.len(), md.st_ino())),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "unix")]
|
||||
fn get_metadata_blocks_and_inode(d: &std::fs::DirEntry) -> Option<(u64, u64)> {
|
||||
use std::os::unix::fs::MetadataExt;
|
||||
match d.metadata().ok() {
|
||||
Some(md) => Some((md.len(), md.ino())),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn get_metadata_blocks_and_inode(d: &std::fs::DirEntry) -> Option<(u64, u64)> {
|
||||
use std::os::macos::fs::MetadataExt;
|
||||
match d.metadata().ok() {
|
||||
Some(md) => Some((md.len(), md.st_ino())),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "linux", target_os = "unix", target_os = "macos")))]
|
||||
fn get_metadata_blocks_and_inode(_d: &std::fs::DirEntry) -> Option<(u64, u64)> {
|
||||
match _d.metadata().ok() {
|
||||
Some(md) => Some((md.len(), 0)), //move to option not 0
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn examine_dir(a_dir: io::Result<ReadDir>, inodes: &mut HashSet<u64>) -> (bool, Vec<Node>) {
|
||||
let mut result = vec![];
|
||||
let mut have_permission = true;
|
||||
|
||||
if a_dir.is_ok() {
|
||||
let paths = a_dir.unwrap();
|
||||
for dd in paths {
|
||||
match dd {
|
||||
Ok(d) => {
|
||||
let file_type = d.file_type().ok();
|
||||
let maybe_size_and_inode = get_metadata_blocks_and_inode(&d);
|
||||
|
||||
match (file_type, maybe_size_and_inode) {
|
||||
(Some(file_type), Some((size, inode))) => {
|
||||
let s = d.path().to_string_lossy().to_string();
|
||||
if inodes.contains(&inode) {
|
||||
continue;
|
||||
}
|
||||
inodes.insert(inode);
|
||||
|
||||
if d.path().is_dir() && !file_type.is_symlink() {
|
||||
let (hp, recursive) = examine_dir(fs::read_dir(d.path()), inodes);
|
||||
have_permission = have_permission && hp;
|
||||
let new_size = recursive.iter().fold(size, |a, b| a + b.dir.size);
|
||||
result.push(Node {
|
||||
dir: Dir {
|
||||
name: s,
|
||||
size: new_size,
|
||||
},
|
||||
children: recursive,
|
||||
})
|
||||
} else {
|
||||
result.push(Node {
|
||||
dir: Dir {
|
||||
name: s,
|
||||
size: size,
|
||||
},
|
||||
children: vec![],
|
||||
})
|
||||
}
|
||||
}
|
||||
(_, None) => have_permission = false,
|
||||
(_, _) => (),
|
||||
}
|
||||
}
|
||||
Err(_) => (),
|
||||
let depth = {
|
||||
if options.is_present("depth") {
|
||||
match value_t!(options.value_of("depth"), u64) {
|
||||
Ok(v) => Some(v + 1),
|
||||
Err(_) => None,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
have_permission = false;
|
||||
}
|
||||
(have_permission, result)
|
||||
}
|
||||
|
||||
// We start with a list of root directories - these must be the biggest folders
|
||||
// We then repeadedly merge in the children of the biggest directory - Each iteration
|
||||
// the next biggest directory's children are merged in.
|
||||
fn find_big_ones<'a>(l: &'a Vec<Node>, max_to_show: usize) -> Vec<&Node> {
|
||||
let mut new_l: Vec<&Node> = l.iter().map(|a| a).collect();
|
||||
new_l.sort();
|
||||
|
||||
for processed_pointer in 0..max_to_show {
|
||||
if new_l.len() == processed_pointer {
|
||||
break;
|
||||
}
|
||||
// Must be a list of pointers into new_l otherwise b_list will go out of scope
|
||||
// when it is deallocated
|
||||
let mut b_list: Vec<&Node> = new_l[processed_pointer]
|
||||
.children
|
||||
.iter()
|
||||
.map(|a| a)
|
||||
.collect();
|
||||
new_l.extend(b_list);
|
||||
new_l.sort();
|
||||
/*println!(
|
||||
"{:?} -------------------",
|
||||
new_l
|
||||
.iter()
|
||||
.map(|a| a.dir.size.to_string() + ": " + &a.dir.name)
|
||||
.collect::<Vec<String>>()
|
||||
);*/
|
||||
}
|
||||
if new_l.len() > max_to_show {
|
||||
new_l[0..max_to_show + 1].to_vec()
|
||||
} else {
|
||||
new_l
|
||||
}
|
||||
}
|
||||
|
||||
fn display(permissions: bool, to_display: Vec<&Node>) -> () {
|
||||
if !permissions {
|
||||
eprintln!("Did not have permissions for all directories");
|
||||
}
|
||||
|
||||
display_node(to_display[0], &to_display, true, 1, "")
|
||||
}
|
||||
|
||||
fn display_node<S: Into<String>>(
|
||||
node_to_print: &Node,
|
||||
to_display: &Vec<&Node>,
|
||||
is_first: bool,
|
||||
depth: u8,
|
||||
indentation_str: S,
|
||||
) {
|
||||
let mut is = indentation_str.into();
|
||||
print_this_node(node_to_print, is_first, depth, is.as_ref());
|
||||
|
||||
is = is.replace("└──", " ");
|
||||
is = is.replace("├──", "│ ");
|
||||
|
||||
let printable_node_slashes = node_to_print.dir.name.matches("/").count();
|
||||
|
||||
let mut num_sibblings = to_display.iter().fold(0, |a, b| {
|
||||
if node_to_print.children.contains(b)
|
||||
&& b.dir.name.matches("/").count() == printable_node_slashes + 1
|
||||
{
|
||||
a + 1
|
||||
} else {
|
||||
a
|
||||
}
|
||||
});
|
||||
|
||||
let mut is_biggest = true;
|
||||
for node in to_display {
|
||||
if node_to_print.children.contains(node) {
|
||||
if node.dir.name.matches("/").count() == printable_node_slashes + 1 {
|
||||
num_sibblings -= 1;
|
||||
let tree_chars = {
|
||||
if num_sibblings == 0 {
|
||||
"└──"
|
||||
} else {
|
||||
"├──"
|
||||
}
|
||||
};
|
||||
display_node(
|
||||
&node,
|
||||
to_display,
|
||||
is_biggest,
|
||||
depth + 1,
|
||||
is.to_string() + tree_chars,
|
||||
);
|
||||
is_biggest = false;
|
||||
}
|
||||
None
|
||||
}
|
||||
};
|
||||
if options.is_present("depth")
|
||||
&& options.value_of("number_of_lines").unwrap() != DEFAULT_NUMBER_OF_LINES
|
||||
{
|
||||
io::stderr()
|
||||
.write(b"Use either -n for number of directories to show. Or -d for depth. Not both")
|
||||
.expect("Error writing to stderr. Oh the irony!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fn print_this_node(node_to_print: &Node, is_biggest: bool, depth: u8, indentation_str: &str) {
|
||||
let padded_size = format!("{:>5}", human_readable_number(node_to_print.dir.size),);
|
||||
println!(
|
||||
"{} {} {}",
|
||||
if is_biggest {
|
||||
Fixed(196).paint(padded_size)
|
||||
let use_apparent_size = options.is_present("display_apparent_size");
|
||||
let use_full_path = options.is_present("display_full_paths");
|
||||
|
||||
let (permissions, nodes, top_level_names) = get_dir_tree(&filenames, use_apparent_size);
|
||||
let sorted_data = sort(nodes);
|
||||
let biggest_ones = {
|
||||
if depth.is_none() {
|
||||
find_big_ones(sorted_data, number_of_lines)
|
||||
} else {
|
||||
Fixed(7).paint(padded_size)
|
||||
},
|
||||
indentation_str,
|
||||
Fixed(7)
|
||||
.on(Fixed(cmp::min(8, (depth) as u8) + 231))
|
||||
.paint(node_to_print.dir.name.to_string())
|
||||
sorted_data
|
||||
}
|
||||
};
|
||||
draw_it(
|
||||
permissions,
|
||||
!use_full_path,
|
||||
depth,
|
||||
top_level_names,
|
||||
biggest_ones,
|
||||
);
|
||||
}
|
||||
|
||||
fn human_readable_number(size: u64) -> (String) {
|
||||
let units = vec!["T", "G", "M", "K"]; //make static
|
||||
|
||||
//return format!("{}B", size);
|
||||
|
||||
for (i, u) in units.iter().enumerate() {
|
||||
let marker = 1024u64.pow((units.len() - i) as u32);
|
||||
if size >= marker {
|
||||
if size / marker < 10 {
|
||||
return format!("{:.1}{}", (size as f32 / marker as f32), u);
|
||||
} else {
|
||||
return format!("{}{}", (size / marker), u);
|
||||
}
|
||||
}
|
||||
}
|
||||
return format!("{}B", size);
|
||||
}
|
||||
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_human_readable_number() {
|
||||
assert_eq!(human_readable_number(1), "1B");
|
||||
assert_eq!(human_readable_number(956), "956B");
|
||||
assert_eq!(human_readable_number(1004), "1004B");
|
||||
assert_eq!(human_readable_number(1024), "1.0K");
|
||||
assert_eq!(human_readable_number(1536), "1.5K");
|
||||
assert_eq!(human_readable_number(1024 * 512), "512K");
|
||||
assert_eq!(human_readable_number(1024 * 1024), "1.0M");
|
||||
assert_eq!(human_readable_number(1024 * 1024 * 1024 - 1), "1023M");
|
||||
assert_eq!(human_readable_number(1024 * 1024 * 1024 * 20), "20G");
|
||||
assert_eq!(human_readable_number(1024 * 1024 * 1024 * 1024), "1.0T");
|
||||
}
|
||||
}
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
hello
|
||||
+274
@@ -0,0 +1,274 @@
|
||||
extern crate ansi_term;
|
||||
extern crate tempfile;
|
||||
use self::tempfile::Builder;
|
||||
use self::tempfile::TempDir;
|
||||
use super::*;
|
||||
use display::format_string;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::panic;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
|
||||
#[test]
|
||||
pub fn test_main() {
|
||||
assert_cli::Assert::main_binary()
|
||||
.with_args(&["src/test_dir"])
|
||||
.stdout()
|
||||
.is(main_output(true))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_main_long_paths() {
|
||||
assert_cli::Assert::main_binary()
|
||||
.with_args(&["-p", "src/test_dir"])
|
||||
.stdout()
|
||||
.is(main_output(false))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn main_output(short_paths: bool) -> String {
|
||||
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",
|
||||
" └──",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn main_output(short_paths: bool) -> String {
|
||||
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",
|
||||
" └──",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_apparent_size() {
|
||||
let r = format!(
|
||||
"{}",
|
||||
format_string(
|
||||
"src/test_dir/many/hello_file",
|
||||
true,
|
||||
true,
|
||||
" 6B",
|
||||
" ├──",
|
||||
),
|
||||
);
|
||||
|
||||
assert_cli::Assert::main_binary()
|
||||
.with_args(&["-s", "src/test_dir"])
|
||||
.stdout()
|
||||
.contains(r)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
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();
|
||||
file_path
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_soft_sym_link() {
|
||||
let dir = Builder::new().tempdir().unwrap();
|
||||
let file = build_temp_file(&dir);
|
||||
let dir_s = dir.path().to_str().unwrap();
|
||||
let file_path_s = file.to_str().unwrap();
|
||||
|
||||
let link_name = dir.path().join("the_link");
|
||||
let link_name_s = link_name.to_str().unwrap();
|
||||
let c = Command::new("ln")
|
||||
.arg("-s")
|
||||
.arg(file_path_s)
|
||||
.arg(link_name_s)
|
||||
.output();
|
||||
assert!(c.is_ok());
|
||||
|
||||
let r = soft_sym_link_output(dir_s, file_path_s, 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])
|
||||
.stdout()
|
||||
.contains(r)
|
||||
.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() {
|
||||
let dir = Builder::new().tempdir().unwrap();
|
||||
let file = build_temp_file(&dir);
|
||||
let dir_s = dir.path().to_str().unwrap();
|
||||
let file_path_s = file.to_str().unwrap();
|
||||
|
||||
let link_name = dir.path().join("the_link");
|
||||
let link_name_s = link_name.to_str().unwrap();
|
||||
let c = Command::new("ln")
|
||||
.arg(file_path_s)
|
||||
.arg(link_name_s)
|
||||
.output();
|
||||
assert!(c.is_ok());
|
||||
|
||||
let (r, r2) = hard_link_output(dir_s, file_path_s, link_name_s);
|
||||
|
||||
// Because this is a hard link the file and hard link look identicle. Therefore
|
||||
// we cannot guarantee which version will appear first.
|
||||
// TODO: Consider adding predictable itteration order (sort file entries by name?)
|
||||
let result = panic::catch_unwind(|| {
|
||||
assert_cli::Assert::main_binary()
|
||||
.with_args(&[dir_s])
|
||||
.stdout()
|
||||
.contains(r)
|
||||
.unwrap();
|
||||
});
|
||||
if result.is_err() {
|
||||
assert_cli::Assert::main_binary()
|
||||
.with_args(&[dir_s])
|
||||
.stdout()
|
||||
.contains(r2)
|
||||
.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
|
||||
#[test]
|
||||
pub fn test_recursive_sym_link() {
|
||||
let dir = Builder::new().tempdir().unwrap();
|
||||
let dir_s = dir.path().to_str().unwrap();
|
||||
|
||||
let link_name = dir.path().join("the_link");
|
||||
let link_name_s = link_name.to_str().unwrap();
|
||||
|
||||
let c = Command::new("ln")
|
||||
.arg("-s")
|
||||
.arg(dir_s)
|
||||
.arg(link_name_s)
|
||||
.output();
|
||||
assert!(c.is_ok());
|
||||
|
||||
assert_cli::Assert::main_binary()
|
||||
.with_args(&[dir_s])
|
||||
.stdout()
|
||||
.contains(recursive_sym_link_output(dir_s, link_name_s))
|
||||
.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", "└──",),
|
||||
)
|
||||
}
|
||||
#[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", "└──",),
|
||||
)
|
||||
}
|
||||
|
||||
// TODO: add test for bad path
|
||||
@@ -0,0 +1,105 @@
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::cmp::Ordering;
|
||||
|
||||
use walkdir::WalkDir;
|
||||
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
||||
mod platform;
|
||||
use self::platform::*;
|
||||
|
||||
pub fn get_dir_tree(
|
||||
filenames: &Vec<&str>,
|
||||
apparent_size: bool,
|
||||
) -> (bool, HashMap<String, u64>, Vec<String>) {
|
||||
let mut permissions = 0;
|
||||
let mut inodes: HashSet<(u64, u64)> = HashSet::new();
|
||||
let mut data: HashMap<String, u64> = HashMap::new();
|
||||
let mut top_level_names = Vec::new();
|
||||
|
||||
for b in filenames {
|
||||
let top_level_name = strip_end_slashes(b);
|
||||
examine_dir(
|
||||
&Path::new(&top_level_name).to_path_buf(),
|
||||
apparent_size,
|
||||
&mut inodes,
|
||||
&mut data,
|
||||
&mut permissions,
|
||||
);
|
||||
top_level_names.push(top_level_name);
|
||||
}
|
||||
(permissions == 0, data, top_level_names)
|
||||
}
|
||||
|
||||
fn strip_end_slashes(s: &str) -> String {
|
||||
let mut new_name = String::from(s);
|
||||
while new_name.chars().last() == Some('/') && new_name.len() != 1 {
|
||||
new_name.pop();
|
||||
}
|
||||
new_name
|
||||
}
|
||||
|
||||
fn examine_dir(
|
||||
top_dir: &PathBuf,
|
||||
apparent_size: bool,
|
||||
inodes: &mut HashSet<(u64, u64)>,
|
||||
data: &mut HashMap<String, u64>,
|
||||
permissions: &mut u64,
|
||||
) {
|
||||
for entry in WalkDir::new(top_dir) {
|
||||
match entry {
|
||||
Ok(e) => {
|
||||
let maybe_size_and_inode = get_metadata(&e, apparent_size);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
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).or_insert(0);
|
||||
*s += size;
|
||||
if e_path == *top_dir {
|
||||
break;
|
||||
}
|
||||
e_path.pop();
|
||||
}
|
||||
}
|
||||
None => *permissions += 1,
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn compare_tuple(a :&(String, u64), b: &(String, u64)) -> Ordering {
|
||||
let result = b.1.cmp(&a.1);
|
||||
if result == Ordering::Equal {
|
||||
a.0.cmp(&b.0)
|
||||
} else {
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sort<'a>(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| compare_tuple(&a, &b));
|
||||
new_l
|
||||
}
|
||||
|
||||
pub fn find_big_ones<'a>(new_l: Vec<(String, u64)>, max_to_show: usize) -> Vec<(String, u64)> {
|
||||
if max_to_show > 0 && new_l.len() > max_to_show {
|
||||
new_l[0..max_to_show + 1].to_vec()
|
||||
} else {
|
||||
new_l
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
use walkdir::DirEntry;
|
||||
|
||||
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
|
||||
512
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub fn get_metadata(d: &DirEntry, use_apparent_size: bool) -> Option<(u64, Option<(u64, u64)>)> {
|
||||
use std::os::linux::fs::MetadataExt;
|
||||
match d.metadata().ok() {
|
||||
Some(md) => {
|
||||
let inode = Some((md.st_ino(), md.st_dev()));
|
||||
if use_apparent_size {
|
||||
Some((md.len(), inode))
|
||||
} else {
|
||||
Some((md.st_blocks() * get_block_size(), inode))
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "unix")]
|
||||
pub fn get_metadata(d: &DirEntry, use_apparent_size: bool) -> Option<(u64, Option<(u64, u64)>)> {
|
||||
use std::os::unix::fs::MetadataExt;
|
||||
match d.metadata().ok() {
|
||||
Some(md) => {
|
||||
let inode = Some((md.ino(), md.dev()));
|
||||
if use_apparent_size {
|
||||
Some((md.len(), inode))
|
||||
} else {
|
||||
Some((md.blocks() * get_block_size(), inode))
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
pub fn get_metadata(d: &DirEntry, use_apparent_size: bool) -> Option<(u64, Option<(u64, u64)>)> {
|
||||
use std::os::macos::fs::MetadataExt;
|
||||
match d.metadata().ok() {
|
||||
Some(md) => {
|
||||
let inode = Some((md.st_ino(), md.st_dev()));
|
||||
if use_apparent_size {
|
||||
Some((md.len(), inode))
|
||||
} else {
|
||||
Some((md.st_blocks() * get_block_size(), inode))
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "linux", target_os = "unix", target_os = "macos")))]
|
||||
pub fn get_metadata(d: &DirEntry, _apparent: bool) -> Option<(u64, Option<(u64, u64)>)> {
|
||||
match d.metadata().ok() {
|
||||
Some(md) => Some((md.len(), None)),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user