From ade6e8c6329979e90e98a625fbd732e27c2f8b5f Mon Sep 17 00:00:00 2001 From: Dorian Peron Date: Fri, 30 Jan 2026 16:17:31 +0100 Subject: [PATCH] Remove mentions to hashsum --- Cargo.lock | 10 - Cargo.toml | 2 - GNUmakefile | 6 - build.rs | 3 - docs/src/extensions.md | 7 - fuzz/fuzz_targets/fuzz_non_utf8_paths.rs | 7 - src/uu/hashsum/Cargo.toml | 30 - src/uu/hashsum/LICENSE | 1 - src/uu/hashsum/locales/en-US.ftl | 39 - src/uu/hashsum/locales/fr-FR.ftl | 37 - src/uu/hashsum/src/hashsum.rs | 408 ------- src/uu/hashsum/src/main.rs | 1 - tests/by-util/test_b2sum.rs | 7 +- tests/by-util/test_hashsum.rs | 1265 ---------------------- tests/by-util/test_sha1sum.rs | 2 - tests/by-util/test_sha256sum.rs | 1 - tests/by-util/test_sha384sum.rs | 1 - tests/by-util/test_sha512sum.rs | 1 - tests/test_localization_and_colors.rs | 27 - tests/tests.rs | 4 - util/show-utils.BAT | 4 +- util/show-utils.sh | 2 +- 22 files changed, 4 insertions(+), 1861 deletions(-) delete mode 100644 src/uu/hashsum/Cargo.toml delete mode 120000 src/uu/hashsum/LICENSE delete mode 100644 src/uu/hashsum/locales/en-US.ftl delete mode 100644 src/uu/hashsum/locales/fr-FR.ftl delete mode 100644 src/uu/hashsum/src/hashsum.rs delete mode 100644 src/uu/hashsum/src/main.rs delete mode 100644 tests/by-util/test_hashsum.rs diff --git a/Cargo.lock b/Cargo.lock index c82b84cc586..8141ded2613 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -588,7 +588,6 @@ dependencies = [ "uu_fmt", "uu_fold", "uu_groups", - "uu_hashsum", "uu_head", "uu_hostid", "uu_hostname", @@ -3570,15 +3569,6 @@ dependencies = [ "uucore", ] -[[package]] -name = "uu_hashsum" -version = "0.6.0" -dependencies = [ - "clap", - "fluent", - "uucore", -] - [[package]] name = "uu_head" version = "0.6.0" diff --git a/Cargo.toml b/Cargo.toml index 228272604a8..80cce0fe12b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -112,7 +112,6 @@ feat_common_core = [ "false", "fmt", "fold", - "hashsum", "head", "join", "link", @@ -472,7 +471,6 @@ false = { optional = true, version = "0.6.0", package = "uu_false", path = "src/ fmt = { optional = true, version = "0.6.0", package = "uu_fmt", path = "src/uu/fmt" } fold = { optional = true, version = "0.6.0", package = "uu_fold", path = "src/uu/fold" } groups = { optional = true, version = "0.6.0", package = "uu_groups", path = "src/uu/groups" } -hashsum = { optional = true, version = "0.6.0", package = "uu_hashsum", path = "src/uu/hashsum" } head = { optional = true, version = "0.6.0", package = "uu_head", path = "src/uu/head" } hostid = { optional = true, version = "0.6.0", package = "uu_hostid", path = "src/uu/hostid" } hostname = { optional = true, version = "0.6.0", package = "uu_hostname", path = "src/uu/hostname" } diff --git a/GNUmakefile b/GNUmakefile index b1c8ff2dce1..f6b8f043222 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -105,9 +105,6 @@ ifeq ($(SELINUX_ENABLED),1) endif UTILS ?= $(filter-out $(SKIP_UTILS),$(PROGS)) -ifneq ($(filter hashsum,$(UTILS)),hashsum) - HASHSUM_PROGS := -endif ifneq ($(findstring stdbuf,$(UTILS)),) # Use external libstdbuf per default. It is more robust than embedding libstdbuf. @@ -306,9 +303,6 @@ else $(foreach prog, $(INSTALLEES), \ $(INSTALL) -m 755 $(BUILDDIR)/$(prog) $(INSTALLDIR_BIN)/$(PROG_PREFIX)$(prog) $(newline) \ ) - $(foreach prog, $(HASHSUM_PROGS), \ - cd $(INSTALLDIR_BIN) && $(LN) $(PROG_PREFIX)hashsum $(PROG_PREFIX)$(prog) $(newline) \ - ) $(if $(findstring test,$(INSTALLEES)), $(INSTALL) -m 755 $(BUILDDIR)/test $(INSTALLDIR_BIN)/$(PROG_PREFIX)[) endif diff --git a/build.rs b/build.rs index a7eb9031225..4b77018ab9b 100644 --- a/build.rs +++ b/build.rs @@ -87,9 +87,6 @@ pub fn main() { "false" | "true" => { phf_map.entry(krate, format!("(r#{krate}::uumain, r#{krate}::uu_app)")); } - "hashsum" => { - phf_map.entry(krate, format!("({krate}::uumain, {krate}::uu_app_custom)")); - } _ => { phf_map.entry(krate, map_value.clone()); } diff --git a/docs/src/extensions.md b/docs/src/extensions.md index fa92c54a099..bb0dfff0617 100644 --- a/docs/src/extensions.md +++ b/docs/src/extensions.md @@ -53,13 +53,6 @@ packages. `rm` can display a progress bar when the `-g`/`--progress` flag is set. -## `hashsum` (deprecated) - -This utility does not exist in GNU coreutils. `hashsum` is a utility that -supports computing the checksums with several algorithms. The flags and options -are identical to the `*sum` family of utils (`sha1sum`, `sha256sum`, `b2sum`, -etc.). This utility will be removed in the future and it is advised to use `cksum --untagged` instead. - ## `more` We provide a simple implementation of `more`, which is not part of GNU diff --git a/fuzz/fuzz_targets/fuzz_non_utf8_paths.rs b/fuzz/fuzz_targets/fuzz_non_utf8_paths.rs index 82e5374844b..56451502ba9 100644 --- a/fuzz/fuzz_targets/fuzz_non_utf8_paths.rs +++ b/fuzz/fuzz_targets/fuzz_non_utf8_paths.rs @@ -83,7 +83,6 @@ static PATH_PROGRAMS: &[&str] = &[ "vdir", "mkfifo", "mknod", - "hashsum", // File I/O utilities "dd", "sync", @@ -252,12 +251,6 @@ fn test_program_with_non_utf8_path(program: &str, path: &Path) -> CommandResult OsString::from("bs=1"), OsString::from("count=1"), ], - // Hashsum needs algorithm - "hashsum" => vec![ - OsString::from(program), - OsString::from("--md5"), - path_os.to_owned(), - ], // Encoding/decoding programs "base32" | "base64" | "basenc" => vec![OsString::from(program), path_os.to_owned()], "df" => vec![OsString::from(program), path_os.to_owned()], diff --git a/src/uu/hashsum/Cargo.toml b/src/uu/hashsum/Cargo.toml deleted file mode 100644 index 4c28a1588b6..00000000000 --- a/src/uu/hashsum/Cargo.toml +++ /dev/null @@ -1,30 +0,0 @@ -[package] -name = "uu_hashsum" -description = "hashsum ~ (uutils) display or check input digests" -repository = "https://github.com/uutils/coreutils/tree/main/src/uu/hashsum" -version.workspace = true -authors.workspace = true -license.workspace = true -homepage.workspace = true -keywords.workspace = true -categories.workspace = true -edition.workspace = true -readme.workspace = true - -[lints] -workspace = true - -[lib] -path = "src/hashsum.rs" - -[dependencies] -clap = { workspace = true } -uucore = { workspace = true, features = ["checksum", "encoding", "sum"] } -fluent = { workspace = true } - -[[bin]] -name = "hashsum" -path = "src/main.rs" - -[dev-dependencies] -uucore = { workspace = true, features = ["benchmark"] } diff --git a/src/uu/hashsum/LICENSE b/src/uu/hashsum/LICENSE deleted file mode 120000 index 5853aaea53b..00000000000 --- a/src/uu/hashsum/LICENSE +++ /dev/null @@ -1 +0,0 @@ -../../../LICENSE \ No newline at end of file diff --git a/src/uu/hashsum/locales/en-US.ftl b/src/uu/hashsum/locales/en-US.ftl deleted file mode 100644 index c0a6a556748..00000000000 --- a/src/uu/hashsum/locales/en-US.ftl +++ /dev/null @@ -1,39 +0,0 @@ -hashsum-about = Compute and check message digests. -hashsum-usage = hashsum -- [OPTIONS]... [FILE]... - -# Utility-specific usage template -hashsum-usage-specific = {$utility_name} [OPTION]... [FILE]... - -# Help messages -hashsum-help-binary-windows = read or check in binary mode (default) -hashsum-help-binary-other = read in binary mode -hashsum-help-text-windows = read or check in text mode -hashsum-help-text-other = read in text mode (default) -hashsum-help-check = read hashsums from the FILEs and check them -hashsum-help-tag = create a BSD-style checksum -hashsum-help-quiet = don't print OK for each successfully verified file -hashsum-help-status = don't output anything, status code shows success -hashsum-help-strict = exit non-zero for improperly formatted checksum lines -hashsum-help-ignore-missing = don't fail or report status for missing files -hashsum-help-warn = warn about improperly formatted checksum lines -hashsum-help-zero = end each output line with NUL, not newline -hashsum-help-length = digest length in bits; must not exceed the max for the blake2 algorithm and must be a multiple of 8 -# Algorithm help messages -hashsum-help-md5 = work with MD5 -hashsum-help-sha1 = work with SHA1 -hashsum-help-sha224 = work with SHA224 -hashsum-help-sha256 = work with SHA256 -hashsum-help-sha384 = work with SHA384 -hashsum-help-sha512 = work with SHA512 -hashsum-help-sha3 = work with SHA3 -hashsum-help-sha3-224 = work with SHA3-224 -hashsum-help-sha3-256 = work with SHA3-256 -hashsum-help-sha3-384 = work with SHA3-384 -hashsum-help-sha3-512 = work with SHA3-512 -hashsum-help-shake128 = work with SHAKE128 using BITS for the output size -hashsum-help-shake256 = work with SHAKE256 using BITS for the output size -hashsum-help-b2sum = work with BLAKE2 -hashsum-help-b3sum = work with BLAKE3 - -# Error messages -hashsum-error-failed-to-read-input = failed to read input diff --git a/src/uu/hashsum/locales/fr-FR.ftl b/src/uu/hashsum/locales/fr-FR.ftl deleted file mode 100644 index 26c61fec9d3..00000000000 --- a/src/uu/hashsum/locales/fr-FR.ftl +++ /dev/null @@ -1,37 +0,0 @@ -hashsum-about = Calculer et vérifier les empreintes de messages. -hashsum-usage = hashsum -- [OPTION]... [FICHIER]... - -# Messages d'aide -hashsum-help-binary-windows = lire ou vérifier en mode binaire (par défaut) -hashsum-help-binary-other = lire en mode binaire -hashsum-help-text-windows = lire ou vérifier en mode texte -hashsum-help-text-other = lire en mode texte (par défaut) -hashsum-help-check = lire les empreintes depuis les FICHIERs et les vérifier -hashsum-help-tag = créer une somme de contrôle de style BSD -hashsum-help-quiet = ne pas afficher OK pour chaque fichier vérifié avec succès -hashsum-help-status = ne rien afficher, le code de statut indique le succès -hashsum-help-strict = sortir avec un code non-zéro pour les lignes de somme de contrôle mal formatées -hashsum-help-ignore-missing = ne pas échouer ou rapporter le statut pour les fichiers manquants -hashsum-help-warn = avertir des lignes de somme de contrôle mal formatées -hashsum-help-zero = terminer chaque ligne de sortie avec NUL, pas de retour à la ligne -hashsum-help-length = longueur de l'empreinte en bits ; ne doit pas dépasser le maximum pour l'algorithme blake2 et doit être un multiple de 8 - -# Messages d'aide des algorithmes -hashsum-help-md5 = travailler avec MD5 -hashsum-help-sha1 = travailler avec SHA1 -hashsum-help-sha224 = travailler avec SHA224 -hashsum-help-sha256 = travailler avec SHA256 -hashsum-help-sha384 = travailler avec SHA384 -hashsum-help-sha512 = travailler avec SHA512 -hashsum-help-sha3 = travailler avec SHA3 -hashsum-help-sha3-224 = travailler avec SHA3-224 -hashsum-help-sha3-256 = travailler avec SHA3-256 -hashsum-help-sha3-384 = travailler avec SHA3-384 -hashsum-help-sha3-512 = travailler avec SHA3-512 -hashsum-help-shake128 = travailler avec SHAKE128 en utilisant BITS pour la taille de sortie -hashsum-help-shake256 = travailler avec SHAKE256 en utilisant BITS pour la taille de sortie -hashsum-help-b2sum = travailler avec BLAKE2 -hashsum-help-b3sum = travailler avec BLAKE3 - -# Messages d'erreur -hashsum-error-failed-to-read-input = échec de la lecture de l'entrée diff --git a/src/uu/hashsum/src/hashsum.rs b/src/uu/hashsum/src/hashsum.rs deleted file mode 100644 index 6c401041ab4..00000000000 --- a/src/uu/hashsum/src/hashsum.rs +++ /dev/null @@ -1,408 +0,0 @@ -// This file is part of the uutils coreutils package. -// -// For the full copyright and license information, please view the LICENSE -// file that was distributed with this source code. - -// spell-checker:ignore (ToDO) algo, algoname, bitlen, regexes, nread - -use std::ffi::{OsStr, OsString}; -use std::iter; -use std::path::Path; - -use clap::builder::ValueParser; -use clap::{Arg, ArgAction, ArgMatches, Command}; - -use uucore::checksum::compute::{ - ChecksumComputeOptions, OutputFormat, perform_checksum_computation, -}; -use uucore::checksum::validate::{ - ChecksumValidateOptions, ChecksumVerbose, perform_checksum_validation, -}; -use uucore::checksum::{ - AlgoKind, ChecksumError, SizedAlgoKind, calculate_blake2b_length_str, - sanitize_sha2_sha3_length_str, -}; -use uucore::error::UResult; -use uucore::line_ending::LineEnding; -use uucore::{format_usage, translate}; - -const NAME: &str = "hashsum"; - -/// Creates a hasher instance based on the command-line flags. -/// -/// # Arguments -/// -/// * `matches` - A reference to the `ArgMatches` object containing the command-line arguments. -/// -/// # Returns -/// -/// Returns a [`UResult`] of a tuple containing the algorithm name, the hasher instance, and -/// the output length in bits or an Err if multiple hash algorithms are specified or if a -/// required flag is missing. -#[allow(clippy::cognitive_complexity)] -fn create_algorithm_from_flags(matches: &ArgMatches) -> UResult<(AlgoKind, Option)> { - let mut alg: Option<(AlgoKind, Option)> = None; - - let mut set_or_err = |new_alg: (AlgoKind, Option)| -> UResult<()> { - if alg.is_some() { - return Err(ChecksumError::CombineMultipleAlgorithms.into()); - } - alg = Some(new_alg); - Ok(()) - }; - - if matches.get_flag("md5") { - set_or_err((AlgoKind::Md5, None))?; - } - if matches.get_flag("sha1") { - set_or_err((AlgoKind::Sha1, None))?; - } - if matches.get_flag("sha224") { - set_or_err((AlgoKind::Sha224, None))?; - } - if matches.get_flag("sha256") { - set_or_err((AlgoKind::Sha256, None))?; - } - if matches.get_flag("sha384") { - set_or_err((AlgoKind::Sha384, None))?; - } - if matches.get_flag("sha512") { - set_or_err((AlgoKind::Sha512, None))?; - } - if matches.get_flag("b2sum") { - set_or_err((AlgoKind::Blake2b, None))?; - } - if matches.get_flag("b3sum") { - set_or_err((AlgoKind::Blake3, None))?; - } - if matches.get_flag("sha3") { - match matches.get_one::(options::LENGTH) { - Some(len) => set_or_err(( - AlgoKind::Sha3, - Some(sanitize_sha2_sha3_length_str(AlgoKind::Sha3, len)?), - ))?, - None => return Err(ChecksumError::LengthRequired("SHA3".into()).into()), - } - } - if matches.get_flag("sha3-224") { - set_or_err((AlgoKind::Sha3, Some(224)))?; - } - if matches.get_flag("sha3-256") { - set_or_err((AlgoKind::Sha3, Some(256)))?; - } - if matches.get_flag("sha3-384") { - set_or_err((AlgoKind::Sha3, Some(384)))?; - } - if matches.get_flag("sha3-512") { - set_or_err((AlgoKind::Sha3, Some(512)))?; - } - if matches.get_flag("shake128") { - set_or_err((AlgoKind::Shake128, Some(128)))?; - } - if matches.get_flag("shake256") { - set_or_err((AlgoKind::Shake256, Some(256)))?; - } - - if alg.is_none() { - return Err(ChecksumError::NeedAlgorithmToHash.into()); - } - - Ok(alg.unwrap()) -} - -#[uucore::main] -pub fn uumain(mut args: impl uucore::Args) -> UResult<()> { - // if there is no program name for some reason, default to "hashsum" - let program = args.next().unwrap_or_else(|| OsString::from(NAME)); - let binary_name = Path::new(&program) - .file_stem() - .unwrap_or_else(|| OsStr::new(NAME)) - .to_string_lossy(); - - let args = iter::once(program.clone()).chain(args); - - let (command, is_hashsum_bin) = uu_app(&binary_name); - - // FIXME: this should use try_get_matches_from() and crash!(), but at the moment that just - // causes "error: " to be printed twice (once from crash!() and once from clap). With - // the current setup, the name of the utility is not printed, but I think this is at - // least somewhat better from a user's perspective. - let matches = uucore::clap_localization::handle_clap_result(command, args)?; - - let length: Option = if binary_name == "b2sum" { - if let Some(len) = matches.get_one::(options::LENGTH) { - calculate_blake2b_length_str(len)? - } else { - None - } - } else { - None - }; - - let (algo_kind, length) = if is_hashsum_bin { - create_algorithm_from_flags(&matches)? - } else { - (AlgoKind::from_bin_name(&binary_name)?, length) - }; - - let check = matches.get_flag("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("ignore-missing")?; - let warn = check_flag("warn")?; - let quiet = check_flag("quiet")?; - let strict = check_flag("strict")?; - let status = check_flag("status")?; - - // clap provides the default value -. So we unwrap() safety. - let files = matches - .get_many::(options::FILE) - .unwrap() - .map(|s| s.as_os_str()); - - if check { - // on Windows, allow --binary/--text to be used with --check - // and keep the behavior of defaulting to binary - #[cfg(not(windows))] - { - let text_flag = matches.get_flag("text"); - let binary_flag = matches.get_flag("binary"); - - if binary_flag || text_flag { - return Err(ChecksumError::BinaryTextConflict.into()); - } - } - - let verbose = ChecksumVerbose::new(status, quiet, warn); - - let opts = ChecksumValidateOptions { - ignore_missing, - strict, - verbose, - }; - - // Execute the checksum validation - return perform_checksum_validation(files, Some(algo_kind), length, opts); - } - - let algo = SizedAlgoKind::from_unsized(algo_kind, length)?; - let line_ending = LineEnding::from_zero_flag(matches.get_flag("zero")); - let output_format = OutputFormat::from_standalone(std::env::args_os())?; - - let opts = ChecksumComputeOptions { - algo_kind: algo, - output_format, - line_ending, - }; - - // Show the hashsum of the input - perform_checksum_computation(opts, files) -} - -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 QUIET: &str = "quiet"; -} - -pub fn uu_app_common() -> Command { - Command::new(uucore::util_name()) - .version(uucore::crate_version!()) - .help_template(uucore::localized_help_template(uucore::util_name())) - .about(translate!("hashsum-about")) - .override_usage(format_usage(&translate!("hashsum-usage"))) - .infer_long_args(true) - .args_override_self(true) - .arg( - Arg::new(options::BINARY) - .short('b') - .long("binary") - .help({ - #[cfg(windows)] - { - translate!("hashsum-help-binary-windows") - } - #[cfg(not(windows))] - { - translate!("hashsum-help-binary-other") - } - }) - .action(ArgAction::SetTrue), - ) - .arg( - Arg::new(options::CHECK) - .short('c') - .long("check") - .help(translate!("hashsum-help-check")) - .action(ArgAction::SetTrue) - .conflicts_with("tag"), - ) - .arg( - Arg::new(options::TAG) - .long("tag") - .help(translate!("hashsum-help-tag")) - .action(ArgAction::SetTrue) - .conflicts_with("text"), - ) - .arg( - Arg::new(options::TEXT) - .short('t') - .long("text") - .help({ - #[cfg(windows)] - { - translate!("hashsum-help-text-windows") - } - #[cfg(not(windows))] - { - translate!("hashsum-help-text-other") - } - }) - .conflicts_with("binary") - .action(ArgAction::SetTrue), - ) - .arg( - Arg::new(options::QUIET) - .short('q') - .long(options::QUIET) - .help(translate!("hashsum-help-quiet")) - .action(ArgAction::SetTrue) - .overrides_with_all([options::STATUS, options::WARN]), - ) - .arg( - Arg::new(options::STATUS) - .short('s') - .long("status") - .help(translate!("hashsum-help-status")) - .action(ArgAction::SetTrue) - .overrides_with_all([options::QUIET, options::WARN]), - ) - .arg( - Arg::new(options::STRICT) - .long("strict") - .help(translate!("hashsum-help-strict")) - .action(ArgAction::SetTrue), - ) - .arg( - Arg::new("ignore-missing") - .long("ignore-missing") - .help(translate!("hashsum-help-ignore-missing")) - .action(ArgAction::SetTrue), - ) - .arg( - Arg::new(options::WARN) - .short('w') - .long("warn") - .help(translate!("hashsum-help-warn")) - .action(ArgAction::SetTrue) - .overrides_with_all([options::QUIET, options::STATUS]), - ) - .arg( - Arg::new("zero") - .short('z') - .long("zero") - .help(translate!("hashsum-help-zero")) - .action(ArgAction::SetTrue), - ) - .arg( - Arg::new(options::FILE) - .index(1) - .action(ArgAction::Append) - .value_name(options::FILE) - .default_value("-") - .hide_default_value(true) - .value_hint(clap::ValueHint::FilePath) - .value_parser(ValueParser::os_string()), - ) -} - -pub fn uu_app_length() -> Command { - uu_app_opt_length(uu_app_common()) -} - -fn uu_app_opt_length(command: Command) -> Command { - command.arg( - Arg::new(options::LENGTH) - .long(options::LENGTH) - .short('l') - .help(translate!("hashsum-help-length")) - .overrides_with(options::LENGTH) - .action(ArgAction::Set), - ) -} - -pub fn uu_app_custom() -> Command { - let mut command = uu_app_opt_length(uu_app_common()); - let algorithms = &[ - ("md5", translate!("hashsum-help-md5")), - ("sha1", translate!("hashsum-help-sha1")), - ("sha224", translate!("hashsum-help-sha224")), - ("sha256", translate!("hashsum-help-sha256")), - ("sha384", translate!("hashsum-help-sha384")), - ("sha512", translate!("hashsum-help-sha512")), - ("sha3", translate!("hashsum-help-sha3")), - ("sha3-224", translate!("hashsum-help-sha3-224")), - ("sha3-256", translate!("hashsum-help-sha3-256")), - ("sha3-384", translate!("hashsum-help-sha3-384")), - ("sha3-512", translate!("hashsum-help-sha3-512")), - ("shake128", translate!("hashsum-help-shake128")), - ("shake256", translate!("hashsum-help-shake256")), - ("b2sum", translate!("hashsum-help-b2sum")), - ("b3sum", translate!("hashsum-help-b3sum")), - ]; - - for (name, desc) in algorithms { - command = command.arg( - Arg::new(*name) - .long(name) - .help(desc) - .action(ArgAction::SetTrue), - ); - } - command -} - -/// hashsum is handled differently in build.rs -/// therefore, this is different from other utilities. -fn uu_app(binary_name: &str) -> (Command, bool) { - let (command, is_hashsum_bin) = match binary_name { - // These all support the same options. - "md5sum" | "sha1sum" | "sha224sum" | "sha256sum" | "sha384sum" | "sha512sum" => { - (uu_app_common(), false) - } - // b2sum supports the md5sum options plus -l/--length. - "b2sum" => (uu_app_length(), false), - // We're probably just being called as `hashsum`, so give them everything. - _ => (uu_app_custom(), true), - }; - - // If not called as generic hashsum, override the command name and usage - let command = if is_hashsum_bin { - command - } else { - let usage = translate!("hashsum-usage-specific", "utility_name" => binary_name); - command - .help_template(uucore::localized_help_template(binary_name)) - .override_usage(format_usage(&usage)) - }; - - (command, is_hashsum_bin) -} diff --git a/src/uu/hashsum/src/main.rs b/src/uu/hashsum/src/main.rs deleted file mode 100644 index c31d4a9afb9..00000000000 --- a/src/uu/hashsum/src/main.rs +++ /dev/null @@ -1 +0,0 @@ -uucore::bin!(uu_hashsum); diff --git a/tests/by-util/test_b2sum.rs b/tests/by-util/test_b2sum.rs index 30e2c46ca35..9df3170e606 100644 --- a/tests/by-util/test_b2sum.rs +++ b/tests/by-util/test_b2sum.rs @@ -286,12 +286,7 @@ fn test_check_b2sum_strict_check() { #[test] fn test_help_shows_correct_utility_name() { - // Test that help output shows the actual utility name instead of "hashsum" - let scene = TestScenario::new(util_name!()); - - // Test b2sum - scene - .ccmd("b2sum") + new_ucmd!() .arg("--help") .succeeds() .stdout_contains("Usage: b2sum") diff --git a/tests/by-util/test_hashsum.rs b/tests/by-util/test_hashsum.rs deleted file mode 100644 index c139469d66c..00000000000 --- a/tests/by-util/test_hashsum.rs +++ /dev/null @@ -1,1265 +0,0 @@ -// This file is part of the uutils coreutils package. -// -// For the full copyright and license information, please view the LICENSE -// file that was distributed with this source code. - -use rstest::rstest; - -use uutests::new_ucmd; -use uutests::util::TestScenario; -use uutests::util_name; -// spell-checker:ignore checkfile, testf, ntestf -macro_rules! get_hash( - ($str:expr) => ( - $str.split(' ').collect::>()[0] - ); -); - -macro_rules! test_digest { - ($id:ident, $t:ident) => { - mod $id { - use uutests::util::*; - use uutests::util_name; - static DIGEST_ARG: &'static str = concat!("--", stringify!($t)); - static EXPECTED_FILE: &'static str = concat!(stringify!($id), ".expected"); - static CHECK_FILE: &'static str = concat!(stringify!($id), ".checkfile"); - static INPUT_FILE: &'static str = "input.txt"; - - #[test] - fn test_single_file() { - let ts = TestScenario::new(util_name!()); - assert_eq!( - ts.fixtures.read(EXPECTED_FILE), - get_hash!( - ts.ucmd() - .arg(DIGEST_ARG) - .arg(INPUT_FILE) - .succeeds() - .no_stderr() - .stdout_str() - ) - ); - } - - #[test] - fn test_stdin() { - let ts = TestScenario::new(util_name!()); - assert_eq!( - ts.fixtures.read(EXPECTED_FILE), - get_hash!( - ts.ucmd() - .arg(DIGEST_ARG) - .pipe_in_fixture(INPUT_FILE) - .succeeds() - .no_stderr() - .stdout_str() - ) - ); - } - - #[test] - fn test_check() { - let ts = TestScenario::new(util_name!()); - println!("File content='{}'", ts.fixtures.read(INPUT_FILE)); - println!("Check file='{}'", ts.fixtures.read(CHECK_FILE)); - - ts.ucmd() - .args(&[DIGEST_ARG, "--check", CHECK_FILE]) - .succeeds() - .no_stderr() - .stdout_is("input.txt: OK\n"); - } - - #[test] - fn test_zero() { - let ts = TestScenario::new(util_name!()); - assert_eq!( - ts.fixtures.read(EXPECTED_FILE), - get_hash!( - ts.ucmd() - .arg(DIGEST_ARG) - .arg("--zero") - .arg(INPUT_FILE) - .succeeds() - .no_stderr() - .stdout_str() - ) - ); - } - - #[test] - fn test_missing_file() { - let ts = TestScenario::new(util_name!()); - let at = &ts.fixtures; - - at.write("a", "file1\n"); - at.write("c", "file3\n"); - - ts.ucmd() - .args(&[DIGEST_ARG, "a", "b", "c"]) - .fails() - .stdout_contains("a\n") - .stdout_contains("c\n") - .stderr_contains("b: No such file or directory"); - } - } - }; -} - -macro_rules! test_digest_with_len { - ($id:ident, $t:ident, $size:expr) => { - mod $id { - use uutests::util::*; - use uutests::util_name; - static DIGEST_ARG: &'static str = concat!("--", stringify!($t)); - static LENGTH_ARG: &'static str = concat!("--length=", stringify!($size)); - static EXPECTED_FILE: &'static str = concat!(stringify!($id), ".expected"); - static CHECK_FILE: &'static str = concat!(stringify!($id), ".checkfile"); - static INPUT_FILE: &'static str = "input.txt"; - - #[test] - fn test_single_file() { - let ts = TestScenario::new(util_name!()); - assert_eq!( - ts.fixtures.read(EXPECTED_FILE), - get_hash!( - ts.ucmd() - .arg(DIGEST_ARG) - .arg(LENGTH_ARG) - .arg(INPUT_FILE) - .succeeds() - .no_stderr() - .stdout_str() - ) - ); - } - - #[test] - fn test_stdin() { - let ts = TestScenario::new(util_name!()); - assert_eq!( - ts.fixtures.read(EXPECTED_FILE), - get_hash!( - ts.ucmd() - .arg(DIGEST_ARG) - .arg(LENGTH_ARG) - .pipe_in_fixture(INPUT_FILE) - .succeeds() - .no_stderr() - .stdout_str() - ) - ); - } - - #[test] - fn test_check() { - let ts = TestScenario::new(util_name!()); - println!("File content='{}'", ts.fixtures.read(INPUT_FILE)); - println!("Check file='{}'", ts.fixtures.read(CHECK_FILE)); - - ts.ucmd() - .args(&[DIGEST_ARG, LENGTH_ARG, "--check", CHECK_FILE]) - .succeeds() - .no_stderr() - .stdout_is("input.txt: OK\n"); - } - - #[test] - fn test_zero() { - let ts = TestScenario::new(util_name!()); - assert_eq!( - ts.fixtures.read(EXPECTED_FILE), - get_hash!( - ts.ucmd() - .arg(DIGEST_ARG) - .arg(LENGTH_ARG) - .arg("--zero") - .arg(INPUT_FILE) - .succeeds() - .no_stderr() - .stdout_str() - ) - ); - } - - #[test] - fn test_missing_file() { - let ts = TestScenario::new(util_name!()); - let at = &ts.fixtures; - - at.write("a", "file1\n"); - at.write("c", "file3\n"); - - ts.ucmd() - .args(&[DIGEST_ARG, LENGTH_ARG, "a", "b", "c"]) - .fails() - .stdout_contains("a\n") - .stdout_contains("c\n") - .stderr_contains("b: No such file or directory"); - } - } - }; -} - -test_digest! {b3sum, b3sum} -test_digest! {shake128, shake128} -test_digest! {shake256, shake256} - -test_digest_with_len! {sha3_224, sha3, 224} -test_digest_with_len! {sha3_256, sha3, 256} -test_digest_with_len! {sha3_384, sha3, 384} -test_digest_with_len! {sha3_512, sha3, 512} - -#[ignore = "moved to standalone"] -#[test] -fn test_check_sha1() { - // To make sure that #3815 doesn't happen again - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - at.write("testf", "foobar\n"); - at.write( - "testf.sha1", - "988881adc9fc3655077dc2d4d757d480b5ea0e11 testf\n", - ); - scene - .ccmd("sha1sum") - .arg("-c") - .arg(at.subdir.join("testf.sha1")) - .succeeds() - .stdout_is("testf: OK\n") - .stderr_is(""); -} - -#[ignore = "moved to standalone"] -#[test] -fn test_check_md5_ignore_missing() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - at.write("testf", "foobar\n"); - at.write( - "testf.sha1", - "14758f1afd44c09b7992073ccf00b43d testf\n14758f1afd44c09b7992073ccf00b43d testf2\n", - ); - scene - .ccmd("md5sum") - .arg("-c") - .arg(at.subdir.join("testf.sha1")) - .fails() - .stdout_contains("testf2: FAILED open or read"); - - scene - .ccmd("md5sum") - .arg("-c") - .arg("--ignore-missing") - .arg(at.subdir.join("testf.sha1")) - .succeeds() - .stdout_is("testf: OK\n") - .stderr_is(""); - - scene - .ccmd("md5sum") - .arg("--ignore-missing") - .arg(at.subdir.join("testf.sha1")) - .fails() - .stderr_contains("the --ignore-missing option is meaningful only when verifying checksums"); -} - -#[ignore = "moved to standalone"] -#[test] -fn test_check_b2sum_length_option_0() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - at.write("testf", "foobar\n"); - at.write("testf.b2sum", "9e2bf63e933e610efee4a8d6cd4a9387e80860edee97e27db3b37a828d226ab1eb92a9cdd8ca9ca67a753edaf8bd89a0558496f67a30af6f766943839acf0110 testf\n"); - - scene - .ccmd("b2sum") - .arg("--length=0") - .arg("-c") - .arg(at.subdir.join("testf.b2sum")) - .succeeds() - .stdout_only("testf: OK\n"); -} - -#[ignore = "moved to standalone"] -#[test] -fn test_check_b2sum_length_duplicate() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - at.write("testf", "foobar\n"); - - scene - .ccmd("b2sum") - .arg("--length=123") - .arg("--length=128") - .arg("testf") - .succeeds() - .stdout_contains("d6d45901dec53e65d2b55fb6e2ab67b0"); -} - -#[ignore = "moved to standalone"] -#[test] -fn test_check_b2sum_length_option_8() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - at.write("testf", "foobar\n"); - at.write("testf.b2sum", "6a testf\n"); - - scene - .ccmd("b2sum") - .arg("--length=8") - .arg("-c") - .arg(at.subdir.join("testf.b2sum")) - .succeeds() - .stdout_only("testf: OK\n"); -} - -#[ignore = "moved to standalone"] -#[test] -fn test_invalid_b2sum_length_option_not_multiple_of_8() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - at.write("testf", "foobar\n"); - - scene - .ccmd("b2sum") - .arg("--length=9") - .arg(at.subdir.join("testf")) - .fails_with_code(1) - .stderr_contains("b2sum: invalid length: '9'") - .stderr_contains("b2sum: length is not a multiple of 8"); -} - -#[rstest] -#[ignore = "moved to standalone"] -#[case("513")] -#[ignore = "moved to standalone"] -#[case("1024")] -#[ignore = "moved to standalone"] -#[case("18446744073709552000")] -fn test_invalid_b2sum_length_option_too_large(#[case] len: &str) { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - at.write("testf", "foobar\n"); - - scene - .ccmd("b2sum") - .arg("--length") - .arg(len) - .arg(at.subdir.join("testf")) - .fails_with_code(1) - .no_stdout() - .stderr_contains(format!("b2sum: invalid length: '{len}'")) - .stderr_contains("b2sum: maximum digest length for 'BLAKE2b' is 512 bits"); -} - -#[ignore = "moved to standalone"] -#[test] -fn test_check_b2sum_tag_output() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - at.touch("f"); - - scene - .ccmd("b2sum") - .arg("--length=0") - .arg("--tag") - .arg("f") - .succeeds() - .stdout_only("BLAKE2b (f) = 786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce\n"); - - scene - .ccmd("b2sum") - .arg("--length=128") - .arg("--tag") - .arg("f") - .succeeds() - .stdout_only("BLAKE2b-128 (f) = cae66941d9efbd404e4d88758ea67670\n"); -} - -#[ignore = "moved to standalone"] -#[test] -fn test_check_b2sum_verify() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - at.write("a", "a\n"); - - scene - .ccmd("b2sum") - .arg("--tag") - .arg("a") - .succeeds() - .stdout_only("BLAKE2b (a) = bedfbb90d858c2d67b7ee8f7523be3d3b54004ef9e4f02f2ad79a1d05bfdfe49b81e3c92ebf99b504102b6bf003fa342587f5b3124c205f55204e8c4b4ce7d7c\n"); - - scene - .ccmd("b2sum") - .arg("--tag") - .arg("-l") - .arg("128") - .arg("a") - .succeeds() - .stdout_only("BLAKE2b-128 (a) = b93e0fc7bb21633c08bba07c5e71dc00\n"); -} - -#[ignore = "moved to standalone"] -#[test] -fn test_check_file_not_found_warning() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - at.write("testf", "foobar\n"); - at.write( - "testf.sha1", - "988881adc9fc3655077dc2d4d757d480b5ea0e11 testf\n", - ); - at.remove("testf"); - scene - .ccmd("sha1sum") - .arg("-c") - .arg(at.subdir.join("testf.sha1")) - .fails() - .stdout_is("testf: FAILED open or read\n") - .stderr_is("sha1sum: testf: No such file or directory\nsha1sum: WARNING: 1 listed file could not be read\n"); -} - -// Asterisk `*` is a reserved paths character on win32, nor the path can end with a whitespace. -// ref: https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions -#[ignore = "moved to standalone"] -#[test] -fn test_check_md5sum() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - #[cfg(not(windows))] - { - for f in &["a", " b", "*c", "dd", " "] { - at.write(f, &format!("{f}\n")); - } - at.write( - "check.md5sum", - "60b725f10c9c85c70d97880dfe8191b3 a\n\ - bf35d7536c785cf06730d5a40301eba2 b\n\ - f5b61709718c1ecf8db1aea8547d4698 *c\n\ - b064a020db8018f18ff5ae367d01b212 dd\n\ - d784fa8b6d98d27699781bd9a7cf19f0 ", - ); - scene - .ccmd("md5sum") - .arg("--strict") - .arg("-c") - .arg("check.md5sum") - .succeeds() - .stdout_is("a: OK\n b: OK\n*c: OK\ndd: OK\n : OK\n") - .stderr_is(""); - } - #[cfg(windows)] - { - for f in &["a", " b", "dd"] { - at.write(f, &format!("{f}\n")); - } - at.write( - "check.md5sum", - "60b725f10c9c85c70d97880dfe8191b3 a\n\ - bf35d7536c785cf06730d5a40301eba2 b\n\ - b064a020db8018f18ff5ae367d01b212 dd", - ); - scene - .ccmd("md5sum") - .arg("--strict") - .arg("-c") - .arg("check.md5sum") - .succeeds() - .stdout_is("a: OK\n b: OK\ndd: OK\n") - .stderr_is(""); - } -} - -// GNU also supports one line sep -#[ignore = "moved to standalone"] -#[test] -fn test_check_md5sum_only_one_space() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - for f in ["a", " b", "c"] { - at.write(f, &format!("{f}\n")); - } - at.write( - "check.md5sum", - "60b725f10c9c85c70d97880dfe8191b3 a\n\ - bf35d7536c785cf06730d5a40301eba2 b\n\ - 2cd6ee2c70b0bde53fbe6cac3c8b8bb1 c\n", - ); - scene - .ccmd("md5sum") - .arg("--strict") - .arg("-c") - .arg("check.md5sum") - .succeeds() - .stdout_only("a: OK\n b: OK\nc: OK\n"); -} - -#[ignore = "moved to standalone"] -#[test] -fn test_check_md5sum_reverse_bsd() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - #[cfg(not(windows))] - { - for f in &["a", " b", "*c", "dd", " "] { - at.write(f, &format!("{f}\n")); - } - at.write( - "check.md5sum", - "60b725f10c9c85c70d97880dfe8191b3 a\n\ - bf35d7536c785cf06730d5a40301eba2 b\n\ - f5b61709718c1ecf8db1aea8547d4698 *c\n\ - b064a020db8018f18ff5ae367d01b212 dd\n\ - d784fa8b6d98d27699781bd9a7cf19f0 ", - ); - scene - .ccmd("md5sum") - .arg("--strict") - .arg("-c") - .arg("check.md5sum") - .succeeds() - .stdout_is("a: OK\n b: OK\n*c: OK\ndd: OK\n : OK\n") - .stderr_is(""); - } - #[cfg(windows)] - { - for f in &["a", " b", "dd"] { - at.write(f, &format!("{f}\n")); - } - at.write( - "check.md5sum", - "60b725f10c9c85c70d97880dfe8191b3 a\n\ - bf35d7536c785cf06730d5a40301eba2 b\n\ - b064a020db8018f18ff5ae367d01b212 dd", - ); - scene - .ccmd("md5sum") - .arg("--strict") - .arg("-c") - .arg("check.md5sum") - .succeeds() - .stdout_is("a: OK\n b: OK\ndd: OK\n") - .stderr_is(""); - } -} - -#[ignore = "moved to standalone"] -#[test] -fn test_check_md5sum_mixed_format() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - #[cfg(not(windows))] - { - for f in &[" b", "*c", "dd", " "] { - at.write(f, &format!("{f}\n")); - } - at.write( - "check.md5sum", - "bf35d7536c785cf06730d5a40301eba2 b\n\ - f5b61709718c1ecf8db1aea8547d4698 *c\n\ - b064a020db8018f18ff5ae367d01b212 dd\n\ - d784fa8b6d98d27699781bd9a7cf19f0 ", - ); - } - #[cfg(windows)] - { - for f in &[" b", "dd"] { - at.write(f, &format!("{f}\n")); - } - at.write( - "check.md5sum", - "bf35d7536c785cf06730d5a40301eba2 b\n\ - b064a020db8018f18ff5ae367d01b212 dd", - ); - } - scene - .ccmd("md5sum") - .arg("--strict") - .arg("-c") - .arg("check.md5sum") - .fails_with_code(1); -} - -#[test] -fn test_invalid_arg() { - new_ucmd!().arg("--definitely-invalid").fails_with_code(1); -} - -#[test] -fn test_conflicting_arg() { - new_ucmd!() - .arg("--tag") - .arg("--check") - .arg("--md5") - .fails_with_code(1); - new_ucmd!() - .arg("--tag") - .arg("--text") - .arg("--md5") - .fails_with_code(1); -} - -#[ignore = "moved to standalone"] -#[test] -fn test_tag() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - at.write("foobar", "foo bar\n"); - scene - .ccmd("sha256sum") - .arg("--tag") - .arg("foobar") - .succeeds() - .stdout_is( - "SHA256 (foobar) = 1f2ec52b774368781bed1d1fb140a92e0eb6348090619c9291f9a5a3c8e8d151\n", - ); -} - -#[ignore = "moved to standalone"] -#[test] -#[cfg(not(windows))] -fn test_with_escape_filename() { - let scene = TestScenario::new(util_name!()); - - let at = &scene.fixtures; - let filename = "a\nb"; - at.touch(filename); - let result = scene.ccmd("md5sum").arg("--text").arg(filename).succeeds(); - let stdout = result.stdout_str(); - println!("stdout {stdout}"); - assert!(stdout.starts_with('\\')); - assert!(stdout.trim().ends_with("a\\nb")); -} - -#[ignore = "moved to standalone"] -#[test] -#[cfg(not(windows))] -fn test_with_escape_filename_zero_text() { - let scene = TestScenario::new(util_name!()); - - let at = &scene.fixtures; - let filename = "a\nb"; - at.touch(filename); - let result = scene - .ccmd("md5sum") - .arg("--text") - .arg("--zero") - .arg(filename) - .succeeds(); - let stdout = result.stdout_str(); - println!("stdout {stdout}"); - assert!(!stdout.starts_with('\\')); - assert!(stdout.contains("a\nb")); -} - -#[ignore = "moved to standalone"] -#[test] -fn test_check_empty_line() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - at.touch("f"); - at.write( - "in.md5", - "d41d8cd98f00b204e9800998ecf8427e f\n\nd41d8cd98f00b204e9800998ecf8427e f\ninvalid\n\n", - ); - scene - .ccmd("md5sum") - .arg("--check") - .arg(at.subdir.join("in.md5")) - .succeeds() - .stderr_contains("WARNING: 1 line is improperly formatted"); -} - -#[ignore = "moved to standalone"] -#[test] -#[cfg(not(windows))] -fn test_check_with_escape_filename() { - let scene = TestScenario::new(util_name!()); - - let at = &scene.fixtures; - - let filename = "a\nb"; - at.touch(filename); - let result = scene.ccmd("md5sum").arg("--tag").arg(filename).succeeds(); - let stdout = result.stdout_str(); - println!("stdout {stdout}"); - assert!(stdout.starts_with("\\MD5")); - assert!(stdout.contains("a\\nb")); - at.write("check.md5", stdout); - let result = scene - .ccmd("md5sum") - .arg("--strict") - .arg("-c") - .arg("check.md5") - .succeeds(); - result.stdout_is("\\a\\nb: OK\n"); -} - -#[ignore = "moved to standalone"] -#[test] -fn test_check_strict_error() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - at.touch("f"); - at.write( - "in.md5", - "ERR\nERR\nd41d8cd98f00b204e9800998ecf8427e f\nERR\n", - ); - scene - .ccmd("md5sum") - .arg("--check") - .arg("--strict") - .arg(at.subdir.join("in.md5")) - .fails() - .stderr_contains("WARNING: 3 lines are improperly formatted"); -} - -#[ignore = "moved to standalone"] -#[test] -fn test_check_warn() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - at.touch("f"); - at.write( - "in.md5", - "d41d8cd98f00b204e9800998ecf8427e f\nd41d8cd98f00b204e9800998ecf8427e f\ninvalid\n", - ); - scene - .ccmd("md5sum") - .arg("--check") - .arg("--warn") - .arg(at.subdir.join("in.md5")) - .succeeds() - .stderr_contains("in.md5: 3: improperly formatted MD5 checksum line") - .stderr_contains("WARNING: 1 line is improperly formatted"); - - // with strict, we should fail the execution - scene - .ccmd("md5sum") - .arg("--check") - .arg("--strict") - .arg(at.subdir.join("in.md5")) - .fails(); -} - -#[ignore = "moved to standalone"] -#[test] -fn test_check_status() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - at.touch("f"); - at.write("in.md5", "MD5(f)= d41d8cd98f00b204e9800998ecf8427f\n"); - scene - .ccmd("md5sum") - .arg("--check") - .arg("--status") - .arg(at.subdir.join("in.md5")) - .fails() - .no_output(); -} - -#[ignore = "moved to standalone"] -#[test] -fn test_check_status_code() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - at.touch("f"); - at.write("in.md5", "d41d8cd98f00b204e9800998ecf8427f f\n"); - scene - .ccmd("md5sum") - .arg("--check") - .arg("--status") - .arg(at.subdir.join("in.md5")) - .fails() - .stderr_is("") - .stdout_is(""); -} - -#[ignore = "moved to standalone"] -#[test] -fn test_sha1_with_md5sum_should_fail() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - at.touch("f"); - at.write("f.sha1", "SHA1 (f) = d41d8cd98f00b204e9800998ecf8427e\n"); - scene - .ccmd("md5sum") - .arg("--check") - .arg(at.subdir.join("f.sha1")) - .fails() - .stderr_contains("f.sha1: no properly formatted checksum lines found") - .stderr_does_not_contain("WARNING: 1 line is improperly formatted"); -} - -#[ignore = "moved to standalone"] -#[test] -// Disabled on Windows because of the "*" -#[cfg(not(windows))] -fn test_check_one_two_space_star() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - at.touch("empty"); - - // with one space, the "*" is removed - at.write("in.md5", "d41d8cd98f00b204e9800998ecf8427e *empty\n"); - - scene - .ccmd("md5sum") - .arg("--check") - .arg(at.subdir.join("in.md5")) - .succeeds() - .stdout_is("empty: OK\n"); - - // with two spaces, the "*" is not removed - at.write("in.md5", "d41d8cd98f00b204e9800998ecf8427e *empty\n"); - // First should fail as *empty doesn't exit - scene - .ccmd("md5sum") - .arg("--check") - .arg(at.subdir.join("in.md5")) - .fails() - .stdout_is("*empty: FAILED open or read\n"); - - at.touch("*empty"); - // Should pass as we have the file - scene - .ccmd("md5sum") - .arg("--check") - .arg(at.subdir.join("in.md5")) - .succeeds() - .stdout_is("*empty: OK\n"); -} - -#[ignore = "moved to standalone"] -#[test] -// Disabled on Windows because of the "*" -#[cfg(not(windows))] -fn test_check_space_star_or_not() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - at.touch("a"); - at.touch("*c"); - - // with one space, the "*" is removed - at.write( - "in.md5", - "d41d8cd98f00b204e9800998ecf8427e *c\n - d41d8cd98f00b204e9800998ecf8427e a\n", - ); - - scene - .ccmd("md5sum") - .arg("--check") - .arg(at.subdir.join("in.md5")) - .fails() - .stdout_contains("c: FAILED") - .stdout_does_not_contain("a: FAILED") - .stderr_contains("WARNING: 1 line is improperly formatted"); - - at.write( - "in.md5", - "d41d8cd98f00b204e9800998ecf8427e a\n - d41d8cd98f00b204e9800998ecf8427e *c\n", - ); - - // First should fail as *empty doesn't exit - scene - .ccmd("md5sum") - .arg("--check") - .arg(at.subdir.join("in.md5")) - .succeeds() - .stdout_contains("a: OK") - .stderr_contains("WARNING: 1 line is improperly formatted"); -} - -#[ignore = "moved to standalone"] -#[test] -fn test_check_no_backslash_no_space() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - at.touch("f"); - at.write("in.md5", "MD5(f)= d41d8cd98f00b204e9800998ecf8427e\n"); - scene - .ccmd("md5sum") - .arg("--check") - .arg(at.subdir.join("in.md5")) - .succeeds() - .stdout_is("f: OK\n"); -} - -#[ignore = "moved to standalone"] -#[test] -fn test_incomplete_format() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - at.touch("f"); - at.write("in.md5", "MD5 (\n"); - scene - .ccmd("md5sum") - .arg("--check") - .arg(at.subdir.join("in.md5")) - .fails() - .stderr_contains("no properly formatted checksum lines found"); -} - -#[ignore = "moved to standalone"] -#[test] -fn test_start_error() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - at.touch("f"); - at.write("in.md5", "ERR\nd41d8cd98f00b204e9800998ecf8427e f\n"); - scene - .ccmd("md5sum") - .arg("--check") - .arg("--strict") - .arg(at.subdir.join("in.md5")) - .fails() - .stdout_is("f: OK\n") - .stderr_contains("WARNING: 1 line is improperly formatted"); -} - -#[ignore = "moved to standalone"] -#[test] -fn test_check_check_ignore_no_file() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - at.touch("f"); - at.write("in.md5", "d41d8cd98f00b204e9800998ecf8427f missing\n"); - scene - .ccmd("md5sum") - .arg("--check") - .arg("--ignore-missing") - .arg(at.subdir.join("in.md5")) - .fails() - .stderr_contains("in.md5: no file was verified"); -} - -#[ignore = "moved to standalone"] -#[test] -fn test_check_directory_error() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - at.mkdir("d"); - at.write("in.md5", "d41d8cd98f00b204e9800998ecf8427f d\n"); - #[cfg(not(windows))] - let err_msg = "md5sum: d: Is a directory\n"; - #[cfg(windows)] - let err_msg = "md5sum: d: Permission denied\n"; - scene - .ccmd("md5sum") - .arg("--check") - .arg(at.subdir.join("in.md5")) - .fails() - .stderr_contains(err_msg); -} - -#[ignore = "moved to standalone"] -#[test] -#[cfg(not(windows))] -fn test_continue_after_directory_error() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - at.mkdir("d"); - at.touch("file"); - at.touch("no_read_perms"); - at.set_mode("no_read_perms", 200); - - let (out, err_msg) = ( - "d41d8cd98f00b204e9800998ecf8427e file\n", - [ - "md5sum: d: Is a directory", - "md5sum: dne: No such file or directory", - "md5sum: no_read_perms: Permission denied\n", - ] - .join("\n"), - ); - - scene - .ccmd("md5sum") - .arg("d") - .arg("dne") - .arg("no_read_perms") - .arg("file") - .fails() - .stdout_is(out) - .stderr_is(err_msg); -} - -#[ignore = "moved to standalone"] -#[test] -fn test_check_quiet() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - at.touch("f"); - at.write("in.md5", "d41d8cd98f00b204e9800998ecf8427e f\n"); - scene - .ccmd("md5sum") - .arg("--quiet") - .arg("--check") - .arg(at.subdir.join("in.md5")) - .succeeds() - .no_output(); - - // incorrect md5 - at.write("in.md5", "d41d8cd98f00b204e9800998ecf8427f f\n"); - scene - .ccmd("md5sum") - .arg("--quiet") - .arg("--check") - .arg(at.subdir.join("in.md5")) - .fails() - .stdout_contains("f: FAILED") - .stderr_contains("WARNING: 1 computed checksum did NOT match"); - - scene - .ccmd("md5sum") - .arg("--quiet") - .arg(at.subdir.join("in.md5")) - .fails() - .stderr_contains("md5sum: the --quiet option is meaningful only when verifying checksums"); - scene - .ccmd("md5sum") - .arg("--strict") - .arg(at.subdir.join("in.md5")) - .fails() - .stderr_contains("md5sum: the --strict option is meaningful only when verifying checksums"); -} - -#[ignore = "moved to standalone"] -#[test] -fn test_star_to_start() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - at.touch("f"); - at.write("in.md5", "d41d8cd98f00b204e9800998ecf8427e *f\n"); - scene - .ccmd("md5sum") - .arg("--check") - .arg(at.subdir.join("in.md5")) - .succeeds() - .stdout_only("f: OK\n"); -} - -#[ignore = "moved to standalone"] -#[test] -fn test_check_b2sum_strict_check() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - at.touch("f"); - - let checksums = [ - "2e f\n", - "e4a6a0577479b2b4 f\n", - "cae66941d9efbd404e4d88758ea67670 f\n", - "246c0442cd564aced8145b8b60f1370aa7 f\n", - "0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8 f\n", - "4ded8c5fc8b12f3273f877ca585a44ad6503249a2b345d6d9c0e67d85bcb700db4178c0303e93b8f4ad758b8e2c9fd8b3d0c28e585f1928334bb77d36782e8 f\n", - "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce f\n", - ]; - - at.write("ck", &checksums.join("")); - - let output = "f: OK\n".to_string().repeat(checksums.len()); - - scene - .ccmd("b2sum") - .arg("-c") - .arg(at.subdir.join("ck")) - .succeeds() - .stdout_only(&output); - - scene - .ccmd("b2sum") - .arg("--strict") - .arg("-c") - .arg(at.subdir.join("ck")) - .succeeds() - .stdout_only(&output); -} - -#[ignore = "moved to standalone"] -#[test] -fn test_check_md5_comment_line() { - // A comment in a checksum file shall be discarded unnoticed. - - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - at.write("foo", "foo-content\n"); - at.write( - "MD5SUM", - "\ - # This is a comment\n\ - 8411029f3f5b781026a93db636aca721 foo\n\ - # next comment is empty\n#", - ); - - scene - .ccmd("md5sum") - .arg("--check") - .arg("MD5SUM") - .succeeds() - .stdout_contains("foo: OK") - .no_stderr(); -} - -#[ignore = "moved to standalone"] -#[test] -fn test_check_md5_comment_only() { - // A file only filled with comments is equivalent to an empty file, - // and therefore produces an error. - - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - at.write("foo", "foo-content\n"); - at.write("MD5SUM", "# This is a comment\n"); - - scene - .ccmd("md5sum") - .arg("--check") - .arg("MD5SUM") - .fails() - .stderr_contains("no properly formatted checksum lines found"); -} - -#[ignore = "moved to standalone"] -#[test] -fn test_check_md5_comment_leading_space() { - // A file only filled with comments is equivalent to an empty file, - // and therefore produces an error. - - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - at.write("foo", "foo-content\n"); - at.write( - "MD5SUM", - " # This is a comment\n\ - 8411029f3f5b781026a93db636aca721 foo\n", - ); - - scene - .ccmd("md5sum") - .arg("--check") - .arg("MD5SUM") - .succeeds() - .stdout_contains("foo: OK") - .stderr_contains("WARNING: 1 line is improperly formatted"); -} - -#[ignore = "moved to standalone"] -#[test] -fn test_sha256_binary() { - let ts = TestScenario::new(util_name!()); - assert_eq!( - ts.fixtures.read("binary.sha256.expected"), - get_hash!( - ts.ucmd() - .arg("--sha256") - .arg("binary.png") - .succeeds() - .no_stderr() - .stdout_str() - ) - ); -} - -#[ignore = "moved to standalone"] -#[test] -fn test_sha256_stdin_binary() { - let ts = TestScenario::new(util_name!()); - assert_eq!( - ts.fixtures.read("binary.sha256.expected"), - get_hash!( - ts.ucmd() - .arg("--sha256") - .pipe_in_fixture("binary.png") - .succeeds() - .no_stderr() - .stdout_str() - ) - ); -} - -// This test is currently disabled on windows -#[ignore = "moved to standalone"] -#[test] -fn test_check_sha256_binary() { - new_ucmd!() - .args(&["--sha256", "--check", "binary.sha256.checkfile"]) - .succeeds() - .no_stderr() - .stdout_is("binary.png: OK\n"); -} - -#[test] -fn test_help_shows_correct_utility_name() { - // Test that help output shows the actual utility name instead of "hashsum" - let scene = TestScenario::new(util_name!()); - - // Test md5sum - // scene - // .ccmd("md5sum") - // .arg("--help") - // .succeeds() - // .stdout_contains("Usage: md5sum") - // .stdout_does_not_contain("Usage: hashsum"); - - // Test sha256sum - // scene - // .ccmd("sha256sum") - // .arg("--help") - // .succeeds() - // .stdout_contains("Usage: sha256sum") - // .stdout_does_not_contain("Usage: hashsum"); - - // Test b2sum - // scene - // .ccmd("b2sum") - // .arg("--help") - // .succeeds() - // .stdout_contains("Usage: b2sum") - // .stdout_does_not_contain("Usage: hashsum"); - - // Test that generic hashsum still shows the correct usage - scene - .ccmd("hashsum") - .arg("--help") - .succeeds() - .stdout_contains("Usage: hashsum --"); -} diff --git a/tests/by-util/test_sha1sum.rs b/tests/by-util/test_sha1sum.rs index d0e7f6f3d71..6a540d509b1 100644 --- a/tests/by-util/test_sha1sum.rs +++ b/tests/by-util/test_sha1sum.rs @@ -155,8 +155,6 @@ fn test_conflicting_arg() { #[test] fn test_help_shows_correct_utility_name() { - // Test that help output shows the actual utility name instead of "hashsum" - new_ucmd!() .arg("--help") .succeeds() diff --git a/tests/by-util/test_sha256sum.rs b/tests/by-util/test_sha256sum.rs index b3b538384b1..b8219e2382b 100644 --- a/tests/by-util/test_sha256sum.rs +++ b/tests/by-util/test_sha256sum.rs @@ -172,7 +172,6 @@ fn test_check_sha256_binary() { #[test] fn test_help_shows_correct_utility_name() { - // Test that help output shows the actual utility name instead of "hashsum" new_ucmd!() .arg("--help") .succeeds() diff --git a/tests/by-util/test_sha384sum.rs b/tests/by-util/test_sha384sum.rs index 9dbc730801c..a579e041a68 100644 --- a/tests/by-util/test_sha384sum.rs +++ b/tests/by-util/test_sha384sum.rs @@ -113,7 +113,6 @@ fn test_conflicting_arg() { #[test] fn test_help_shows_correct_utility_name() { - // Test that help output shows the actual utility name instead of "hashsum" new_ucmd!() .arg("--help") .succeeds() diff --git a/tests/by-util/test_sha512sum.rs b/tests/by-util/test_sha512sum.rs index 5e01ad32a18..08c6d20fe92 100644 --- a/tests/by-util/test_sha512sum.rs +++ b/tests/by-util/test_sha512sum.rs @@ -113,7 +113,6 @@ fn test_conflicting_arg() { #[test] fn test_help_shows_correct_utility_name() { - // Test that help output shows the actual utility name instead of "hashsum" new_ucmd!() .arg("--help") .succeeds() diff --git a/tests/test_localization_and_colors.rs b/tests/test_localization_and_colors.rs index 677e2e0b75c..f2a1ff08485 100644 --- a/tests/test_localization_and_colors.rs +++ b/tests/test_localization_and_colors.rs @@ -132,15 +132,6 @@ fn test_error_messages_have_colors() { println!("Testing error colors for {utility}"); let mut cmd = create_utility_command(utility); - let uu_name = format!("uu_{utility}"); - let binary_name = uucore::get_canonical_util_name(&uu_name); - - // For hashsum aliases, we need to pass the hash algorithm as a subcommand - if binary_name == "hashsum" && utility != "hashsum" { - // Extract the hash algorithm from the utility name - let algo = utility.trim_end_matches("sum"); - cmd.arg(algo); - } let output = cmd .arg("--invalid-option-that-should-not-exist") @@ -232,15 +223,6 @@ fn test_error_messages_french_translation() { println!("Testing French error translation for {utility}"); let mut cmd = create_utility_command(utility); - let uu_name = format!("uu_{utility}"); - let binary_name = uucore::get_canonical_util_name(&uu_name); - - // For hashsum aliases, we need to pass the hash algorithm as a subcommand - if binary_name == "hashsum" && utility != "hashsum" { - // Extract the hash algorithm from the utility name - let algo = utility.trim_end_matches("sum"); - cmd.arg(algo); - } let output = cmd .arg("--invalid-option-that-should-not-exist") @@ -285,15 +267,6 @@ fn test_french_colored_error_messages() { println!("Testing French colored errors for {utility}"); let mut cmd = create_utility_command(utility); - let uu_name = format!("uu_{utility}"); - let binary_name = uucore::get_canonical_util_name(&uu_name); - - // For hashsum aliases, we need to pass the hash algorithm as a subcommand - if binary_name == "hashsum" && utility != "hashsum" { - // Extract the hash algorithm from the utility name - let algo = utility.trim_end_matches("sum"); - cmd.arg(algo); - } let output = cmd .arg("--invalid-option-that-should-not-exist") diff --git a/tests/tests.rs b/tests/tests.rs index d2ecbca10f1..b731ad465b7 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -172,10 +172,6 @@ mod test_fold; #[path = "by-util/test_groups.rs"] mod test_groups; -#[cfg(feature = "hashsum")] -#[path = "by-util/test_hashsum.rs"] -mod test_hashsum; - #[cfg(feature = "head")] #[path = "by-util/test_head.rs"] mod test_head; diff --git a/util/show-utils.BAT b/util/show-utils.BAT index f6d9007349c..92f618160f5 100644 --- a/util/show-utils.BAT +++ b/util/show-utils.BAT @@ -2,7 +2,7 @@ @echo off @rem ::# spell-checker:ignore (CMD) ERRORLEVEL -@rem ::# spell-checker:ignore (utils) cksum coreutils dircolors hashsum mkdir mktemp printenv printf readlink realpath rmdir shuf tsort unexpand +@rem ::# spell-checker:ignore (utils) cksum coreutils dircolors mkdir mktemp printenv printf readlink realpath rmdir shuf tsort unexpand @rem ::# spell-checker:ignore (jq) deps startswith set "ME=%~0" @@ -12,7 +12,7 @@ set "ME_parent_dir=%~dp0.\.." @rem refs: , @rem :: default ("Tier 1" cross-platform) utility list -set "default_utils=base32 base64 basename cat cksum comm cp cut date dircolors dirname echo env expand expr factor false fmt fold hashsum head join link ln ls mkdir mktemp more mv nl od paste printenv printf ptx pwd readlink realpath rm rmdir seq shred shuf sleep sort split sum tac tail tee test tr true truncate tsort unexpand uniq wc yes" +set "default_utils=base32 base64 basename cat cksum comm cp cut date dircolors dirname echo env expand expr factor false fmt fold head join link ln ls mkdir mktemp more mv nl od paste printenv printf ptx pwd readlink realpath rm rmdir seq shred shuf sleep sort split sum tac tail tee test tr true truncate tsort unexpand uniq wc yes" set "project_dir=%ME_parent_dir%" cd "%project_dir%" diff --git a/util/show-utils.sh b/util/show-utils.sh index 66266e7a992..ff70fe25d49 100755 --- a/util/show-utils.sh +++ b/util/show-utils.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # spell-checker:ignore (shell) OSTYPE -# spell-checker:ignore (utils) cksum coreutils dircolors hashsum mkdir mktemp printenv printf readlink realpath grealpath rmdir shuf tsort unexpand +# spell-checker:ignore (utils) cksum coreutils dircolors mkdir mktemp printenv printf readlink realpath grealpath rmdir shuf tsort unexpand # spell-checker:ignore (jq) deps startswith # Use GNU version for realpath on *BSD