summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwngr <oliver@wngr.de>2019-09-11 20:36:12 +0200
committerDavid Peter <sharkdp@users.noreply.github.com>2019-09-20 23:28:01 +0200
commitda731abb2b42b05e540f90d3b403c51b955b75d2 (patch)
tree29b1acf8c133f07f965d4fa8bae4f1e70acaefa6
parenta35d58d543e3e836aabdd748cc76a3290e2088e1 (diff)
Add verbose flag and hide error messages behind it. Add additional output warning, if there were I/O errors while walking the tree.
-rw-r--r--src/main.rs42
-rw-r--r--src/walk/mod.rs34
2 files changed, 55 insertions, 21 deletions
diff --git a/src/main.rs b/src/main.rs
index 9dc48d2..48badfd 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -14,12 +14,39 @@ use humansize::{file_size_opts, FileSize};
use walk::Walk;
-fn print_result(size: u64) {
+fn print_result(size: u64, errors: &[walk::Err], verbose: bool) {
+ let tainted = errors.iter().any(|x| {
+ if let walk::Err::NoMetadataForPath(_) = x {
+ true
+ } else {
+ false
+ }
+ });
println!(
"{} ({} bytes)",
size.file_size(file_size_opts::DECIMAL).unwrap(),
size
);
+ if verbose {
+ for err in errors {
+ match err {
+ walk::Err::NoMetadataForPath(path) => {
+ eprintln!(
+ "diskus: could not retrieve metadata for path '{}'",
+ path.to_string_lossy()
+ );
+ }
+ walk::Err::CouldNotReadDir(path) => {
+ eprintln!(
+ "diskus: could not read contents of directory '{}'",
+ path.to_string_lossy()
+ );
+ }
+ }
+ }
+ } else if tainted {
+ println!("Warning, results may be tainted. Try running with --verbose.");
+ }
}
fn main() {
@@ -42,6 +69,13 @@ fn main() {
.value_name("N")
.takes_value(true)
.help("Set the number of threads (default: 3 x num cores)"),
+ )
+ .arg(
+ Arg::with_name("verbose")
+ .long("verbose")
+ .short("v")
+ .takes_value(false)
+ .help("Emits verbose output"),
);
let matches = app.get_matches();
@@ -61,7 +95,9 @@ fn main() {
.map(|paths| paths.map(PathBuf::from).collect())
.unwrap_or_else(|| vec![PathBuf::from(".")]);
+ let verbose = matches.is_present("verbose");
+
let walk = Walk::new(&paths, num_threads);
- let size = walk.run();
- print_result(size);
+ let (size, errors) = walk.run();
+ print_result(size, &errors, verbose);
}
diff --git a/src/walk/mod.rs b/src/walk/mod.rs
index 7fc3256..87e4bcb 100644
--- a/src/walk/mod.rs
+++ b/src/walk/mod.rs
@@ -21,11 +21,14 @@ mod unix;
#[cfg(not(target_os = "windows"))]
pub use self::unix::*;
-enum Message {
- SizeEntry(Option<UniqueID>, u64),
+pub enum Err {
NoMetadataForPath(PathBuf),
CouldNotReadDir(PathBuf),
}
+enum Message {
+ SizeEntry(Option<UniqueID>, u64),
+ Error { err: Err },
+}
fn walk(tx: channel::Sender<Message>, entries: &[PathBuf]) {
entries.into_par_iter().for_each_with(tx, |tx_ref, entry| {
@@ -48,7 +51,9 @@ fn walk(tx: channel::Sender<Message>, entries: &[PathBuf]) {
}
Err(_) => {
tx_ref
- .send(Message::CouldNotReadDir(entry.clone()))
+ .send(Message::Error {
+ err: Err::CouldNotReadDir(entry.clone()),
+ })
.unwrap();
}
}
@@ -57,7 +62,9 @@ fn walk(tx: channel::Sender<Message>, entries: &[PathBuf]) {
};
} else {
tx_ref
- .send(Message::NoMetadataForPath(entry.clone()))
+ .send(Message::Error {
+ err: Err::NoMetadataForPath(entry.clone()),
+ })
.unwrap();
};
});
@@ -76,12 +83,13 @@ impl<'a> Walk<'a> {
}
}
- pub fn run(&self) -> u64 {
+ pub fn run(&self) -> (u64, Vec<Err>) {
let (tx, rx) = channel::unbounded();
let receiver_thread = thread::spawn(move || {
let mut total = 0;
let mut ids = HashSet::new();
+ let mut error_messages: Vec<Err> = Vec::new();
for msg in rx {
match msg {
Message::SizeEntry(unique_id, size) => {
@@ -94,22 +102,12 @@ impl<'a> Walk<'a> {
total += size;
}
}
- Message::NoMetadataForPath(path) => {
- eprintln!(
- "diskus: could not retrieve metadata for path '{}'",
- path.to_string_lossy()
- );
- }
- Message::CouldNotReadDir(path) => {
- eprintln!(
- "diskus: could not read contents of directory '{}'",
- path.to_string_lossy()
- );
+ Message::Error { err } => {
+ error_messages.push(err);
}
}
}
-
- total
+ (total, error_messages)
});
let pool = rayon::ThreadPoolBuilder::new()