mirror of
https://github.com/BLAKE3-team/BLAKE3
synced 2024-06-02 22:56:02 +02:00
Add --check summary of failures
Add a warning to stderr at the end similar to other *sum utilities when --check is used and some files failed verification. At least the last part of the comment above check_one_checkfile seemed to be incorrect so I removed that comment. Fixes #283
This commit is contained in:
parent
c303437aab
commit
4c819d01bc
|
@ -490,8 +490,8 @@ fn hash_one_input(path: &Path, args: &Args) -> Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true for success. Having a boolean return value here, instead of
|
// Returns true for success. Having a boolean return value here, instead of
|
||||||
// passing down the some_file_failed reference, makes it less likely that we
|
// passing down the files_failed reference, makes it less likely that we might
|
||||||
// might forget to set it in some error condition.
|
// forget to set it in some error condition.
|
||||||
fn check_one_line(line: &str, args: &Args) -> bool {
|
fn check_one_line(line: &str, args: &Args) -> bool {
|
||||||
let parse_result = parse_check_line(&line);
|
let parse_result = parse_check_line(&line);
|
||||||
let ParsedCheckLine {
|
let ParsedCheckLine {
|
||||||
|
@ -537,7 +537,7 @@ fn check_one_line(line: &str, args: &Args) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_one_checkfile(path: &Path, args: &Args, some_file_failed: &mut bool) -> Result<()> {
|
fn check_one_checkfile(path: &Path, args: &Args, files_failed: &mut i64) -> Result<()> {
|
||||||
let checkfile_input = Input::open(path, args)?;
|
let checkfile_input = Input::open(path, args)?;
|
||||||
let mut bufreader = io::BufReader::new(checkfile_input);
|
let mut bufreader = io::BufReader::new(checkfile_input);
|
||||||
let mut line = String::new();
|
let mut line = String::new();
|
||||||
|
@ -551,7 +551,7 @@ fn check_one_checkfile(path: &Path, args: &Args, some_file_failed: &mut bool) ->
|
||||||
// return, so it doesn't return a Result.
|
// return, so it doesn't return a Result.
|
||||||
let success = check_one_line(&line, args);
|
let success = check_one_line(&line, args);
|
||||||
if !success {
|
if !success {
|
||||||
*some_file_failed = true;
|
*files_failed += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -564,16 +564,11 @@ fn main() -> Result<()> {
|
||||||
}
|
}
|
||||||
let thread_pool = thread_pool_builder.build()?;
|
let thread_pool = thread_pool_builder.build()?;
|
||||||
thread_pool.install(|| {
|
thread_pool.install(|| {
|
||||||
let mut some_file_failed = false;
|
let mut files_failed = 0i64;
|
||||||
// Note that file_args automatically includes `-` if nothing is given.
|
// Note that file_args automatically includes `-` if nothing is given.
|
||||||
for path in &args.file_args {
|
for path in &args.file_args {
|
||||||
if args.check() {
|
if args.check() {
|
||||||
// A hash mismatch or a failure to read a hashed file will be
|
check_one_checkfile(path, &args, &mut files_failed)?;
|
||||||
// printed in the checkfile loop, and will not propagate here.
|
|
||||||
// This is similar to the explicit error handling we do in the
|
|
||||||
// hashing case immediately below. In these cases,
|
|
||||||
// some_file_failed will be set to false.
|
|
||||||
check_one_checkfile(path, &args, &mut some_file_failed)?;
|
|
||||||
} else {
|
} else {
|
||||||
// Errors encountered in hashing are tolerated and printed to
|
// Errors encountered in hashing are tolerated and printed to
|
||||||
// stderr. This allows e.g. `b3sum *` to print errors for
|
// stderr. This allows e.g. `b3sum *` to print errors for
|
||||||
|
@ -581,12 +576,15 @@ fn main() -> Result<()> {
|
||||||
// errors we'll still return non-zero at the end.
|
// errors we'll still return non-zero at the end.
|
||||||
let result = hash_one_input(path, &args);
|
let result = hash_one_input(path, &args);
|
||||||
if let Err(e) = result {
|
if let Err(e) = result {
|
||||||
some_file_failed = true;
|
files_failed += 1;
|
||||||
eprintln!("{}: {}: {}", NAME, path.to_string_lossy(), e);
|
eprintln!("{}: {}: {}", NAME, path.to_string_lossy(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::process::exit(if some_file_failed { 1 } else { 0 });
|
if args.check() && files_failed > 0 {
|
||||||
|
eprintln!("{}: WARNING {} computed checksum{} did NOT match", NAME, files_failed, if files_failed == 1 {""} else {"s"});
|
||||||
|
}
|
||||||
|
std::process::exit(if files_failed > 0 { 1 } else { 0 });
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -420,7 +420,7 @@ fn test_check() {
|
||||||
c/d: OK\n";
|
c/d: OK\n";
|
||||||
assert!(!output.status.success());
|
assert!(!output.status.success());
|
||||||
assert_eq!(expected_check_failure, stdout);
|
assert_eq!(expected_check_failure, stdout);
|
||||||
assert_eq!("", stderr);
|
assert_eq!("b3sum: WARNING 1 computed checksum did NOT match\n", stderr);
|
||||||
|
|
||||||
// Delete one of the files and check again.
|
// Delete one of the files and check again.
|
||||||
fs::remove_file(dir.path().join("b")).unwrap();
|
fs::remove_file(dir.path().join("b")).unwrap();
|
||||||
|
@ -442,7 +442,7 @@ fn test_check() {
|
||||||
);
|
);
|
||||||
assert!(!output.status.success());
|
assert!(!output.status.success());
|
||||||
assert_eq!(expected_check_failure, stdout);
|
assert_eq!(expected_check_failure, stdout);
|
||||||
assert_eq!("", stderr);
|
assert_eq!("b3sum: WARNING 1 computed checksum did NOT match\n", stderr);
|
||||||
|
|
||||||
// Confirm that --quiet suppresses the OKs but not the FAILEDs.
|
// Confirm that --quiet suppresses the OKs but not the FAILEDs.
|
||||||
let output = cmd!(b3sum_exe(), "--check", "--quiet", &checkfile_path)
|
let output = cmd!(b3sum_exe(), "--check", "--quiet", &checkfile_path)
|
||||||
|
@ -457,7 +457,7 @@ fn test_check() {
|
||||||
let expected_check_failure = format!("b: FAILED ({})\n", open_file_error);
|
let expected_check_failure = format!("b: FAILED ({})\n", open_file_error);
|
||||||
assert!(!output.status.success());
|
assert!(!output.status.success());
|
||||||
assert_eq!(expected_check_failure, stdout);
|
assert_eq!(expected_check_failure, stdout);
|
||||||
assert_eq!("", stderr);
|
assert_eq!("b3sum: WARNING 1 computed checksum did NOT match\n", stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -472,9 +472,12 @@ fn test_check_invalid_characters() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let stdout = std::str::from_utf8(&output.stdout).unwrap();
|
let stdout = std::str::from_utf8(&output.stdout).unwrap();
|
||||||
let stderr = std::str::from_utf8(&output.stderr).unwrap();
|
let stderr = std::str::from_utf8(&output.stderr).unwrap();
|
||||||
|
let expected_stderr = "\
|
||||||
|
b3sum: Null character in path\n\
|
||||||
|
b3sum: WARNING 1 computed checksum did NOT match\n";
|
||||||
assert!(!output.status.success());
|
assert!(!output.status.success());
|
||||||
assert_eq!("", stdout);
|
assert_eq!("", stdout);
|
||||||
assert_eq!("b3sum: Null character in path\n", stderr);
|
assert_eq!(expected_stderr, stderr);
|
||||||
|
|
||||||
// Check that a Unicode replacement character in the path fails.
|
// Check that a Unicode replacement character in the path fails.
|
||||||
let output = cmd!(b3sum_exe(), "--check")
|
let output = cmd!(b3sum_exe(), "--check")
|
||||||
|
@ -486,9 +489,12 @@ fn test_check_invalid_characters() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let stdout = std::str::from_utf8(&output.stdout).unwrap();
|
let stdout = std::str::from_utf8(&output.stdout).unwrap();
|
||||||
let stderr = std::str::from_utf8(&output.stderr).unwrap();
|
let stderr = std::str::from_utf8(&output.stderr).unwrap();
|
||||||
|
let expected_stderr = "\
|
||||||
|
b3sum: Unicode replacement character in path\n\
|
||||||
|
b3sum: WARNING 1 computed checksum did NOT match\n";
|
||||||
assert!(!output.status.success());
|
assert!(!output.status.success());
|
||||||
assert_eq!("", stdout);
|
assert_eq!("", stdout);
|
||||||
assert_eq!("b3sum: Unicode replacement character in path\n", stderr);
|
assert_eq!(expected_stderr, stderr);
|
||||||
|
|
||||||
// Check that an invalid escape sequence in the path fails.
|
// Check that an invalid escape sequence in the path fails.
|
||||||
let output = cmd!(b3sum_exe(), "--check")
|
let output = cmd!(b3sum_exe(), "--check")
|
||||||
|
@ -500,9 +506,12 @@ fn test_check_invalid_characters() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let stdout = std::str::from_utf8(&output.stdout).unwrap();
|
let stdout = std::str::from_utf8(&output.stdout).unwrap();
|
||||||
let stderr = std::str::from_utf8(&output.stderr).unwrap();
|
let stderr = std::str::from_utf8(&output.stderr).unwrap();
|
||||||
|
let expected_stderr = "\
|
||||||
|
b3sum: Invalid backslash escape\n\
|
||||||
|
b3sum: WARNING 1 computed checksum did NOT match\n";
|
||||||
assert!(!output.status.success());
|
assert!(!output.status.success());
|
||||||
assert_eq!("", stdout);
|
assert_eq!("", stdout);
|
||||||
assert_eq!("b3sum: Invalid backslash escape\n", stderr);
|
assert_eq!(expected_stderr, stderr);
|
||||||
|
|
||||||
// Windows also forbids literal backslashes. Check for that if and only if
|
// Windows also forbids literal backslashes. Check for that if and only if
|
||||||
// we're on Windows.
|
// we're on Windows.
|
||||||
|
@ -516,9 +525,12 @@ fn test_check_invalid_characters() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let stdout = std::str::from_utf8(&output.stdout).unwrap();
|
let stdout = std::str::from_utf8(&output.stdout).unwrap();
|
||||||
let stderr = std::str::from_utf8(&output.stderr).unwrap();
|
let stderr = std::str::from_utf8(&output.stderr).unwrap();
|
||||||
|
let expected_stderr = "\
|
||||||
|
b3sum: Backslash in path\n\
|
||||||
|
b3sum: WARNING 1 computed checksum did NOT match\n";
|
||||||
assert!(!output.status.success());
|
assert!(!output.status.success());
|
||||||
assert_eq!("", stdout);
|
assert_eq!("", stdout);
|
||||||
assert_eq!("b3sum: Backslash in path\n", stderr);
|
assert_eq!(expected_stderr, stderr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue