From fbd0d0ee6b783662851a124152051d3be6a7deaf Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Mon, 31 Jan 2022 13:47:09 +0000 Subject: [PATCH] hashsum: Refactor `uu_app` to isolate non-"GNU Coreutils" options Several binaries have been added to `hashsum` that have never been part of GNU Coreutils: - `sha3*sum` (uutils/coreutils#869) - `shake*sum` (uutils/coreutils#987) - `b3sum` (uutils/coreutils#3108 and uutils/coreutils#3164) In particular, the `--bits` option, and the `--no-names` option added in uutils/coreutils#3361, are not valid for any GNU Coreutils `*sum` binary (as of Coreutils 9.0). This commit refactors the argument parsing so that `--bits` and `--no-names` become invalid options for the binaries intended to match the GNU Coreutils API, instead of being ignored options. It also refactors the custom binary name handling to distinguish between binaries intended to match the GNU Coreutils API, and binaries that don't have that constraint. Part of uutils/coreutils#2930. --- build.rs | 10 ++-- src/uu/hashsum/src/hashsum.rs | 88 +++++++++++++++++++---------------- 2 files changed, 56 insertions(+), 42 deletions(-) diff --git a/build.rs b/build.rs index 3df8d891d58..570911a88c0 100644 --- a/build.rs +++ b/build.rs @@ -104,6 +104,10 @@ pub fn main() { ); let map_value = format!("({krate}::uumain, {krate}::uu_app_common)", krate = krate); + let map_value_shake = + format!("({krate}::uumain, {krate}::uu_app_shake)", krate = krate); + let map_value_b3sum = + format!("({krate}::uumain, {krate}::uu_app_b3sum)", krate = krate); phf_map.entry("md5sum", &map_value); phf_map.entry("sha1sum", &map_value); phf_map.entry("sha224sum", &map_value); @@ -115,10 +119,10 @@ pub fn main() { phf_map.entry("sha3-256sum", &map_value); phf_map.entry("sha3-384sum", &map_value); phf_map.entry("sha3-512sum", &map_value); - phf_map.entry("shake128sum", &map_value); - phf_map.entry("shake256sum", &map_value); + phf_map.entry("shake128sum", &map_value_shake); + phf_map.entry("shake256sum", &map_value_shake); phf_map.entry("b2sum", &map_value); - phf_map.entry("b3sum", &map_value); + phf_map.entry("b3sum", &map_value_b3sum); tf.write_all( format!( "#[path=\"{dir}/test_{krate}.rs\"]\nmod test_{krate};\n", diff --git a/src/uu/hashsum/src/hashsum.rs b/src/uu/hashsum/src/hashsum.rs index 872cb5c21d1..3e4fdc98e9a 100644 --- a/src/uu/hashsum/src/hashsum.rs +++ b/src/uu/hashsum/src/hashsum.rs @@ -54,27 +54,6 @@ struct Options { output_bits: usize, } -fn is_custom_binary(program: &str) -> bool { - matches!( - program, - "md5sum" - | "sha1sum" - | "sha224sum" - | "sha256sum" - | "sha384sum" - | "sha512sum" - | "sha3sum" - | "sha3-224sum" - | "sha3-256sum" - | "sha3-384sum" - | "sha3-512sum" - | "shake128sum" - | "shake256sum" - | "b2sum" - | "b3sum" - ) -} - #[allow(clippy::cognitive_complexity)] fn detect_algo( program: &str, @@ -373,11 +352,6 @@ pub fn uu_app_common<'a>() -> Command<'a> { .long("tag") .help("create a BSD-style checksum"), ) - .arg( - Arg::new("no-names") - .long("no-names") - .help("Omits filenames in the output (option not present in GNU/Coreutils)"), - ) .arg( Arg::new("text") .short('t') @@ -408,6 +382,34 @@ pub fn uu_app_common<'a>() -> Command<'a> { .long("warn") .help("warn about improperly formatted checksum lines"), ) + .arg( + Arg::new("FILE") + .index(1) + .multiple_occurrences(true) + .value_name("FILE") + .value_hint(clap::ValueHint::FilePath) + .allow_invalid_utf8(true), + ) +} + +pub fn uu_app_b3sum<'a>() -> Command<'a> { + uu_app_b3sum_opts(uu_app_common()) +} + +fn uu_app_b3sum_opts<'a>(command: Command<'a>) -> Command<'a> { + command.arg( + Arg::new("no-names") + .long("no-names") + .help("Omits filenames in the output (option not present in GNU/Coreutils)"), + ) +} + +pub fn uu_app_shake<'a>() -> Command<'a> { + uu_app_shake_opts(uu_app_common()) +} + +fn uu_app_shake_opts<'a>(command: Command<'a>) -> Command<'a> { + command // Needed for variable-length output sums (e.g. SHAKE) .arg( Arg::new("bits") @@ -418,18 +420,10 @@ pub fn uu_app_common<'a>() -> Command<'a> { // XXX: should we actually use validators? they're not particularly efficient .validator(is_valid_bit_num), ) - .arg( - Arg::new("FILE") - .index(1) - .multiple_occurrences(true) - .value_name("FILE") - .value_hint(clap::ValueHint::FilePath) - .allow_invalid_utf8(true), - ) } pub fn uu_app_custom<'a>() -> Command<'a> { - let mut command = uu_app_common(); + let mut command = uu_app_b3sum_opts(uu_app_shake_opts(uu_app_common())); let algorithms = &[ ("md5", "work with MD5"), ("sha1", "work with SHA1"), @@ -463,10 +457,26 @@ pub fn uu_app_custom<'a>() -> Command<'a> { // hashsum is handled differently in build.rs, therefore this is not the same // as in other utilities. fn uu_app<'a>(binary_name: &str) -> Command<'a> { - if !is_custom_binary(binary_name) { - uu_app_custom() - } else { - uu_app_common() + match binary_name { + // These all support the same options. + "md5sum" | "sha1sum" | "sha224sum" | "sha256sum" | "sha384sum" | "sha512sum" => { + uu_app_common() + } + // b2sum supports the md5sum options plus -l/--length. + "b2sum" => uu_app_common(), // TODO: Implement -l/--length + // These have never been part of GNU Coreutils, but can function with the same + // options as md5sum. + "sha3sum" | "sha3-224sum" | "sha3-256sum" | "sha3-384sum" | "sha3-512sum" => { + uu_app_common() + } + // These have never been part of GNU Coreutils, and require an additional --bits + // option to specify their output size. + "shake128sum" | "shake256sum" => uu_app_shake(), + // b3sum has never been part of GNU Coreutils, and has a --no-names option in + // addition to the b2sum options. + "b3sum" => uu_app_b3sum(), + // We're probably just being called as `hashsum`, so give them everything. + _ => uu_app_custom(), } }