From df7136837ac03a282cff6cd9d1acfd406cd73599 Mon Sep 17 00:00:00 2001 From: Shun Sakai Date: Wed, 14 Sep 2022 19:53:05 +0900 Subject: [PATCH 1/3] Rewrite CLI using Derive API --- b3sum/Cargo.lock | 191 ++++++++++++++++++++++++++------------- b3sum/Cargo.toml | 2 +- b3sum/README.md | 2 +- b3sum/src/main.rs | 221 ++++++++++++++++++++-------------------------- 4 files changed, 232 insertions(+), 184 deletions(-) diff --git a/b3sum/Cargo.lock b/b3sum/Cargo.lock index 212e4924..c1596656 100644 --- a/b3sum/Cargo.lock +++ b/b3sum/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "anyhow" -version = "1.0.56" +version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27" +checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602" [[package]] name = "arrayref" @@ -73,9 +73,9 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" dependencies = [ "generic-array", ] @@ -94,19 +94,43 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "3.1.6" +version = "3.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8c93436c21e4698bacadf42917db28b23017027a4deccb35dbe47a7e7840123" +checksum = "1ed5341b2301a26ab80be5cbdced622e80ed808483c52e45e3310a877d3b37d7" dependencies = [ "atty", "bitflags", + "clap_derive", + "clap_lex", "indexmap", - "os_str_bytes", + "once_cell", "strsim", "termcolor", "textwrap", ] +[[package]] +name = "clap_derive" +version = "3.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", +] + [[package]] name = "constant_time_eq" version = "0.1.5" @@ -115,9 +139,9 @@ checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" [[package]] name = "crossbeam-channel" -version = "0.5.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53" +checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" dependencies = [ "cfg-if", "crossbeam-utils", @@ -125,9 +149,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" dependencies = [ "cfg-if", "crossbeam-epoch", @@ -136,33 +160,33 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.8" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c" +checksum = "045ebe27666471bb549370b4b0b3e51b07f56325befa4284db65fc89c02511b1" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "lazy_static", "memoffset", + "once_cell", "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.8" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" +checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc" dependencies = [ "cfg-if", - "lazy_static", + "once_cell", ] [[package]] name = "crypto-common" -version = "0.1.3" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", "typenum", @@ -193,24 +217,24 @@ dependencies = [ [[package]] name = "either" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" [[package]] name = "fastrand" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" +checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" dependencies = [ "instant", ] [[package]] name = "generic-array" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" dependencies = [ "typenum", "version_check", @@ -224,9 +248,15 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "hashbrown" -version = "0.11.2" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "heck" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" [[package]] name = "hermit-abi" @@ -245,9 +275,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "indexmap" -version = "1.8.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" +checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" dependencies = [ "autocfg", "hashbrown", @@ -262,29 +292,17 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - [[package]] name = "libc" -version = "0.2.121" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f" - -[[package]] -name = "memchr" -version = "2.4.1" +version = "0.2.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" [[package]] name = "memmap2" -version = "0.5.3" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "057a3db23999c867821a7a59feb06a578fcb03685e983dff90daf9e7d24ac08f" +checksum = "95af15f345b17af2efc8ead6080fb8bc376f8cec1b35277b935637595fe77498" dependencies = [ "libc", ] @@ -310,9 +328,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.10.0" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" +checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0" [[package]] name = "os_pipe" @@ -326,18 +344,57 @@ dependencies = [ [[package]] name = "os_str_bytes" -version = "6.0.0" +version = "6.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff" + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" dependencies = [ - "memchr", + "proc-macro2", ] [[package]] name = "rayon" -version = "1.5.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" dependencies = [ "autocfg", "crossbeam-deque", @@ -347,22 +404,21 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.9.1" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" dependencies = [ "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "lazy_static", "num_cpus", ] [[package]] name = "redox_syscall" -version = "0.2.12" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae183fc1b06c149f0c1793e1eb447c8b04bfe46d48e9e48bfb8d2d7ed64ecf0" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ "bitflags", ] @@ -404,6 +460,17 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +[[package]] +name = "syn" +version = "1.0.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "tempfile" version = "3.3.0" @@ -439,6 +506,12 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +[[package]] +name = "unicode-ident" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd" + [[package]] name = "version_check" version = "0.9.4" @@ -447,9 +520,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "wild" -version = "2.0.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "035793abb854745033f01a07647a79831eba29ec0be377205f2a25b0aa830020" +checksum = "05b116685a6be0c52f5a103334cbff26db643826c7b3735fc0a3ba9871310a74" dependencies = [ "glob", ] diff --git a/b3sum/Cargo.toml b/b3sum/Cargo.toml index 3c567b1f..1b44c1c6 100644 --- a/b3sum/Cargo.toml +++ b/b3sum/Cargo.toml @@ -16,7 +16,7 @@ pure = ["blake3/pure"] [dependencies] anyhow = "1.0.25" blake3 = { version = "1", path = "..", features = ["rayon"] } -clap = "3.0.5" +clap = { version = "3.2.21", features = ["derive"] } hex = "0.4.0" memmap2 = "0.5.3" rayon = "1.2.1" diff --git a/b3sum/README.md b/b3sum/README.md index 0b5e7f93..f7438f8c 100644 --- a/b3sum/README.md +++ b/b3sum/README.md @@ -22,7 +22,7 @@ OPTIONS: --keyed Uses the keyed mode. The secret key is read from standard input, and it must be exactly 32 raw bytes. -l, --length The number of output bytes, prior to hex - encoding (default 32) + encoding [default: 32] --no-mmap Disables memory mapping. Currently this also disables multithreading. --no-names Omits filenames in the output diff --git a/b3sum/src/main.rs b/b3sum/src/main.rs index 0b692a2c..3dc0cd20 100644 --- a/b3sum/src/main.rs +++ b/b3sum/src/main.rs @@ -1,5 +1,5 @@ -use anyhow::{bail, ensure, Context, Result}; -use clap::{Arg, Command}; +use anyhow::{bail, ensure, Result}; +use clap::Parser; use std::cmp; use std::convert::TryInto; use std::fs::File; @@ -12,124 +12,111 @@ mod unit_tests; const NAME: &str = "b3sum"; -const FILE_ARG: &str = "FILE"; const DERIVE_KEY_ARG: &str = "derive-key"; const KEYED_ARG: &str = "keyed"; const LENGTH_ARG: &str = "length"; -const NO_MMAP_ARG: &str = "no-mmap"; const NO_NAMES_ARG: &str = "no-names"; -const NUM_THREADS_ARG: &str = "num-threads"; const RAW_ARG: &str = "raw"; const CHECK_ARG: &str = "check"; -const QUIET_ARG: &str = "quiet"; + +#[derive(Parser)] +#[clap(version)] +struct Inner { + /// Files to hash, or checkfiles to check. When no file is given, + /// or when - is given, read standard input. + #[clap(value_parser, verbatim_doc_comment)] + file: Vec, + + /// The number of output bytes, prior to hex + /// encoding + #[clap( + long, + short, + value_name("LEN"), + default_value_t = blake3::OUT_LEN as u64, + verbatim_doc_comment + )] + length: u64, + + /// The maximum number of threads to use. By + /// default, this is the number of logical cores. + /// If this flag is omitted, or if its value is 0, + /// RAYON_NUM_THREADS is also respected. + #[clap(long, value_name("NUM"), verbatim_doc_comment)] + num_threads: Option, + + /// Uses the keyed mode. The secret key is read from standard + /// input, and it must be exactly 32 raw bytes. + #[clap(long, requires("file"), verbatim_doc_comment)] + keyed: bool, + + /// Uses the key derivation mode, with the given + /// context string. Cannot be used with --keyed. + #[clap( + long, + conflicts_with(KEYED_ARG), + value_name("CONTEXT"), + verbatim_doc_comment + )] + derive_key: Option, + + /// Disables memory mapping. Currently this also disables + /// multithreading. + #[clap(long, verbatim_doc_comment)] + no_mmap: bool, + + /// Omits filenames in the output + #[clap(long)] + no_names: bool, + + /// Writes raw output bytes to stdout, rather than hex. + /// --no-names is implied. In this case, only a single + /// input is allowed. + #[clap(long, verbatim_doc_comment)] + raw: bool, + + /// Reads BLAKE3 sums from the [FILE]s and checks them + #[clap( + long, + short, + conflicts_with(DERIVE_KEY_ARG), + conflicts_with(KEYED_ARG), + conflicts_with(LENGTH_ARG), + conflicts_with(RAW_ARG), + conflicts_with(NO_NAMES_ARG) + )] + check: bool, + + /// Skips printing OK for each successfully verified file. + /// Must be used with --check. + #[clap(long, requires(CHECK_ARG), verbatim_doc_comment)] + quiet: bool, +} struct Args { - inner: clap::ArgMatches, + inner: Inner, file_args: Vec, base_hasher: blake3::Hasher, } impl Args { fn parse() -> Result { - let inner = Command::new(NAME) - .version(env!("CARGO_PKG_VERSION")) - .arg( - Arg::new(FILE_ARG) - .multiple_occurrences(true) - .allow_invalid_utf8(true) - .help( - "Files to hash, or checkfiles to check. When no file is given,\n\ - or when - is given, read standard input.", - ), - ) - .arg( - Arg::new(LENGTH_ARG) - .long(LENGTH_ARG) - .short('l') - .takes_value(true) - .value_name("LEN") - .help( - "The number of output bytes, prior to hex\n\ - encoding (default 32)", - ), - ) - .arg( - Arg::new(NUM_THREADS_ARG) - .long(NUM_THREADS_ARG) - .takes_value(true) - .value_name("NUM") - .help( - "The maximum number of threads to use. By\n\ - default, this is the number of logical cores.\n\ - If this flag is omitted, or if its value is 0,\n\ - RAYON_NUM_THREADS is also respected.", - ), - ) - .arg(Arg::new(KEYED_ARG).long(KEYED_ARG).requires(FILE_ARG).help( - "Uses the keyed mode. The secret key is read from standard\n\ - input, and it must be exactly 32 raw bytes.", - )) - .arg( - Arg::new(DERIVE_KEY_ARG) - .long(DERIVE_KEY_ARG) - .conflicts_with(KEYED_ARG) - .takes_value(true) - .value_name("CONTEXT") - .help( - "Uses the key derivation mode, with the given\n\ - context string. Cannot be used with --keyed.", - ), - ) - .arg(Arg::new(NO_MMAP_ARG).long(NO_MMAP_ARG).help( - "Disables memory mapping. Currently this also disables\n\ - multithreading.", - )) - .arg( - Arg::new(NO_NAMES_ARG) - .long(NO_NAMES_ARG) - .help("Omits filenames in the output"), - ) - .arg(Arg::new(RAW_ARG).long(RAW_ARG).help( - "Writes raw output bytes to stdout, rather than hex.\n\ - --no-names is implied. In this case, only a single\n\ - input is allowed.", - )) - .arg( - Arg::new(CHECK_ARG) - .long(CHECK_ARG) - .short('c') - .conflicts_with(DERIVE_KEY_ARG) - .conflicts_with(KEYED_ARG) - .conflicts_with(LENGTH_ARG) - .conflicts_with(RAW_ARG) - .conflicts_with(NO_NAMES_ARG) - .help("Reads BLAKE3 sums from the [FILE]s and checks them"), - ) - .arg( - Arg::new(QUIET_ARG) - .long(QUIET_ARG) - .requires(CHECK_ARG) - .help( - "Skips printing OK for each successfully verified file.\n\ - Must be used with --check.", - ), - ) - // wild::args_os() is equivalent to std::env::args_os() on Unix, - // but on Windows it adds support for globbing. - .get_matches_from(wild::args_os()); - let file_args = if let Some(iter) = inner.values_of_os(FILE_ARG) { - iter.map(|s| s.into()).collect() + // wild::args_os() is equivalent to std::env::args_os() on Unix, + // but on Windows it adds support for globbing. + let inner = Inner::parse_from(wild::args_os()); + let file_args = if !inner.file.is_empty() { + inner.file.clone() } else { vec!["-".into()] }; - if inner.is_present(RAW_ARG) && file_args.len() > 1 { + if inner.raw && file_args.len() > 1 { bail!("Only one filename can be provided when using --raw"); } - let base_hasher = if inner.is_present(KEYED_ARG) { + let base_hasher = if inner.keyed { // In keyed mode, since stdin is used for the key, we can't handle // `-` arguments. Input::open handles that case below. blake3::Hasher::new_keyed(&read_key_from_stdin()?) - } else if let Some(context) = inner.value_of(DERIVE_KEY_ARG) { + } else if let Some(ref context) = inner.derive_key { blake3::Hasher::new_derive_key(context) } else { blake3::Hasher::new() @@ -141,48 +128,36 @@ impl Args { }) } - fn num_threads(&self) -> Result> { - if let Some(num_threads_str) = self.inner.value_of(NUM_THREADS_ARG) { - Ok(Some( - num_threads_str - .parse() - .context("Failed to parse num threads.")?, - )) - } else { - Ok(None) - } + fn num_threads(&self) -> Option { + self.inner.num_threads } fn check(&self) -> bool { - self.inner.is_present(CHECK_ARG) + self.inner.check } fn raw(&self) -> bool { - self.inner.is_present(RAW_ARG) + self.inner.raw } fn no_mmap(&self) -> bool { - self.inner.is_present(NO_MMAP_ARG) + self.inner.no_mmap } fn no_names(&self) -> bool { - self.inner.is_present(NO_NAMES_ARG) + self.inner.no_names } - fn len(&self) -> Result { - if let Some(length) = self.inner.value_of(LENGTH_ARG) { - length.parse::().context("Failed to parse length.") - } else { - Ok(blake3::OUT_LEN as u64) - } + fn len(&self) -> u64 { + self.inner.length } fn keyed(&self) -> bool { - self.inner.is_present(KEYED_ARG) + self.inner.keyed } fn quiet(&self) -> bool { - self.inner.is_present(QUIET_ARG) + self.inner.quiet } } @@ -307,7 +282,7 @@ fn maybe_memmap_file(file: &File) -> Result> { fn write_hex_output(mut output: blake3::OutputReader, args: &Args) -> Result<()> { // Encoding multiples of the block size is most efficient. - let mut len = args.len()?; + let mut len = args.len(); let mut block = [0; blake3::guts::BLOCK_LEN]; while len > 0 { output.fill(&mut block); @@ -320,7 +295,7 @@ fn write_hex_output(mut output: blake3::OutputReader, args: &Args) -> Result<()> } fn write_raw_output(output: blake3::OutputReader, args: &Args) -> Result<()> { - let mut output = output.take(args.len()?); + let mut output = output.take(args.len()); let stdout = std::io::stdout(); let mut handler = stdout.lock(); std::io::copy(&mut output, &mut handler)?; @@ -589,7 +564,7 @@ fn check_one_checkfile(path: &Path, args: &Args, some_file_failed: &mut bool) -> fn main() -> Result<()> { let args = Args::parse()?; let mut thread_pool_builder = rayon::ThreadPoolBuilder::new(); - if let Some(num_threads) = args.num_threads()? { + if let Some(num_threads) = args.num_threads() { thread_pool_builder = thread_pool_builder.num_threads(num_threads); } let thread_pool = thread_pool_builder.build()?; From e4dfb96b411fb0a6a28c0ee1e204ab06550b4bf5 Mon Sep 17 00:00:00 2001 From: Shun Sakai Date: Mon, 3 Oct 2022 12:07:33 +0900 Subject: [PATCH 2/3] Bump clap to v4.0 --- b3sum/Cargo.lock | 40 +++++++------------------------- b3sum/Cargo.toml | 2 +- b3sum/README.md | 59 ++++++++++++++++++++++------------------------- b3sum/src/main.rs | 48 +++++++++++++++++++++++--------------- 4 files changed, 66 insertions(+), 83 deletions(-) diff --git a/b3sum/Cargo.lock b/b3sum/Cargo.lock index c1596656..793cc36f 100644 --- a/b3sum/Cargo.lock +++ b/b3sum/Cargo.lock @@ -94,26 +94,24 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "3.2.21" +version = "4.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ed5341b2301a26ab80be5cbdced622e80ed808483c52e45e3310a877d3b37d7" +checksum = "5840cd9093aabeabf7fd932754c435b7674520fc3ddc935c397837050f0f1e4b" dependencies = [ "atty", "bitflags", "clap_derive", "clap_lex", - "indexmap", "once_cell", "strsim", "termcolor", - "textwrap", ] [[package]] name = "clap_derive" -version = "3.2.18" +version = "4.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65" +checksum = "92289ffc6fb4a85d85c246ddb874c05a87a2e540fb6ad52f7ca07c8c1e1840b1" dependencies = [ "heck", "proc-macro-error", @@ -124,9 +122,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.2.4" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" dependencies = [ "os_str_bytes", ] @@ -246,12 +244,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - [[package]] name = "heck" version = "0.4.0" @@ -273,16 +265,6 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -[[package]] -name = "indexmap" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" -dependencies = [ - "autocfg", - "hashbrown", -] - [[package]] name = "instant" version = "0.1.12" @@ -294,9 +276,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.132" +version = "0.2.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" +checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966" [[package]] name = "memmap2" @@ -494,12 +476,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "textwrap" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" - [[package]] name = "typenum" version = "1.15.0" diff --git a/b3sum/Cargo.toml b/b3sum/Cargo.toml index 1b44c1c6..13ddc706 100644 --- a/b3sum/Cargo.toml +++ b/b3sum/Cargo.toml @@ -16,7 +16,7 @@ pure = ["blake3/pure"] [dependencies] anyhow = "1.0.25" blake3 = { version = "1", path = "..", features = ["rayon"] } -clap = { version = "3.2.21", features = ["derive"] } +clap = { version = "4.0.8", features = ["derive"] } hex = "0.4.0" memmap2 = "0.5.3" rayon = "1.2.1" diff --git a/b3sum/README.md b/b3sum/README.md index f7438f8c..86bfa1e1 100644 --- a/b3sum/README.md +++ b/b3sum/README.md @@ -5,37 +5,34 @@ A command line utility for calculating Coreutils tools like `b2sum` or `md5sum`. ``` -b3sum 1.3.1 - -USAGE: - b3sum [OPTIONS] [FILE]... - -ARGS: - ... Files to hash, or checkfiles to check. When no file is given, - or when - is given, read standard input. - -OPTIONS: - -c, --check Reads BLAKE3 sums from the [FILE]s and checks them - --derive-key Uses the key derivation mode, with the given - context string. Cannot be used with --keyed. - -h, --help Print help information - --keyed Uses the keyed mode. The secret key is read from standard - input, and it must be exactly 32 raw bytes. - -l, --length The number of output bytes, prior to hex - encoding [default: 32] - --no-mmap Disables memory mapping. Currently this also disables - multithreading. - --no-names Omits filenames in the output - --num-threads The maximum number of threads to use. By - default, this is the number of logical cores. - If this flag is omitted, or if its value is 0, - RAYON_NUM_THREADS is also respected. - --quiet Skips printing OK for each successfully verified file. - Must be used with --check. - --raw Writes raw output bytes to stdout, rather than hex. - --no-names is implied. In this case, only a single - input is allowed. - -V, --version Print version information +Usage: b3sum [OPTIONS] [FILE]... + +Arguments: + [FILE]... Files to hash, or checkfiles to check. When no file is given, + or when - is given, read standard input. + +Options: + -l, --length The number of output bytes, prior to hex + encoding [default: 32] + --num-threads The maximum number of threads to use. By + default, this is the number of logical cores. + If this flag is omitted, or if its value is 0, + RAYON_NUM_THREADS is also respected. + --keyed Uses the keyed mode. The secret key is read from standard + input, and it must be exactly 32 raw bytes. + --derive-key Uses the key derivation mode, with the given + context string. Cannot be used with --keyed. + --no-mmap Disables memory mapping. Currently this also disables + multithreading. + --no-names Omits filenames in the output + --raw Writes raw output bytes to stdout, rather than hex. + --no-names is implied. In this case, only a single + input is allowed. + -c, --check Reads BLAKE3 sums from the [FILE]s and checks them + --quiet Skips printing OK for each successfully verified file. + Must be used with --check. + -h, --help Print help information + -V, --version Print version information ``` See also [this document about how the `--check` flag diff --git a/b3sum/src/main.rs b/b3sum/src/main.rs index 3dc0cd20..6e0e2527 100644 --- a/b3sum/src/main.rs +++ b/b3sum/src/main.rs @@ -12,29 +12,29 @@ mod unit_tests; const NAME: &str = "b3sum"; -const DERIVE_KEY_ARG: &str = "derive-key"; +const DERIVE_KEY_ARG: &str = "derive_key"; const KEYED_ARG: &str = "keyed"; const LENGTH_ARG: &str = "length"; -const NO_NAMES_ARG: &str = "no-names"; +const NO_NAMES_ARG: &str = "no_names"; const RAW_ARG: &str = "raw"; const CHECK_ARG: &str = "check"; #[derive(Parser)] -#[clap(version)] +#[command(version)] struct Inner { /// Files to hash, or checkfiles to check. When no file is given, /// or when - is given, read standard input. - #[clap(value_parser, verbatim_doc_comment)] + #[arg(verbatim_doc_comment)] file: Vec, /// The number of output bytes, prior to hex /// encoding - #[clap( - long, + #[arg( + verbatim_doc_comment, short, - value_name("LEN"), + long, default_value_t = blake3::OUT_LEN as u64, - verbatim_doc_comment + value_name("LEN") )] length: u64, @@ -42,43 +42,43 @@ struct Inner { /// default, this is the number of logical cores. /// If this flag is omitted, or if its value is 0, /// RAYON_NUM_THREADS is also respected. - #[clap(long, value_name("NUM"), verbatim_doc_comment)] + #[arg(verbatim_doc_comment, long, value_name("NUM"))] num_threads: Option, /// Uses the keyed mode. The secret key is read from standard /// input, and it must be exactly 32 raw bytes. - #[clap(long, requires("file"), verbatim_doc_comment)] + #[arg(verbatim_doc_comment, long, requires("file"))] keyed: bool, /// Uses the key derivation mode, with the given /// context string. Cannot be used with --keyed. - #[clap( + #[arg( + verbatim_doc_comment, long, - conflicts_with(KEYED_ARG), value_name("CONTEXT"), - verbatim_doc_comment + conflicts_with(KEYED_ARG) )] derive_key: Option, /// Disables memory mapping. Currently this also disables /// multithreading. - #[clap(long, verbatim_doc_comment)] + #[arg(verbatim_doc_comment, long)] no_mmap: bool, /// Omits filenames in the output - #[clap(long)] + #[arg(long)] no_names: bool, /// Writes raw output bytes to stdout, rather than hex. /// --no-names is implied. In this case, only a single /// input is allowed. - #[clap(long, verbatim_doc_comment)] + #[arg(verbatim_doc_comment, long)] raw: bool, /// Reads BLAKE3 sums from the [FILE]s and checks them - #[clap( - long, + #[arg( short, + long, conflicts_with(DERIVE_KEY_ARG), conflicts_with(KEYED_ARG), conflicts_with(LENGTH_ARG), @@ -89,7 +89,7 @@ struct Inner { /// Skips printing OK for each successfully verified file. /// Must be used with --check. - #[clap(long, requires(CHECK_ARG), verbatim_doc_comment)] + #[arg(verbatim_doc_comment, long, requires(CHECK_ARG))] quiet: bool, } @@ -594,3 +594,13 @@ fn main() -> Result<()> { std::process::exit(if some_file_failed { 1 } else { 0 }); }) } + +#[cfg(test)] +mod test { + use clap::CommandFactory; + + #[test] + fn test_args() { + crate::Inner::command().debug_assert(); + } +} From cf9edb090bc9e79e239bc8fddb597edf95979d6a Mon Sep 17 00:00:00 2001 From: Shun Sakai Date: Mon, 3 Oct 2022 13:28:52 +0900 Subject: [PATCH 3/3] Split short summary from full help text --- b3sum/Cargo.lock | 101 ++++++++++++++++++++++++++++++++++++++++++++++ b3sum/Cargo.toml | 2 +- b3sum/README.md | 46 ++++++++++----------- b3sum/src/main.rs | 62 ++++++++++++++-------------- 4 files changed, 155 insertions(+), 56 deletions(-) diff --git a/b3sum/Cargo.lock b/b3sum/Cargo.lock index 793cc36f..2ec8f3f7 100644 --- a/b3sum/Cargo.lock +++ b/b3sum/Cargo.lock @@ -105,6 +105,7 @@ dependencies = [ "once_cell", "strsim", "termcolor", + "terminal_size", ] [[package]] @@ -219,6 +220,27 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "fastrand" version = "1.8.0" @@ -274,12 +296,24 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "io-lifetimes" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ea37f355c05dde75b84bba2d767906ad522e97cd9e2eef2be7a4ab7fb442c06" + [[package]] name = "libc" version = "0.2.133" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966" +[[package]] +name = "linux-raw-sys" +version = "0.0.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4d2456c373231a208ad294c33dc5bff30051eafd954cd4caae83a712b12854d" + [[package]] name = "memmap2" version = "0.5.7" @@ -414,6 +448,20 @@ dependencies = [ "winapi", ] +[[package]] +name = "rustix" +version = "0.35.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbb2fda4666def1433b1b05431ab402e42a1084285477222b72d6c564c417cef" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys", +] + [[package]] name = "scopeguard" version = "1.1.0" @@ -476,6 +524,16 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "terminal_size" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8440c860cf79def6164e4a0a983bcc2305d82419177a0e0c71930d049e3ac5a1" +dependencies = [ + "rustix", + "windows-sys", +] + [[package]] name = "typenum" version = "1.15.0" @@ -533,3 +591,46 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +dependencies = [ + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" + +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" diff --git a/b3sum/Cargo.toml b/b3sum/Cargo.toml index 13ddc706..9b43f0a9 100644 --- a/b3sum/Cargo.toml +++ b/b3sum/Cargo.toml @@ -16,7 +16,7 @@ pure = ["blake3/pure"] [dependencies] anyhow = "1.0.25" blake3 = { version = "1", path = "..", features = ["rayon"] } -clap = { version = "4.0.8", features = ["derive"] } +clap = { version = "4.0.8", features = ["derive", "wrap_help"] } hex = "0.4.0" memmap2 = "0.5.3" rayon = "1.2.1" diff --git a/b3sum/README.md b/b3sum/README.md index 86bfa1e1..af10361f 100644 --- a/b3sum/README.md +++ b/b3sum/README.md @@ -8,31 +8,31 @@ Coreutils tools like `b2sum` or `md5sum`. Usage: b3sum [OPTIONS] [FILE]... Arguments: - [FILE]... Files to hash, or checkfiles to check. When no file is given, - or when - is given, read standard input. + [FILE]... Files to hash, or checkfiles to check Options: - -l, --length The number of output bytes, prior to hex - encoding [default: 32] - --num-threads The maximum number of threads to use. By - default, this is the number of logical cores. - If this flag is omitted, or if its value is 0, - RAYON_NUM_THREADS is also respected. - --keyed Uses the keyed mode. The secret key is read from standard - input, and it must be exactly 32 raw bytes. - --derive-key Uses the key derivation mode, with the given - context string. Cannot be used with --keyed. - --no-mmap Disables memory mapping. Currently this also disables - multithreading. - --no-names Omits filenames in the output - --raw Writes raw output bytes to stdout, rather than hex. - --no-names is implied. In this case, only a single - input is allowed. - -c, --check Reads BLAKE3 sums from the [FILE]s and checks them - --quiet Skips printing OK for each successfully verified file. - Must be used with --check. - -h, --help Print help information - -V, --version Print version information + -l, --length + The number of output bytes, prior to hex encoding [default: 32] + --num-threads + The maximum number of threads to use + --keyed + Uses the keyed mode + --derive-key + Uses the key derivation mode, with the given context string + --no-mmap + Disables memory mapping + --no-names + Omits filenames in the output + --raw + Writes raw output bytes to stdout, rather than hex + -c, --check + Reads BLAKE3 sums from the [FILE]s and checks them + --quiet + Skips printing OK for each successfully verified file + -h, --help + Print help information (use `--help` for more detail) + -V, --version + Print version information ``` See also [this document about how the `--check` flag diff --git a/b3sum/src/main.rs b/b3sum/src/main.rs index 6e0e2527..dc0759b0 100644 --- a/b3sum/src/main.rs +++ b/b3sum/src/main.rs @@ -20,17 +20,15 @@ const RAW_ARG: &str = "raw"; const CHECK_ARG: &str = "check"; #[derive(Parser)] -#[command(version)] +#[command(version, max_term_width(80))] struct Inner { - /// Files to hash, or checkfiles to check. When no file is given, - /// or when - is given, read standard input. - #[arg(verbatim_doc_comment)] + /// Files to hash, or checkfiles to check. + /// + /// When no file is given, or when - is given, read standard input. file: Vec, - /// The number of output bytes, prior to hex - /// encoding + /// The number of output bytes, prior to hex encoding. #[arg( - verbatim_doc_comment, short, long, default_value_t = blake3::OUT_LEN as u64, @@ -38,44 +36,43 @@ struct Inner { )] length: u64, - /// The maximum number of threads to use. By - /// default, this is the number of logical cores. - /// If this flag is omitted, or if its value is 0, - /// RAYON_NUM_THREADS is also respected. - #[arg(verbatim_doc_comment, long, value_name("NUM"))] + /// The maximum number of threads to use. + /// + /// By default, this is the number of logical cores. If this flag is + /// omitted, or if its value is 0, RAYON_NUM_THREADS is also respected. + #[arg(long, value_name("NUM"))] num_threads: Option, - /// Uses the keyed mode. The secret key is read from standard - /// input, and it must be exactly 32 raw bytes. - #[arg(verbatim_doc_comment, long, requires("file"))] + /// Uses the keyed mode. + /// + /// The secret key is read from standard input, and it must be exactly 32 + /// raw bytes. + #[arg(long, requires("file"))] keyed: bool, - /// Uses the key derivation mode, with the given - /// context string. Cannot be used with --keyed. - #[arg( - verbatim_doc_comment, - long, - value_name("CONTEXT"), - conflicts_with(KEYED_ARG) - )] + /// Uses the key derivation mode, with the given context string. + /// + /// Cannot be used with --keyed. + #[arg(long, value_name("CONTEXT"), conflicts_with(KEYED_ARG))] derive_key: Option, - /// Disables memory mapping. Currently this also disables - /// multithreading. - #[arg(verbatim_doc_comment, long)] + /// Disables memory mapping. + /// + /// Currently this also disables multithreading. + #[arg(long)] no_mmap: bool, - /// Omits filenames in the output + /// Omits filenames in the output. #[arg(long)] no_names: bool, /// Writes raw output bytes to stdout, rather than hex. - /// --no-names is implied. In this case, only a single - /// input is allowed. - #[arg(verbatim_doc_comment, long)] + /// + /// --no-names is implied. In this case, only a single input is allowed. + #[arg(long)] raw: bool, - /// Reads BLAKE3 sums from the [FILE]s and checks them + /// Reads BLAKE3 sums from the [FILE]s and checks them. #[arg( short, long, @@ -88,8 +85,9 @@ struct Inner { check: bool, /// Skips printing OK for each successfully verified file. + /// /// Must be used with --check. - #[arg(verbatim_doc_comment, long, requires(CHECK_ARG))] + #[arg(long, requires(CHECK_ARG))] quiet: bool, }