diff --git a/Cargo.lock b/Cargo.lock index e763db08a..15df13ee7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3295,6 +3295,7 @@ dependencies = [ "clap", "codspeed-divan-compat", "fluent", + "uu_checksum_common", "uucore", ] diff --git a/src/uu/cksum/Cargo.toml b/src/uu/cksum/Cargo.toml index 1c343181c..5f509e313 100644 --- a/src/uu/cksum/Cargo.toml +++ b/src/uu/cksum/Cargo.toml @@ -25,6 +25,7 @@ uucore = { workspace = true, features = [ "sum", "hardware", ] } +uu_checksum_common = { workspace = true } fluent = { workspace = true } [dev-dependencies] diff --git a/src/uu/cksum/locales/en-US.ftl b/src/uu/cksum/locales/en-US.ftl index 834cd77b0..aece6fc5b 100644 --- a/src/uu/cksum/locales/en-US.ftl +++ b/src/uu/cksum/locales/en-US.ftl @@ -12,19 +12,3 @@ cksum-after-help = DIGEST determines the digest algorithm and default output for - sha3: (only available through cksum) - blake2b: (equivalent to b2sum) - sm3: (only available through cksum) - -# Help messages -cksum-help-algorithm = select the digest type to use. See DIGEST below -cksum-help-untagged = create a reversed style checksum, without digest type -cksum-help-tag = create a BSD style checksum, undo --untagged (default) -cksum-help-length = digest length in bits; must not exceed the max for the blake2 algorithm and must be a multiple of 8 -cksum-help-raw = emit a raw binary digest, not hexadecimal -cksum-help-strict = exit non-zero for improperly formatted checksum lines -cksum-help-check = read hashsums from the FILEs and check them -cksum-help-base64 = emit a base64 digest, not hexadecimal -cksum-help-warn = warn about improperly formatted checksum lines -cksum-help-status = don't output anything, status code shows success -cksum-help-quiet = don't print OK for each successfully verified file -cksum-help-ignore-missing = don't fail or report status for missing files -cksum-help-zero = end each output line with NUL, not newline, and disable file name escaping -cksum-help-debug = print CPU hardware capability detection info used by cksum diff --git a/src/uu/cksum/locales/fr-FR.ftl b/src/uu/cksum/locales/fr-FR.ftl index 01136f606..bbc12e59c 100644 --- a/src/uu/cksum/locales/fr-FR.ftl +++ b/src/uu/cksum/locales/fr-FR.ftl @@ -12,19 +12,3 @@ cksum-after-help = DIGEST détermine l'algorithme de condensé et le format de s - sha3 : (disponible uniquement via cksum) - blake2b : (équivalent à b2sum) - sm3 : (disponible uniquement via cksum) - -# Messages d'aide -cksum-help-algorithm = sélectionner le type de condensé à utiliser. Voir DIGEST ci-dessous -cksum-help-untagged = créer une somme de contrôle de style inversé, sans type de condensé -cksum-help-tag = créer une somme de contrôle de style BSD, annuler --untagged (par défaut) -cksum-help-length = longueur du condensé en bits ; ne doit pas dépasser le maximum pour l'algorithme blake2 et doit être un multiple de 8 -cksum-help-raw = émettre un condensé binaire brut, pas hexadécimal -cksum-help-strict = sortir avec un code non-zéro pour les lignes de somme de contrôle mal formatées -cksum-help-check = lire les sommes de hachage des FICHIERs et les vérifier -cksum-help-base64 = émettre un condensé base64, pas hexadécimal -cksum-help-warn = avertir des lignes de somme de contrôle mal formatées -cksum-help-status = ne rien afficher, le code de statut indique le succès -cksum-help-quiet = ne pas afficher OK pour chaque fichier vérifié avec succès -cksum-help-ignore-missing = ne pas échouer ou signaler le statut pour les fichiers manquants -cksum-help-zero = terminer chaque ligne de sortie avec NUL, pas un saut de ligne, et désactiver l'échappement des noms de fichiers -cksum-help-debug = afficher les informations de débogage sur la détection de la prise en charge matérielle du processeur diff --git a/src/uu/cksum/src/cksum.rs b/src/uu/cksum/src/cksum.rs index 2032d0662..0f9fdee5f 100644 --- a/src/uu/cksum/src/cksum.rs +++ b/src/uu/cksum/src/cksum.rs @@ -5,23 +5,18 @@ // spell-checker:ignore (ToDO) fname, algo, bitlen -use clap::builder::ValueParser; -use clap::{Arg, ArgAction, Command}; -use std::ffi::{OsStr, OsString}; -use uucore::checksum::compute::{ - ChecksumComputeOptions, OutputFormat, perform_checksum_computation, -}; -use uucore::checksum::validate::{ - ChecksumValidateOptions, ChecksumVerbose, perform_checksum_validation, -}; +use std::ffi::OsStr; + +use clap::Command; +use uu_checksum_common::{ChecksumCommand, checksum_main, default_checksum_app, options}; + +use uucore::checksum::compute::OutputFormat; use uucore::checksum::{ - AlgoKind, ChecksumError, SUPPORTED_ALGORITHMS, SizedAlgoKind, calculate_blake2b_length_str, - sanitize_sha2_sha3_length_str, + AlgoKind, ChecksumError, calculate_blake2b_length_str, sanitize_sha2_sha3_length_str, }; use uucore::error::UResult; use uucore::hardware::{HasHardwareFeatures as _, SimdPolicy}; -use uucore::line_ending::LineEnding; -use uucore::{format_usage, show_error, translate}; +use uucore::{show_error, translate}; /// Print CPU hardware capability detection information to stderr /// This matches GNU cksum's --debug behavior @@ -47,26 +42,6 @@ fn print_cpu_debug_info() { } } -mod options { - pub const ALGORITHM: &str = "algorithm"; - pub const FILE: &str = "file"; - pub const UNTAGGED: &str = "untagged"; - pub const TAG: &str = "tag"; - pub const LENGTH: &str = "length"; - pub const RAW: &str = "raw"; - pub const BASE64: &str = "base64"; - pub const CHECK: &str = "check"; - pub const STRICT: &str = "strict"; - pub const TEXT: &str = "text"; - pub const BINARY: &str = "binary"; - pub const STATUS: &str = "status"; - pub const WARN: &str = "warn"; - pub const IGNORE_MISSING: &str = "ignore-missing"; - pub const QUIET: &str = "quiet"; - pub const ZERO: &str = "zero"; - pub const DEBUG: &str = "debug"; -} - /// cksum has a bunch of legacy behavior. We handle this in this function to /// make sure they are self contained and "easier" to understand. /// @@ -137,22 +112,6 @@ fn maybe_sanitize_length( pub fn uumain(args: impl uucore::Args) -> UResult<()> { let matches = uucore::clap_localization::handle_clap_result(uu_app(), args)?; - 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::(options::ALGORITHM) .map(AlgoKind::from_cksum) @@ -164,202 +123,36 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let length = maybe_sanitize_length(algo_cli, input_length)?; - // clap provides the default value -. So we unwrap() safety. - let files = matches - .get_many::(options::FILE) - .unwrap() - .map(|s| s.as_os_str()); + let (tag, binary) = handle_tag_text_binary_flags(std::env::args_os())?; - if check { - // cksum does not support '--check'ing legacy algorithms - if algo_cli.is_some_and(AlgoKind::is_legacy) { - return Err(ChecksumError::AlgorithmNotSupportedWithCheck.into()); - } - - let text_flag = matches.get_flag(options::TEXT); - let binary_flag = matches.get_flag(options::BINARY); - let tag = matches.get_flag(options::TAG); - - if tag || binary_flag || text_flag { - return Err(ChecksumError::BinaryTextConflict.into()); - } - - // Execute the checksum validation based on the presence of files or the use of stdin - - let verbose = ChecksumVerbose::new(status, quiet, warn); - let opts = ChecksumValidateOptions { - ignore_missing, - strict, - verbose, - }; - - return perform_checksum_validation(files, algo_cli, length, opts); - } - - // Not --check + let output_format = OutputFormat::from_cksum( + algo_cli.unwrap_or(AlgoKind::Crc), + tag, + binary, + /* raw */ matches.get_flag(options::RAW), + /* base64 */ matches.get_flag(options::BASE64), + ); // 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); - - let (tag, binary) = handle_tag_text_binary_flags(std::env::args_os())?; - - let output_format = OutputFormat::from_cksum( - algo_kind, - tag, - binary, - matches.get_flag(options::RAW), - matches.get_flag(options::BASE64), - ); - - let algo = SizedAlgoKind::from_unsized(algo_kind, length)?; - let line_ending = LineEnding::from_zero_flag(matches.get_flag(options::ZERO)); - - let opts = ChecksumComputeOptions { - algo_kind: algo, - output_format, - line_ending, - }; - - perform_checksum_computation(opts, files)?; - - Ok(()) + checksum_main(algo_cli, length, matches, output_format) } pub fn uu_app() -> Command { - Command::new(uucore::util_name()) - .version(uucore::crate_version!()) - .help_template(uucore::localized_help_template(uucore::util_name())) - .about(translate!("cksum-about")) - .override_usage(format_usage(&translate!("cksum-usage"))) - .infer_long_args(true) - .args_override_self(true) - .arg( - Arg::new(options::FILE) - .hide(true) - .action(ArgAction::Append) - .value_parser(ValueParser::os_string()) - .default_value("-") - .hide_default_value(true) - .value_hint(clap::ValueHint::FilePath), - ) - .arg( - Arg::new(options::ALGORITHM) - .long(options::ALGORITHM) - .short('a') - .help(translate!("cksum-help-algorithm")) - .value_name("ALGORITHM") - .value_parser(SUPPORTED_ALGORITHMS), - ) - .arg( - Arg::new(options::UNTAGGED) - .long(options::UNTAGGED) - .help(translate!("cksum-help-untagged")) - .action(ArgAction::SetTrue) - .overrides_with(options::TAG), - ) - .arg( - Arg::new(options::TAG) - .long(options::TAG) - .help(translate!("cksum-help-tag")) - .action(ArgAction::SetTrue) - .overrides_with(options::UNTAGGED), - ) - .arg( - Arg::new(options::LENGTH) - .long(options::LENGTH) - .short('l') - .help(translate!("cksum-help-length")) - .action(ArgAction::Set), - ) - .arg( - Arg::new(options::RAW) - .long(options::RAW) - .help(translate!("cksum-help-raw")) - .action(ArgAction::SetTrue), - ) - .arg( - Arg::new(options::STRICT) - .long(options::STRICT) - .help(translate!("cksum-help-strict")) - .action(ArgAction::SetTrue), - ) - .arg( - Arg::new(options::CHECK) - .short('c') - .long(options::CHECK) - .help(translate!("cksum-help-check")) - .action(ArgAction::SetTrue), - ) - .arg( - Arg::new(options::BASE64) - .long(options::BASE64) - .help(translate!("cksum-help-base64")) - .action(ArgAction::SetTrue) - // Even though this could easily just override an earlier '--raw', - // GNU cksum does not permit these flags to be combined: - .conflicts_with(options::RAW), - ) - .arg( - Arg::new(options::TEXT) - .long(options::TEXT) - .short('t') - .hide(true) - .overrides_with(options::BINARY) - .action(ArgAction::SetTrue), - ) - .arg( - Arg::new(options::BINARY) - .long(options::BINARY) - .short('b') - .hide(true) - .overrides_with(options::TEXT) - .action(ArgAction::SetTrue), - ) - .arg( - Arg::new(options::WARN) - .short('w') - .long("warn") - .help(translate!("cksum-help-warn")) - .action(ArgAction::SetTrue) - .overrides_with_all([options::STATUS, options::QUIET]), - ) - .arg( - Arg::new(options::STATUS) - .long("status") - .help(translate!("cksum-help-status")) - .action(ArgAction::SetTrue) - .overrides_with_all([options::WARN, options::QUIET]), - ) - .arg( - Arg::new(options::QUIET) - .long(options::QUIET) - .help(translate!("cksum-help-quiet")) - .action(ArgAction::SetTrue) - .overrides_with_all([options::WARN, options::STATUS]), - ) - .arg( - Arg::new(options::IGNORE_MISSING) - .long(options::IGNORE_MISSING) - .help(translate!("cksum-help-ignore-missing")) - .action(ArgAction::SetTrue), - ) - .arg( - Arg::new(options::ZERO) - .long(options::ZERO) - .short('z') - .help(translate!("cksum-help-zero")) - .action(ArgAction::SetTrue), - ) - .arg( - Arg::new(options::DEBUG) - .long(options::DEBUG) - .help(translate!("cksum-help-debug")) - .action(ArgAction::SetTrue), - ) + default_checksum_app(translate!("cksum-about"), translate!("cksum-usage")) + .with_algo() + .with_untagged() + .with_tag(true) + .with_length() + .with_raw() + .with_check_and_opts() + .with_base64() + .with_text(false) + .with_binary() + .with_zero() + .with_debug() .after_help(translate!("cksum-after-help")) } diff --git a/src/uucore/src/lib/mods/locale.rs b/src/uucore/src/lib/mods/locale.rs index ec9a78b43..8425d1e1b 100644 --- a/src/uucore/src/lib/mods/locale.rs +++ b/src/uucore/src/lib/mods/locale.rs @@ -156,6 +156,11 @@ fn create_bundle( // Then, try to load utility-specific strings from the utility's locale directory try_add_resource_from(get_locales_dir(util_name).ok()); + // checksum binaries also require fluent files from the checksum_common crate + if ["cksum"].contains(&util_name) { + try_add_resource_from(get_locales_dir("checksum_common").ok()); + } + // If we have at least one resource, return the bundle if bundle.has_message("common-error") || bundle.has_message(&format!("{util_name}-about")) { Ok(bundle)