checksum: Unify the handling of check-only flags

This commit is contained in:
Dorian Peron 2025-12-16 16:28:26 +01:00
parent 2b67abe741
commit d96ae60d21
3 changed files with 51 additions and 55 deletions

View file

@ -140,6 +140,20 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let check = matches.get_flag(options::CHECK);
let check_flag = |flag| match (check, matches.get_flag(flag)) {
(_, false) => Ok(false),
(true, true) => Ok(true),
(false, true) => Err(ChecksumError::CheckOnlyFlag(flag.into())),
};
// Each of the following flags are only expected in --check mode.
// If we encounter them otherwise, end with an error.
let ignore_missing = check_flag(options::IGNORE_MISSING)?;
let warn = check_flag(options::WARN)?;
let quiet = check_flag(options::QUIET)?;
let strict = check_flag(options::STRICT)?;
let status = check_flag(options::STATUS)?;
let algo_cli = matches
.get_one::<String>(options::ALGORITHM)
.map(AlgoKind::from_cksum)
@ -166,11 +180,6 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let text_flag = matches.get_flag(options::TEXT);
let binary_flag = matches.get_flag(options::BINARY);
let strict = matches.get_flag(options::STRICT);
let status = matches.get_flag(options::STATUS);
let warn = matches.get_flag(options::WARN);
let ignore_missing = matches.get_flag(options::IGNORE_MISSING);
let quiet = matches.get_flag(options::QUIET);
let tag = matches.get_flag(options::TAG);
if tag || binary_flag || text_flag {
@ -191,6 +200,11 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
// Not --check
// Print hardware debug info if requested
if matches.get_flag(options::DEBUG) {
print_cpu_debug_info();
}
// Set the default algorithm to CRC when not '--check'ing.
let algo_kind = algo_cli.unwrap_or(AlgoKind::Crc);
@ -199,22 +213,15 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let algo = SizedAlgoKind::from_unsized(algo_kind, length)?;
let line_ending = LineEnding::from_zero_flag(matches.get_flag(options::ZERO));
let output_format = figure_out_output_format(
algo,
tag,
binary,
matches.get_flag(options::RAW),
matches.get_flag(options::BASE64),
);
// Print hardware debug info if requested
if matches.get_flag(options::DEBUG) {
print_cpu_debug_info();
}
let opts = ChecksumComputeOptions {
algo_kind: algo,
output_format,
output_format: figure_out_output_format(
algo,
tag,
binary,
matches.get_flag(options::RAW),
matches.get_flag(options::BASE64),
),
line_ending,
};

View file

@ -164,16 +164,27 @@ pub fn uumain(mut args: impl uucore::Args) -> UResult<()> {
binary_flag_default
};
let check = matches.get_flag("check");
let status = matches.get_flag("status");
let quiet = matches.get_flag("quiet");
let strict = matches.get_flag("strict");
let warn = matches.get_flag("warn");
let ignore_missing = matches.get_flag("ignore-missing");
if ignore_missing && !check {
// --ignore-missing needs -c
return Err(ChecksumError::IgnoreNotCheck.into());
}
let check_flag = |flag| match (check, matches.get_flag(flag)) {
(_, false) => Ok(false),
(true, true) => Ok(true),
(false, true) => Err(ChecksumError::CheckOnlyFlag(flag.into())),
};
// Each of the following flags are only expected in --check mode.
// If we encounter them otherwise, end with an error.
let ignore_missing = check_flag("ignore-missing")?;
let warn = check_flag("warn")?;
let quiet = check_flag("quiet")?;
let strict = check_flag("strict")?;
let status = check_flag("status")?;
let files = matches.get_many::<OsString>(options::FILE).map_or_else(
// No files given, read from stdin.
|| Box::new(iter::once(OsStr::new("-"))) as Box<dyn Iterator<Item = &OsStr>>,
// At least one file given, read from them.
|files| Box::new(files.map(OsStr::new)) as Box<dyn Iterator<Item = &OsStr>>,
);
if check {
// on Windows, allow --binary/--text to be used with --check
@ -188,13 +199,6 @@ pub fn uumain(mut args: impl uucore::Args) -> UResult<()> {
}
}
// Execute the checksum validation based on the presence of files or the use of stdin
// Determine the source of input: a list of files or stdin.
let input = matches.get_many::<OsString>(options::FILE).map_or_else(
|| iter::once(OsStr::new("-")).collect::<Vec<_>>(),
|files| files.map(OsStr::new).collect::<Vec<_>>(),
);
let verbose = ChecksumVerbose::new(status, quiet, warn);
let opts = ChecksumValidateOptions {
@ -204,16 +208,11 @@ pub fn uumain(mut args: impl uucore::Args) -> UResult<()> {
};
// Execute the checksum validation
return perform_checksum_validation(input.iter().copied(), Some(algo_kind), length, opts);
} else if quiet {
return Err(ChecksumError::QuietNotCheck.into());
} else if strict {
return Err(ChecksumError::StrictNotCheck.into());
return perform_checksum_validation(files, Some(algo_kind), length, opts);
}
let line_ending = LineEnding::from_zero_flag(matches.get_flag("zero"));
let algo = SizedAlgoKind::from_unsized(algo_kind, length)?;
let line_ending = LineEnding::from_zero_flag(matches.get_flag("zero"));
let opts = ChecksumComputeOptions {
algo_kind: algo,
@ -227,13 +226,6 @@ pub fn uumain(mut args: impl uucore::Args) -> UResult<()> {
line_ending,
};
let files = matches.get_many::<OsString>(options::FILE).map_or_else(
// No files given, read from stdin.
|| Box::new(iter::once(OsStr::new("-"))) as Box<dyn Iterator<Item = &OsStr>>,
// At least one file given, read from them.
|files| Box::new(files.map(OsStr::new)) as Box<dyn Iterator<Item = &OsStr>>,
);
// Show the hashsum of the input
perform_checksum_computation(opts, files)
}

View file

@ -373,12 +373,9 @@ impl SizedAlgoKind {
pub enum ChecksumError {
#[error("the --raw option is not supported with multiple files")]
RawMultipleFiles,
#[error("the --ignore-missing option is meaningful only when verifying checksums")]
IgnoreNotCheck,
#[error("the --strict option is meaningful only when verifying checksums")]
StrictNotCheck,
#[error("the --quiet option is meaningful only when verifying checksums")]
QuietNotCheck,
#[error("the --{0} option is meaningful only when verifying checksums")]
CheckOnlyFlag(String),
// --length sanitization errors
#[error("--length required for {}", .0.quote())]