diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index 0a6c9ab1329..c490fa9dfe7 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -297,7 +297,7 @@ jobs: mv -T target target.cache fi # Check that we don't cross-build uudoc - # also do not try to generate manpages for part of hashsum + # also do not try to generate manpages for part of cksum make install-manpages PREFIX=/tmp/usr UTILS=true RUSTC_ARCH="--target aarch64-unknown-linux-gnu" # build (host) make build @@ -372,8 +372,8 @@ jobs: set -x DESTDIR=/tmp/ make PROFILE=release MULTICALL=n install # Check that the utils are present - test -f /tmp/usr/local/bin/hashsum - # Check that hashsum symlinks are present + test -f /tmp/usr/local/bin/cksum + # Check that cksum symlinks are present test -h /tmp/usr/local/bin/b2sum test -h /tmp/usr/local/bin/md5sum test -h /tmp/usr/local/bin/sha1sum @@ -386,7 +386,7 @@ jobs: run: | set -x DESTDIR=/tmp/ make PROFILE=release MULTICALL=y LN="ln -svf" install - # Check that relative symlinks of hashsum are present + # Check that relative symlinks of cksum are present [ $(readlink /tmp/usr/local/bin/b2sum) = coreutils ] [ $(readlink /tmp/usr/local/bin/md5sum) = coreutils ] [ $(readlink /tmp/usr/local/bin/sha512sum) = coreutils ] diff --git a/.vscode/cspell.dictionaries/jargon.wordlist.txt b/.vscode/cspell.dictionaries/jargon.wordlist.txt index 47d435b87ad..4a488f3e789 100644 --- a/.vscode/cspell.dictionaries/jargon.wordlist.txt +++ b/.vscode/cspell.dictionaries/jargon.wordlist.txt @@ -72,7 +72,6 @@ hardfloat hardlink hardlinks hasher -hashsums hwcaps infile iflag diff --git a/.vscode/cspell.dictionaries/workspace.wordlist.txt b/.vscode/cspell.dictionaries/workspace.wordlist.txt index 28c468d4f9c..f6fdfec2916 100644 --- a/.vscode/cspell.dictionaries/workspace.wordlist.txt +++ b/.vscode/cspell.dictionaries/workspace.wordlist.txt @@ -101,7 +101,6 @@ chroot cksum csplit dircolors -hashsum hostid logname mkdir diff --git a/Cargo.toml b/Cargo.toml index 77738518f97..345fdaa559d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -105,7 +105,6 @@ feat_common_core = [ "false", "fmt", "fold", - "hashsum", "head", "join", "link", @@ -453,7 +452,6 @@ false = { optional = true, version = "0.5.0", package = "uu_false", path = "src/ fmt = { optional = true, version = "0.5.0", package = "uu_fmt", path = "src/uu/fmt" } fold = { optional = true, version = "0.5.0", package = "uu_fold", path = "src/uu/fold" } groups = { optional = true, version = "0.5.0", package = "uu_groups", path = "src/uu/groups" } -hashsum = { optional = true, version = "0.5.0", package = "uu_hashsum", path = "src/uu/hashsum" } head = { optional = true, version = "0.5.0", package = "uu_head", path = "src/uu/head" } hostid = { optional = true, version = "0.5.0", package = "uu_hostid", path = "src/uu/hostid" } hostname = { optional = true, version = "0.5.0", package = "uu_hostname", path = "src/uu/hostname" } diff --git a/GNUmakefile b/GNUmakefile index d3430e7e2e5..d73ff1de3f6 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -103,7 +103,6 @@ PROGS := \ false \ fmt \ fold \ - hashsum \ head \ hostname \ join \ @@ -184,7 +183,7 @@ SELINUX_PROGS := \ chcon \ runcon -HASHSUM_PROGS := \ +CKSUM_PROGS := \ b2sum \ md5sum \ sha1sum \ @@ -203,8 +202,8 @@ ifeq ($(SELINUX_ENABLED),1) endif UTILS ?= $(filter-out $(SKIP_UTILS),$(PROGS)) -ifneq ($(filter hashsum,$(UTILS)),hashsum) - HASHSUM_PROGS := +ifneq ($(filter cksum,$(UTILS)),cksum) + CKSUM_PROGS := endif ifneq ($(findstring stdbuf,$(UTILS)),) @@ -236,7 +235,6 @@ TEST_PROGS := \ factor \ false \ fold \ - hashsum \ head \ install \ link \ @@ -386,7 +384,7 @@ build-uudoc: install-manpages: build-uudoc mkdir -p $(DESTDIR)$(DATAROOTDIR)/man/man1 - $(foreach prog, $(INSTALLEES) $(HASHSUM_PROGS), \ + $(foreach prog, $(INSTALLEES) $(CKSUM_PROGS), \ $(BUILDDIR)/uudoc manpage $(prog) > $(DESTDIR)$(DATAROOTDIR)/man/man1/$(PROG_PREFIX)$(prog).1 $(newline) \ ) else @@ -399,7 +397,7 @@ install-completions: build-uudoc mkdir -p $(DESTDIR)$(DATAROOTDIR)/zsh/site-functions mkdir -p $(DESTDIR)$(DATAROOTDIR)/bash-completion/completions mkdir -p $(DESTDIR)$(DATAROOTDIR)/fish/vendor_completions.d - $(foreach prog, $(INSTALLEES) $(HASHSUM_PROGS) , \ + $(foreach prog, $(INSTALLEES) $(CKSUM_PROGS), \ $(BUILDDIR)/uudoc completion $(prog) zsh > $(DESTDIR)$(DATAROOTDIR)/zsh/site-functions/_$(PROG_PREFIX)$(prog) $(newline) \ $(BUILDDIR)/uudoc completion $(prog) bash > $(DESTDIR)$(DATAROOTDIR)/bash-completion/completions/$(PROG_PREFIX)$(prog).bash $(newline) \ $(BUILDDIR)/uudoc completion $(prog) fish > $(DESTDIR)$(DATAROOTDIR)/fish/vendor_completions.d/$(PROG_PREFIX)$(prog).fish $(newline) \ @@ -461,7 +459,7 @@ ifeq (${MULTICALL}, y) $(foreach prog, $(filter-out coreutils, $(INSTALLEES)), \ cd $(INSTALLDIR_BIN) && $(LN) $(PROG_PREFIX)coreutils $(PROG_PREFIX)$(prog) $(newline) \ ) - $(foreach prog, $(HASHSUM_PROGS), \ + $(foreach prog, $(CKSUM_PROGS), \ cd $(INSTALLDIR_BIN) && $(LN) $(PROG_PREFIX)coreutils $(PROG_PREFIX)$(prog) $(newline) \ ) $(if $(findstring test,$(INSTALLEES)), cd $(INSTALLDIR_BIN) && $(LN) $(PROG_PREFIX)coreutils $(PROG_PREFIX)[) @@ -469,8 +467,8 @@ 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) \ + $(foreach prog, $(CKSUM_PROGS), \ + cd $(INSTALLDIR_BIN) && $(LN) $(PROG_PREFIX)cksum $(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 9b35eac5eb4..6334e680fae 100644 --- a/build.rs +++ b/build.rs @@ -75,10 +75,10 @@ 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)")); + "cksum" => { + phf_map.entry(krate, format!("({krate}::uumain, {krate}::uu_app)")); - let map_value = format!("({krate}::uumain, {krate}::uu_app_common)"); + let map_value = format!("({krate}::uumain, {krate}::uu_app)"); phf_map.entry("md5sum", map_value.clone()); phf_map.entry("sha1sum", map_value.clone()); phf_map.entry("sha224sum", map_value.clone()); diff --git a/docs/compiles_table.csv b/docs/compiles_table.csv index e263067b78d..eb77d2844b0 100644 --- a/docs/compiles_table.csv +++ b/docs/compiles_table.csv @@ -1,4 +1,4 @@ -target,arch,base32,base64,basename,cat,chgrp,chmod,chown,chroot,cksum,comm,cp,csplit,cut,date,df,dircolors,dirname,du,echo,env,expand,expr,factor,false,fmt,fold,groups,hashsum,head,hostid,hostname,id,install,join,kill,link,ln,logname,ls,mkdir,mkfifo,mknod,mktemp,more,mv,nice,nl,nohup,nproc,numfmt,od,paste,pathchk,pinky,printenv,printf,ptx,pwd,readlink,realpath,rm,rmdir,seq,shred,shuf,sleep,sort,split,stat,stdbuf,sum,sync,tac,tail,tee,test,timeout,touch,tr,true,truncate,tsort,tty,uname,unexpand,uniq,unlink,uptime,users,wc,who,whoami,yes,chcon,pr,dir,vdir,dd,basenc,runcon +target,arch,base32,base64,basename,cat,chgrp,chmod,chown,chroot,cksum,comm,cp,csplit,cut,date,df,dircolors,dirname,du,echo,env,expand,expr,factor,false,fmt,fold,groups,head,hostid,hostname,id,install,join,kill,link,ln,logname,ls,mkdir,mkfifo,mknod,mktemp,more,mv,nice,nl,nohup,nproc,numfmt,od,paste,pathchk,pinky,printenv,printf,ptx,pwd,readlink,realpath,rm,rmdir,seq,shred,shuf,sleep,sort,split,stat,stdbuf,sum,sync,tac,tail,tee,test,timeout,touch,tr,true,truncate,tsort,tty,uname,unexpand,uniq,unlink,uptime,users,wc,who,whoami,yes,chcon,pr,dir,vdir,dd,basenc,runcon aarch64-unknown-linux-gnu,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 i686-unknown-linux-gnu,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 powerpc64-unknown-linux-gnu,0,0,0,0,0,0,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 diff --git a/docs/src/extensions.md b/docs/src/extensions.md index 80f89e060b5..88dd0d39800 100644 --- a/docs/src/extensions.md +++ b/docs/src/extensions.md @@ -47,13 +47,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 ac7480f3230..a9803956306 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: &PathBuf) -> CommandResu 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/common/validation.rs b/src/common/validation.rs index 057e8a9120d..5361a8d774c 100644 --- a/src/common/validation.rs +++ b/src/common/validation.rs @@ -50,9 +50,9 @@ fn get_canonical_util_name(util_name: &str) -> &str { // uu_test aliases - '[' is an alias for test "[" => "test", - // hashsum aliases - all these hash commands are aliases for hashsum + // cksum aliases - all these hash commands are aliases for cksum "md5sum" | "sha1sum" | "sha224sum" | "sha256sum" | "sha384sum" | "sha512sum" | "b2sum" => { - "hashsum" + "cksum" } "dir" => "ls", // dir is an alias for ls @@ -98,7 +98,7 @@ mod tests { fn test_get_canonical_util_name() { // Test a few key aliases assert_eq!(get_canonical_util_name("["), "test"); - assert_eq!(get_canonical_util_name("md5sum"), "hashsum"); + assert_eq!(get_canonical_util_name("md5sum"), "cksum"); assert_eq!(get_canonical_util_name("dir"), "ls"); // Test passthrough case diff --git a/src/uu/cksum/locales/en-US.ftl b/src/uu/cksum/locales/en-US.ftl index 834cd77b0ef..b7b80008468 100644 --- a/src/uu/cksum/locales/en-US.ftl +++ b/src/uu/cksum/locales/en-US.ftl @@ -1,5 +1,5 @@ -cksum-about = Print CRC and size for each file -cksum-usage = cksum [OPTIONS] [FILE]... +cksum-about = Print checksum and size for each file +cksum-usage = cksum (multicall-binary for {md5,b2,sha*}sum) [OPTIONS] [FILE]... cksum-after-help = DIGEST determines the digest algorithm and default output format: - sysv: (equivalent to sum -s) @@ -16,7 +16,7 @@ cksum-after-help = DIGEST determines the digest algorithm and default output for # 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-tag = create a BSD style checksum (default of cksum) 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 diff --git a/src/uu/cksum/locales/fr-FR.ftl b/src/uu/cksum/locales/fr-FR.ftl index 01136f606f9..456f0fe4016 100644 --- a/src/uu/cksum/locales/fr-FR.ftl +++ b/src/uu/cksum/locales/fr-FR.ftl @@ -1,5 +1,5 @@ -cksum-about = Afficher le CRC et la taille de chaque fichier -cksum-usage = cksum [OPTION]... [FICHIER]... +cksum-about = Afficher le ckecksum et la taille de chaque fichier +cksum-usage = cksum (multicall-binary for {md5,b2,sha*}sum) [OPTION]... [FICHIER]... cksum-after-help = DIGEST détermine l'algorithme de condensé et le format de sortie par défaut : - sysv : (équivalent à sum -s) @@ -16,7 +16,7 @@ cksum-after-help = DIGEST détermine l'algorithme de condensé et le format de s # 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-tag = créer une somme de contrôle de style BSD, annuler --untagged (default of cksum) 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 diff --git a/src/uu/cksum/src/cksum.rs b/src/uu/cksum/src/cksum.rs index 72c7984f049..fdc405eb2cc 100644 --- a/src/uu/cksum/src/cksum.rs +++ b/src/uu/cksum/src/cksum.rs @@ -99,6 +99,14 @@ fn maybe_sanitize_length( #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { + let binary_name = uucore::util_name(); + // Mimic md5sum, b2sum,... by putting --untagged. clap can't do it yet. + let is_cksum = binary_name.ends_with("cksum"); + let mut args: Vec = args.collect(); + if !is_cksum && !args.is_empty() { + args.insert(1, OsString::from("--untagged")); + } + let matches = uucore::clap_localization::handle_clap_result(uu_app(), args)?; let check = matches.get_flag(options::CHECK); @@ -109,13 +117,25 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let strict = matches.get_flag(options::STRICT); let status = matches.get_flag(options::STATUS); - let algo_cli = matches - .get_one::(options::ALGORITHM) - .map(AlgoKind::from_cksum) - .transpose()?; + // Set default algo from binary name. We still use None to ignore --check legacy algos. + let algo_cli = match binary_name { + s if s.ends_with("md5sum") => Some(AlgoKind::Md5), + s if s.ends_with("sha1sum") => Some(AlgoKind::Sha1), + s if s.ends_with("sha224sum") => Some(AlgoKind::Sha224), + s if s.ends_with("sha256sum") => Some(AlgoKind::Sha256), + s if s.ends_with("sha384sum") => Some(AlgoKind::Sha384), + s if s.ends_with("sha512sum") => Some(AlgoKind::Sha512), + s if s.ends_with("b2sum") => Some(AlgoKind::Blake2b), + _ => matches + .get_one::(options::ALGORITHM) + .map(|s| AlgoKind::from_cksum(s)) + .transpose()?, + }; let input_length = matches - .get_one::(options::LENGTH) + .try_get_one::(options::LENGTH) + .ok() + .flatten() .map(String::as_str); let length = maybe_sanitize_length(algo_cli, input_length)?; @@ -126,6 +146,14 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { .unwrap() .map(|s| s.as_os_str()); + // https://github.com/clap-rs/clap/issues/4520 bypasses --warn --binary + // clap 5 should fix them... + if !check & (warn || strict || quiet || ignore_missing || status) { + return Err(uucore::error::UUsageError::new( + 1, + "the following required arguments were not provided:\n--check".to_string(), + )); + } if check { // cksum does not support '--check'ing legacy algorithms if algo_cli.is_some_and(AlgoKind::is_legacy) { @@ -145,16 +173,17 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } // Not --check - // Print hardware debug info if requested - if matches.get_flag(options::DEBUG) { + if is_cksum && 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); + // clap can't set default args. So we adjust tag related flags. + // (Should we use shebang wrapper instead?) - let tag = !matches.get_flag(options::UNTAGGED); // Making TAG default at clap blocks --untagged + let tag = !matches.get_flag(options::UNTAGGED); let binary = matches.get_flag(options::BINARY); let algo = SizedAlgoKind::from_unsized(algo_kind, length)?; @@ -178,13 +207,39 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } pub fn uu_app() -> Command { - Command::new(uucore::util_name()) + let binary_name = uucore::util_name(); + let mut app = Command::new(binary_name) .version(uucore::crate_version!()) - .help_template(uucore::localized_help_template(uucore::util_name())) + .help_template(uucore::localized_help_template(binary_name)) .about(translate!("cksum-about")) .override_usage(format_usage(&translate!("cksum-usage"))) .infer_long_args(true) - .args_override_self(true) + .args_override_self(true); + if binary_name.ends_with("cksum") { + app = app + .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::DEBUG) + .long(options::DEBUG) + .help(translate!("cksum-help-debug")) + .action(ArgAction::SetTrue), + ); + } + app = app + .arg( + Arg::new(options::UNTAGGED) + .long(options::UNTAGGED) + .help(translate!("cksum-help-untagged")) + .action(ArgAction::SetTrue) + .overrides_with(options::TAG), + ) .arg( Arg::new(options::FILE) .hide(true) @@ -194,21 +249,6 @@ pub fn uu_app() -> Command { .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) @@ -218,13 +258,6 @@ pub fn uu_app() -> Command { .overrides_with(options::BINARY) .overrides_with(options::TEXT), ) - .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) @@ -253,8 +286,6 @@ pub fn uu_app() -> Command { .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( @@ -262,7 +293,6 @@ pub fn uu_app() -> Command { .long(options::TEXT) .short('t') .hide(true) - .overrides_with(options::BINARY) .action(ArgAction::SetTrue) .requires(options::UNTAGGED), ) @@ -312,12 +342,15 @@ pub fn uu_app() -> Command { .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), - ) - .after_help(translate!("cksum-after-help")) + ); + if binary_name.ends_with("cksum") || binary_name.ends_with("b2sum") { + app = app.arg( + Arg::new(options::LENGTH) + .long(options::LENGTH) + .short('l') + .help(translate!("cksum-help-length")) + .action(ArgAction::Set), + ); + } + app.after_help(translate!("cksum-after-help")) } diff --git a/src/uu/hashsum/Cargo.toml b/src/uu/hashsum/Cargo.toml deleted file mode 100644 index f77c2c52d84..00000000000 --- a/src/uu/hashsum/Cargo.toml +++ /dev/null @@ -1,32 +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] -divan = { workspace = true } -tempfile = { workspace = true } -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 a13ec468436..00000000000 --- a/src/uu/hashsum/src/hashsum.rs +++ /dev/null @@ -1,420 +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, figure_out_output_format, 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); - - // Default binary in Windows, text mode otherwise - let binary_flag_default = cfg!(windows); - - 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 binary = if matches.get_flag("binary") { - true - } else if matches.get_flag("text") { - false - } else { - binary_flag_default - }; - let check = matches.get_flag("check"); - - let ignore_missing = matches.get_flag("ignore-missing"); - let warn = matches.get_flag("warn"); - let quiet = matches.get_flag("quiet"); - let strict = matches.get_flag("strict"); - let status = matches.get_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 { - // No reason to allow --check with --binary/--text on Cygwin. It want to be same with Linux and --text was broken for a long time. - 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 opts = ChecksumComputeOptions { - algo_kind: algo, - output_format: figure_out_output_format( - algo, - matches.get_flag(options::TAG), - binary, - /* raw */ false, - /* base64: */ false, - ), - 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 { - // --text --arg-deps-check should be error by Arg::new(options::CHECK)...conflicts_with(options::TEXT) - // https://github.com/clap-rs/clap/issues/4520 ? - // Let --{warn,strict,quiet,status,ignore-missing} reject --text and remove them later. - // Bad error message, but not a lie... - 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(options::BINARY) - .conflicts_with(options::TEXT) - .conflicts_with(options::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]) - .conflicts_with("text") - .requires(options::CHECK), - ) - .arg( - Arg::new(options::STATUS) - .short('s') - .long("status") - .help(translate!("hashsum-help-status")) - .action(ArgAction::SetTrue) - .overrides_with_all([options::QUIET, options::WARN]) - .conflicts_with("text") - .requires(options::CHECK), - ) - .arg( - Arg::new(options::STRICT) - .long("strict") - .help(translate!("hashsum-help-strict")) - .action(ArgAction::SetTrue) - .conflicts_with("text") - .requires(options::CHECK), - ) - .arg( - Arg::new("ignore-missing") - .long("ignore-missing") - .help(translate!("hashsum-help-ignore-missing")) - .action(ArgAction::SetTrue) - .conflicts_with("text") - .requires(options::CHECK), - ) - .arg( - Arg::new(options::WARN) - .short('w') - .long("warn") - .help(translate!("hashsum-help-warn")) - .action(ArgAction::SetTrue) - .overrides_with_all([options::QUIET, options::STATUS]) - .conflicts_with("text") - .requires(options::CHECK), - ) - .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/src/uucore/src/lib/features/checksum/mod.rs b/src/uucore/src/lib/features/checksum/mod.rs index e272cdea68b..54a2b8e00b4 100644 --- a/src/uucore/src/lib/features/checksum/mod.rs +++ b/src/uucore/src/lib/features/checksum/mod.rs @@ -374,6 +374,9 @@ pub enum ChecksumError { #[error("the --raw option is not supported with multiple files")] RawMultipleFiles, + #[error("the --{0} option is meaningful only when verifying checksums")] + CheckOnlyFlag(String), + // --length sanitization errors #[error("--length required for {}", .0.quote())] LengthRequired(String), diff --git a/src/uucore/src/lib/features/checksum/validate.rs b/src/uucore/src/lib/features/checksum/validate.rs index aa950abac37..a34d6ed77a9 100644 --- a/src/uucore/src/lib/features/checksum/validate.rs +++ b/src/uucore/src/lib/features/checksum/validate.rs @@ -456,7 +456,6 @@ impl LineInfo { /// In case of non-algo-based format, if `cached_line_format` is Some, it must take the priority /// over the detected format. Otherwise, we must set it the the detected format. /// This specific behavior is emphasized by the test - /// `test_hashsum::test_check_md5sum_only_one_space`. fn parse(s: impl AsRef, cached_line_format: &mut Option) -> Option { let line_bytes = os_str_as_bytes(s.as_ref()).ok()?; diff --git a/src/uucore/src/lib/lib.rs b/src/uucore/src/lib/lib.rs index c1ece8bff35..a16f2624994 100644 --- a/src/uucore/src/lib/lib.rs +++ b/src/uucore/src/lib/lib.rs @@ -172,9 +172,9 @@ pub fn get_canonical_util_name(util_name: &str) -> &str { // uu_test aliases - '[' is an alias for test "[" => "test", - // hashsum aliases - all these hash commands are aliases for hashsum + // cksum aliases - all these hash commands are aliases for cksum "md5sum" | "sha1sum" | "sha224sum" | "sha256sum" | "sha384sum" | "sha512sum" | "b2sum" => { - "hashsum" + "cksum" } "dir" => "ls", // dir is an alias for ls diff --git a/tests/by-util/test_hashsum.rs b/tests/by-util/test_hashsum.rs deleted file mode 100644 index 891cb9d4dfd..00000000000 --- a/tests/by-util/test_hashsum.rs +++ /dev/null @@ -1,1230 +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! {md5, md5} -test_digest! {sha1, sha1} -test_digest! {b3sum, b3sum} -test_digest! {shake128, shake128} -test_digest! {shake256, shake256} - -test_digest_with_len! {sha224, sha224, 224} -test_digest_with_len! {sha256, sha256, 256} -test_digest_with_len! {sha384, sha384, 384} -test_digest_with_len! {sha512, sha512, 512} -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} -test_digest_with_len! {b2sum, b2sum, 512} - -#[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(""); -} - -#[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 following required arguments were not provided"); //clap generated error -} - -#[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"); -} - -#[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"); -} - -#[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"); -} - -#[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] -#[case("513")] -#[case("1024")] -#[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"); -} - -#[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"); -} - -#[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"); -} - -#[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 -#[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 -#[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"); -} - -#[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(""); - } -} - -#[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); -} - -#[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", - ); -} - -#[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")); -} - -#[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")); -} - -#[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"); -} - -#[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"); -} - -#[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"); -} - -#[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(); -} - -#[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(); -} - -#[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(""); -} - -#[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"); -} - -#[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"); -} - -#[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"); -} - -#[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"); -} - -#[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"); -} - -#[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"); -} - -#[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"); -} - -#[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); -} - -#[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); -} - -#[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("the following required arguments were not provided"); //clap generated error - scene - .ccmd("md5sum") - .arg("--strict") - .arg(at.subdir.join("in.md5")) - .fails() - .stderr_contains("the following required arguments were not provided"); //clap generated error -} - -#[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"); -} - -#[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); -} - -#[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(); -} - -#[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"); -} - -#[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"); -} - -#[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() - ) - ); -} - -#[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 -#[test] -#[cfg_attr(windows, ignore = "Discussion is in #9168")] -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/fixtures/hashsum/b2sum.checkfile b/tests/fixtures/hashsum/b2sum.checkfile deleted file mode 100644 index 9d6781cc895..00000000000 --- a/tests/fixtures/hashsum/b2sum.checkfile +++ /dev/null @@ -1 +0,0 @@ -7355dd5276c21cfe0c593b5063b96af3f96a454b33216f58314f44c3ade92e9cd6cec4210a0836246780e9baf927cc50b9a3d7073e8f9bd12780fddbcb930c6d input.txt diff --git a/tests/fixtures/hashsum/b2sum.expected b/tests/fixtures/hashsum/b2sum.expected deleted file mode 100644 index a0dae0db450..00000000000 --- a/tests/fixtures/hashsum/b2sum.expected +++ /dev/null @@ -1 +0,0 @@ -7355dd5276c21cfe0c593b5063b96af3f96a454b33216f58314f44c3ade92e9cd6cec4210a0836246780e9baf927cc50b9a3d7073e8f9bd12780fddbcb930c6d \ No newline at end of file diff --git a/tests/fixtures/hashsum/b3sum.checkfile b/tests/fixtures/hashsum/b3sum.checkfile deleted file mode 100644 index f8d34d0b6f9..00000000000 --- a/tests/fixtures/hashsum/b3sum.checkfile +++ /dev/null @@ -1 +0,0 @@ -a1a55887535397bf461902491c8779188a5dd1f8c3951b3d9cf6ecba194e87b0 input.txt diff --git a/tests/fixtures/hashsum/b3sum.expected b/tests/fixtures/hashsum/b3sum.expected deleted file mode 100644 index a56e54432d0..00000000000 --- a/tests/fixtures/hashsum/b3sum.expected +++ /dev/null @@ -1 +0,0 @@ -a1a55887535397bf461902491c8779188a5dd1f8c3951b3d9cf6ecba194e87b0 \ No newline at end of file diff --git a/tests/fixtures/hashsum/binary.png b/tests/fixtures/hashsum/binary.png deleted file mode 100644 index 6c4161338f2..00000000000 Binary files a/tests/fixtures/hashsum/binary.png and /dev/null differ diff --git a/tests/fixtures/hashsum/binary.sha256.checkfile b/tests/fixtures/hashsum/binary.sha256.checkfile deleted file mode 100644 index 87fde491a09..00000000000 --- a/tests/fixtures/hashsum/binary.sha256.checkfile +++ /dev/null @@ -1 +0,0 @@ -ac10c6d06f343e26875366263d486a1e9f71115b9b80f0565902f79e947dca51 binary.png diff --git a/tests/fixtures/hashsum/binary.sha256.expected b/tests/fixtures/hashsum/binary.sha256.expected deleted file mode 100644 index 3003abf463b..00000000000 --- a/tests/fixtures/hashsum/binary.sha256.expected +++ /dev/null @@ -1 +0,0 @@ -ac10c6d06f343e26875366263d486a1e9f71115b9b80f0565902f79e947dca51 \ No newline at end of file diff --git a/tests/fixtures/hashsum/input.txt b/tests/fixtures/hashsum/input.txt deleted file mode 100644 index 8c01d89ae06..00000000000 --- a/tests/fixtures/hashsum/input.txt +++ /dev/null @@ -1 +0,0 @@ -hello, world \ No newline at end of file diff --git a/tests/fixtures/hashsum/md5.checkfile b/tests/fixtures/hashsum/md5.checkfile deleted file mode 100644 index 328e1bd9454..00000000000 --- a/tests/fixtures/hashsum/md5.checkfile +++ /dev/null @@ -1 +0,0 @@ -e4d7f1b4ed2e42d15898f4b27b019da4 input.txt diff --git a/tests/fixtures/hashsum/md5.expected b/tests/fixtures/hashsum/md5.expected deleted file mode 100644 index 9a78d4ab7d7..00000000000 --- a/tests/fixtures/hashsum/md5.expected +++ /dev/null @@ -1 +0,0 @@ -e4d7f1b4ed2e42d15898f4b27b019da4 \ No newline at end of file diff --git a/tests/fixtures/hashsum/sha1.checkfile b/tests/fixtures/hashsum/sha1.checkfile deleted file mode 100644 index 02c35969fae..00000000000 --- a/tests/fixtures/hashsum/sha1.checkfile +++ /dev/null @@ -1 +0,0 @@ -b7e23ec29af22b0b4e41da31e868d57226121c84 input.txt diff --git a/tests/fixtures/hashsum/sha1.expected b/tests/fixtures/hashsum/sha1.expected deleted file mode 100644 index 8a50a732e08..00000000000 --- a/tests/fixtures/hashsum/sha1.expected +++ /dev/null @@ -1 +0,0 @@ -b7e23ec29af22b0b4e41da31e868d57226121c84 \ No newline at end of file diff --git a/tests/fixtures/hashsum/sha224.checkfile b/tests/fixtures/hashsum/sha224.checkfile deleted file mode 100644 index 6e3402094f1..00000000000 --- a/tests/fixtures/hashsum/sha224.checkfile +++ /dev/null @@ -1 +0,0 @@ -6e1a93e32fb44081a401f3db3ef2e6e108b7bbeeb5705afdaf01fb27 input.txt diff --git a/tests/fixtures/hashsum/sha224.expected b/tests/fixtures/hashsum/sha224.expected deleted file mode 100644 index 456eca80826..00000000000 --- a/tests/fixtures/hashsum/sha224.expected +++ /dev/null @@ -1 +0,0 @@ -6e1a93e32fb44081a401f3db3ef2e6e108b7bbeeb5705afdaf01fb27 \ No newline at end of file diff --git a/tests/fixtures/hashsum/sha256.checkfile b/tests/fixtures/hashsum/sha256.checkfile deleted file mode 100644 index db1d2be1588..00000000000 --- a/tests/fixtures/hashsum/sha256.checkfile +++ /dev/null @@ -1 +0,0 @@ -09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b input.txt diff --git a/tests/fixtures/hashsum/sha256.expected b/tests/fixtures/hashsum/sha256.expected deleted file mode 100644 index 8def5979154..00000000000 --- a/tests/fixtures/hashsum/sha256.expected +++ /dev/null @@ -1 +0,0 @@ -09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b \ No newline at end of file diff --git a/tests/fixtures/hashsum/sha384.checkfile b/tests/fixtures/hashsum/sha384.checkfile deleted file mode 100644 index c53326b1da0..00000000000 --- a/tests/fixtures/hashsum/sha384.checkfile +++ /dev/null @@ -1 +0,0 @@ -1fcdb6059ce05172a26bbe2a3ccc88ed5a8cd5fc53edfd9053304d429296a6da23b1cd9e5c9ed3bb34f00418a70cdb7e input.txt diff --git a/tests/fixtures/hashsum/sha384.expected b/tests/fixtures/hashsum/sha384.expected deleted file mode 100644 index 489dbcef7bc..00000000000 --- a/tests/fixtures/hashsum/sha384.expected +++ /dev/null @@ -1 +0,0 @@ -1fcdb6059ce05172a26bbe2a3ccc88ed5a8cd5fc53edfd9053304d429296a6da23b1cd9e5c9ed3bb34f00418a70cdb7e \ No newline at end of file diff --git a/tests/fixtures/hashsum/sha3_224.checkfile b/tests/fixtures/hashsum/sha3_224.checkfile deleted file mode 100644 index 3a93cd05696..00000000000 --- a/tests/fixtures/hashsum/sha3_224.checkfile +++ /dev/null @@ -1 +0,0 @@ -927b362eaf84a75785bbec3370d1c9711349e93f1104eda060784221 input.txt diff --git a/tests/fixtures/hashsum/sha3_224.expected b/tests/fixtures/hashsum/sha3_224.expected deleted file mode 100644 index 595f998806e..00000000000 --- a/tests/fixtures/hashsum/sha3_224.expected +++ /dev/null @@ -1 +0,0 @@ -927b362eaf84a75785bbec3370d1c9711349e93f1104eda060784221 \ No newline at end of file diff --git a/tests/fixtures/hashsum/sha3_256.checkfile b/tests/fixtures/hashsum/sha3_256.checkfile deleted file mode 100644 index b8bec09241b..00000000000 --- a/tests/fixtures/hashsum/sha3_256.checkfile +++ /dev/null @@ -1 +0,0 @@ -bfb3959527d7a3f2f09def2f6915452d55a8f122df9e164d6f31c7fcf6093e14 input.txt diff --git a/tests/fixtures/hashsum/sha3_256.expected b/tests/fixtures/hashsum/sha3_256.expected deleted file mode 100644 index 46c21e5298d..00000000000 --- a/tests/fixtures/hashsum/sha3_256.expected +++ /dev/null @@ -1 +0,0 @@ -bfb3959527d7a3f2f09def2f6915452d55a8f122df9e164d6f31c7fcf6093e14 \ No newline at end of file diff --git a/tests/fixtures/hashsum/sha3_384.checkfile b/tests/fixtures/hashsum/sha3_384.checkfile deleted file mode 100644 index 6b014fdd2e0..00000000000 --- a/tests/fixtures/hashsum/sha3_384.checkfile +++ /dev/null @@ -1 +0,0 @@ -fbd0c5931195aaa9517869972b372f717bb69f7f9f72bfc0884ed0531c36a16fc2db5dd6d82131968b23ffe0e90757e5 input.txt diff --git a/tests/fixtures/hashsum/sha3_384.expected b/tests/fixtures/hashsum/sha3_384.expected deleted file mode 100644 index 8c975b0958b..00000000000 --- a/tests/fixtures/hashsum/sha3_384.expected +++ /dev/null @@ -1 +0,0 @@ -fbd0c5931195aaa9517869972b372f717bb69f7f9f72bfc0884ed0531c36a16fc2db5dd6d82131968b23ffe0e90757e5 \ No newline at end of file diff --git a/tests/fixtures/hashsum/sha3_512.checkfile b/tests/fixtures/hashsum/sha3_512.checkfile deleted file mode 100644 index 125e2dfba15..00000000000 --- a/tests/fixtures/hashsum/sha3_512.checkfile +++ /dev/null @@ -1 +0,0 @@ -2ed3a863a12e2f8ff140aa86232ff3603a7f24af62f0e2ca74672494ade175a9a3de42a351b5019d931a1deae0499609038d9b47268779d76198e1d410d20974 input.txt diff --git a/tests/fixtures/hashsum/sha3_512.expected b/tests/fixtures/hashsum/sha3_512.expected deleted file mode 100644 index f766857ba6d..00000000000 --- a/tests/fixtures/hashsum/sha3_512.expected +++ /dev/null @@ -1 +0,0 @@ -2ed3a863a12e2f8ff140aa86232ff3603a7f24af62f0e2ca74672494ade175a9a3de42a351b5019d931a1deae0499609038d9b47268779d76198e1d410d20974 \ No newline at end of file diff --git a/tests/fixtures/hashsum/sha512.checkfile b/tests/fixtures/hashsum/sha512.checkfile deleted file mode 100644 index 41a55cabbb5..00000000000 --- a/tests/fixtures/hashsum/sha512.checkfile +++ /dev/null @@ -1 +0,0 @@ -8710339dcb6814d0d9d2290ef422285c9322b7163951f9a0ca8f883d3305286f44139aa374848e4174f5aada663027e4548637b6d19894aec4fb6c46a139fbf9 input.txt diff --git a/tests/fixtures/hashsum/sha512.expected b/tests/fixtures/hashsum/sha512.expected deleted file mode 100644 index fd817368620..00000000000 --- a/tests/fixtures/hashsum/sha512.expected +++ /dev/null @@ -1 +0,0 @@ -8710339dcb6814d0d9d2290ef422285c9322b7163951f9a0ca8f883d3305286f44139aa374848e4174f5aada663027e4548637b6d19894aec4fb6c46a139fbf9 \ No newline at end of file diff --git a/tests/fixtures/hashsum/shake128.checkfile b/tests/fixtures/hashsum/shake128.checkfile deleted file mode 100644 index a3769f78ee5..00000000000 --- a/tests/fixtures/hashsum/shake128.checkfile +++ /dev/null @@ -1 +0,0 @@ -83d41db453072caa9953f2f316480fbbcb84a5f3505460a18b3a36a814ae8e9e input.txt diff --git a/tests/fixtures/hashsum/shake128.expected b/tests/fixtures/hashsum/shake128.expected deleted file mode 100644 index a184b53e490..00000000000 --- a/tests/fixtures/hashsum/shake128.expected +++ /dev/null @@ -1 +0,0 @@ -83d41db453072caa9953f2f316480fbbcb84a5f3505460a18b3a36a814ae8e9e \ No newline at end of file diff --git a/tests/fixtures/hashsum/shake256.checkfile b/tests/fixtures/hashsum/shake256.checkfile deleted file mode 100644 index e16601f3044..00000000000 --- a/tests/fixtures/hashsum/shake256.checkfile +++ /dev/null @@ -1 +0,0 @@ -7c9896ea84a2a1b80b2183a3f2b4e43cd59b7d48471dc213bcedaccb699d6e6f7ad5d304928ab79329f1fc62f6db072d95b51209eb807683f5c9371872a2dd4e input.txt diff --git a/tests/fixtures/hashsum/shake256.expected b/tests/fixtures/hashsum/shake256.expected deleted file mode 100644 index 6e7ef141776..00000000000 --- a/tests/fixtures/hashsum/shake256.expected +++ /dev/null @@ -1 +0,0 @@ -7c9896ea84a2a1b80b2183a3f2b4e43cd59b7d48471dc213bcedaccb699d6e6f7ad5d304928ab79329f1fc62f6db072d95b51209eb807683f5c9371872a2dd4e \ No newline at end of file diff --git a/tests/fixtures/head/zero_terminated.txt b/tests/fixtures/head/zero_terminated.txt index 6c7968122e2..de031ea4819 100644 Binary files a/tests/fixtures/head/zero_terminated.txt and b/tests/fixtures/head/zero_terminated.txt differ diff --git a/tests/fixtures/sort/zero-terminated.expected b/tests/fixtures/sort/zero-terminated.expected index 4e53b304bb3..5c2f43a4482 100644 Binary files a/tests/fixtures/sort/zero-terminated.expected and b/tests/fixtures/sort/zero-terminated.expected differ diff --git a/tests/fixtures/sort/zero-terminated.expected.debug b/tests/fixtures/sort/zero-terminated.expected.debug index fbef272b02c..1fdc1da8d87 100644 --- a/tests/fixtures/sort/zero-terminated.expected.debug +++ b/tests/fixtures/sort/zero-terminated.expected.debug @@ -46,8 +46,6 @@ _____________________ __________________ ../../fixtures/fold ___________________ -../../fixtures/hashsum -______________________ ../../fixtures/head ___________________ ../../fixtures/join diff --git a/tests/fixtures/sort/zero-terminated.txt b/tests/fixtures/sort/zero-terminated.txt index 5c547c851ce..bb2aa200e81 100644 Binary files a/tests/fixtures/sort/zero-terminated.txt and b/tests/fixtures/sort/zero-terminated.txt differ 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 9ffdfd4a312..35ac46a9936 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -144,10 +144,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 3cc48794030..719b803f411 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 @@ -15,7 +15,7 @@ ME_parent_dir_abs="$("${REALPATH}" -mP -- "${ME_parent_dir}" || "${REALPATH}" -- # refs: , # default ("Tier 1" cross-platform) utility list -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" +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" project_main_dir="${ME_parent_dir_abs}" # printf 'project_main_dir="%s"\n' "${project_main_dir}"