From 6a5dd1422b4ba0c042d0bb7a05d9611402637aeb Mon Sep 17 00:00:00 2001 From: n4n5 Date: Wed, 14 May 2025 22:59:00 -0500 Subject: [PATCH 01/19] fix docs hashsum --- Cargo.toml | 1 + src/bin/uudoc.rs | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 67c9e4f79..1aa356b67 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -545,6 +545,7 @@ path = "src/bin/coreutils.rs" name = "uudoc" path = "src/bin/uudoc.rs" required-features = ["uudoc"] +# cargo run --bin uudoc --features uudoc # The default release profile. It contains all optimizations. # With this profile (like in the standard release profile), diff --git a/src/bin/uudoc.rs b/src/bin/uudoc.rs index 6a215a4ad..66d1240ff 100644 --- a/src/bin/uudoc.rs +++ b/src/bin/uudoc.rs @@ -135,12 +135,22 @@ fn main() -> io::Result<()> { println!("Writing to utils"); for (&name, (_, command)) in utils { - if name == "[" { - continue; + let mut usage_name = name.to_string(); + match name { + "[" => { + continue; + } + "md5sum" | "sha1sum" | "sha224sum" | "sha256sum" | "sha384sum" | "sha512sum" + | "sha3sum" | "sha3-224sum" | "sha3-256sum" | "sha3-384sum" | "sha3-512sum" + | "shake128sum" | "shake256sum" | "b2sum" | "b3sum" => { + // These are all the same, so we can skip them. + usage_name = "hashsum".to_string(); + } + _ => {} } let p = format!("docs/src/utils/{name}.md"); - let markdown = File::open(format!("src/uu/{name}/{name}.md")) + let markdown = File::open(format!("src/uu/{usage_name}/{usage_name}.md")) .and_then(|mut f: File| { let mut s = String::new(); f.read_to_string(&mut s)?; From 20fa88185c78aa6f57cd2033bb800e3421cb3527 Mon Sep 17 00:00:00 2001 From: n4n5 Date: Wed, 14 May 2025 23:10:02 -0500 Subject: [PATCH 02/19] fix the test to [ --- src/bin/uudoc.rs | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/bin/uudoc.rs b/src/bin/uudoc.rs index 66d1240ff..f14dfbe6e 100644 --- a/src/bin/uudoc.rs +++ b/src/bin/uudoc.rs @@ -143,7 +143,7 @@ fn main() -> io::Result<()> { "md5sum" | "sha1sum" | "sha224sum" | "sha256sum" | "sha384sum" | "sha512sum" | "sha3sum" | "sha3-224sum" | "sha3-256sum" | "sha3-384sum" | "sha3-512sum" | "shake128sum" | "shake256sum" | "b2sum" | "b3sum" => { - // These are all the same, so we can skip them. + // These use the hashsum usage_name = "hashsum".to_string(); } _ => {} @@ -186,6 +186,25 @@ struct MDWriter<'a, 'b> { markdown: Option, } +fn fix_usage(name: &str, usage: String) -> String { + if name == "test" { + // replace to [ but not the first two line + return usage + .lines() + .enumerate() + .map(|(i, l)| { + if i > 1 { + l.replace("test", "[") + } else { + l.to_string() + } + }) + .collect::>() + .join("\n"); + } + return usage; +} + impl MDWriter<'_, '_> { /// # Errors /// Returns an error if the writer fails. @@ -250,7 +269,7 @@ impl MDWriter<'_, '_> { if let Some(markdown) = &self.markdown { let usage = uuhelp_parser::parse_usage(markdown); let usage = usage.replace("{}", self.name); - + let usage = fix_usage(self.name, usage); writeln!(self.w, "\n```")?; writeln!(self.w, "{usage}")?; writeln!(self.w, "```") From d4971cf34a15882f8288b8b92795dbdc560652b2 Mon Sep 17 00:00:00 2001 From: n4n5 Date: Wed, 14 May 2025 23:22:55 -0500 Subject: [PATCH 03/19] fix suggested by @rwdj --- src/bin/uudoc.rs | 35 ++++++++++++++++++++--------------- src/uu/hashsum/src/hashsum.rs | 7 ++++++- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/bin/uudoc.rs b/src/bin/uudoc.rs index f14dfbe6e..5bf8ba3a7 100644 --- a/src/bin/uudoc.rs +++ b/src/bin/uudoc.rs @@ -187,22 +187,27 @@ struct MDWriter<'a, 'b> { } fn fix_usage(name: &str, usage: String) -> String { - if name == "test" { - // replace to [ but not the first two line - return usage - .lines() - .enumerate() - .map(|(i, l)| { - if i > 1 { - l.replace("test", "[") - } else { - l.to_string() - } - }) - .collect::>() - .join("\n"); + match name { + "test" => { + // replace to [ but not the first two line + return usage + .lines() + .enumerate() + .map(|(i, l)| { + if i > 1 { + l.replace("test", "[") + } else { + l.to_string() + } + }) + .collect::>() + .join("\n"); + } + "md5sum" | "sha1sum" | "sha224sum" | "sha256sum" | "sha384sum" | "sha512sum" + | "sha3sum" | "sha3-224sum" | "sha3-256sum" | "sha3-384sum" | "sha3-512sum" + | "shake128sum" | "shake256sum" | "b2sum" | "b3sum" => usage.replace("-- ", ""), + _ => usage, } - return usage; } impl MDWriter<'_, '_> { diff --git a/src/uu/hashsum/src/hashsum.rs b/src/uu/hashsum/src/hashsum.rs index cd8ca912d..bdc75ec1e 100644 --- a/src/uu/hashsum/src/hashsum.rs +++ b/src/uu/hashsum/src/hashsum.rs @@ -493,7 +493,7 @@ pub fn uu_app_custom() -> Command { // hashsum is handled differently in build.rs, therefore this is not the same // as in other utilities. fn uu_app(binary_name: &str) -> (Command, bool) { - match binary_name { + let (mut command, is_hashsum_bin) = match binary_name { // These all support the same options. "md5sum" | "sha1sum" | "sha224sum" | "sha256sum" | "sha384sum" | "sha512sum" => { (uu_app_common(), false) @@ -511,7 +511,12 @@ fn uu_app(binary_name: &str) -> (Command, bool) { "b3sum" => (uu_app_b3sum(), false), // We're probably just being called as `hashsum`, so give them everything. _ => (uu_app_custom(), true), + }; + if binary_name != "hashsum" { + let correct_usage = format_usage(USAGE).replace("-- ", ""); + command = command.override_usage(correct_usage); } + (command, is_hashsum_bin) } #[allow(clippy::cognitive_complexity)] From 74d04fb7d9c4b5f2ced12cf9119ce3ad983466f9 Mon Sep 17 00:00:00 2001 From: n4n5 Date: Sun, 18 May 2025 22:58:34 -0500 Subject: [PATCH 04/19] remove super useful comment --- Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 1aa356b67..67c9e4f79 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -545,7 +545,6 @@ path = "src/bin/coreutils.rs" name = "uudoc" path = "src/bin/uudoc.rs" required-features = ["uudoc"] -# cargo run --bin uudoc --features uudoc # The default release profile. It contains all optimizations. # With this profile (like in the standard release profile), From 01c1d0ce93b57918e02403a6b661bc16a6a835d0 Mon Sep 17 00:00:00 2001 From: n4n5 Date: Sun, 25 May 2025 17:16:58 -0500 Subject: [PATCH 05/19] add uudoc tests --- tests/test_uudoc.rs | 116 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 tests/test_uudoc.rs diff --git a/tests/test_uudoc.rs b/tests/test_uudoc.rs new file mode 100644 index 000000000..14d147161 --- /dev/null +++ b/tests/test_uudoc.rs @@ -0,0 +1,116 @@ +//! Tests on the `uudoc` binary. +//! +//! To run the uudoc +//! ``` +//! cargo run --bin uudoc --features uudoc +//! ``` +//! +//! To run the tests +//! ``` +//! cargo test --features uudoc +//! ``` + +use std::env; +pub const TESTS_BINARY: &str = env!("CARGO_BIN_EXE_uudoc"); + +// Set the environment variable for any tests + +// Use the ctor attribute to run this function before any tests +#[ctor::ctor] +fn init() { + // No need for unsafe here + unsafe { + std::env::set_var("UUTESTS_BINARY_PATH", TESTS_BINARY); + } + // Print for debugging + eprintln!("Setting UUTESTS_BINARY_PATH={TESTS_BINARY}"); +} + +/// Run the `uudoc` command and return the output as a vector of strings. +/// # Errors +/// If the command fails to execute or if the output cannot be converted to UTF-8, an `io::Error` is returned. +fn run_write_doc() -> Vec { + use std::process::Command; + use uutests::util::TestScenario; + + let scenario = TestScenario::new(""); + let output = Command::new(&scenario.bin_path).output().unwrap(); + assert!( + output.status.success(), + "uudoc command failed: {}", + String::from_utf8_lossy(&output.stderr) + ); + + let res = String::from_utf8(output.stdout) + .unwrap() + .lines() + .map(String::from) + .filter(|line| line.starts_with("Wrote")) + .collect::>(); + res +} + +#[test] +fn uudoc_check_test() { + let pages = run_write_doc(); + println!("Pages written: {pages:?}\n"); + // assert wrote to the correct file + let path_test = pages.iter().find(|line| line.contains("test.md")).unwrap(); + let correct_path_test = path_test + .strip_prefix("Wrote to '") + .unwrap() + .strip_suffix("'") + .unwrap() + .to_string(); + assert_eq!(correct_path_test, "docs/src/utils/test.md"); + + // open the file + let content = std::fs::read_to_string(correct_path_test).unwrap(); + assert!(content.contains( + "``` +test EXPRESSION +test +[ EXPRESSION ] +[ ] +[ OPTION +``` +" + )); +} + +#[test] +fn uudoc_check_sums() { + let pages = run_write_doc(); + let sums = [ + "md5sum", + "sha1sum", + "sha224sum", + "sha256sum", + "sha384sum", + "sha512sum", + "sha3sum", + "sha3-224sum", + "sha3-256sum", + "sha3-384sum", + "sha3-512sum", + "shake128sum", + "shake256sum", + "b2sum", + "b3sum", + ]; + for one_sum in sums { + let path = pages.iter().find(|line| line.contains(one_sum)).unwrap(); + let correct_path = path + .strip_prefix("Wrote to '") + .unwrap() + .strip_suffix("'") + .unwrap() + .to_string(); + assert!(correct_path.contains("docs/src/utils/")); + assert!(correct_path.contains(one_sum)); + // open the file + let content = std::fs::read_to_string(correct_path).unwrap(); + let formatted = format!("```\n{} [OPTIONS]... [FILE]...\n```", one_sum); + assert!(content.contains(&formatted)); + } +} From a514be4d8d007b4b605e337b75fc8ef255c9ab94 Mon Sep 17 00:00:00 2001 From: n4n5 Date: Sun, 25 May 2025 17:22:18 -0500 Subject: [PATCH 06/19] cargo clippy --- tests/test_uudoc.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/test_uudoc.rs b/tests/test_uudoc.rs index 14d147161..98543c16d 100644 --- a/tests/test_uudoc.rs +++ b/tests/test_uudoc.rs @@ -41,13 +41,12 @@ fn run_write_doc() -> Vec { String::from_utf8_lossy(&output.stderr) ); - let res = String::from_utf8(output.stdout) + String::from_utf8(output.stdout) .unwrap() .lines() .map(String::from) .filter(|line| line.starts_with("Wrote")) - .collect::>(); - res + .collect::>() } #[test] From e5cfd4452247b1847cb6c338cbd802c1af9e4825 Mon Sep 17 00:00:00 2001 From: n4n5 Date: Sun, 25 May 2025 17:42:21 -0500 Subject: [PATCH 07/19] change test message --- tests/test_uudoc.rs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/tests/test_uudoc.rs b/tests/test_uudoc.rs index 98543c16d..f0be84b96 100644 --- a/tests/test_uudoc.rs +++ b/tests/test_uudoc.rs @@ -108,8 +108,24 @@ fn uudoc_check_sums() { assert!(correct_path.contains("docs/src/utils/")); assert!(correct_path.contains(one_sum)); // open the file - let content = std::fs::read_to_string(correct_path).unwrap(); + let content = std::fs::read_to_string(&correct_path); + let content = match content { + Ok(content) => content, + Err(e) => { + panic!( + "Failed to read file {}: {} from {:?}", + correct_path, + e, + env::current_dir() + ); + } + }; let formatted = format!("```\n{} [OPTIONS]... [FILE]...\n```", one_sum); - assert!(content.contains(&formatted)); + assert!( + content.contains(&formatted), + "Content of {} does not contain the expected format: {}", + correct_path, + formatted + ); } } From 2d4a8a778de2cf383679401c61888fa1b5d04dec Mon Sep 17 00:00:00 2001 From: n4n5 Date: Sun, 25 May 2025 17:52:22 -0500 Subject: [PATCH 08/19] make a function --- tests/test_uudoc.rs | 55 +++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/tests/test_uudoc.rs b/tests/test_uudoc.rs index f0be84b96..b1ab37b83 100644 --- a/tests/test_uudoc.rs +++ b/tests/test_uudoc.rs @@ -49,22 +49,37 @@ fn run_write_doc() -> Vec { .collect::>() } +fn get_doc_file_from_output(output: &str) -> (String, String) { + let correct_path_test = output + .strip_prefix("Wrote to '") + .unwrap() + .strip_suffix("'") + .unwrap() + .to_string(); + let content = std::fs::read_to_string(&correct_path_test); + let content = match content { + Ok(content) => content, + Err(e) => { + panic!( + "Failed to read file {}: {} from {:?}", + correct_path_test, + e, + env::current_dir() + ); + } + }; + (correct_path_test, content) +} + #[test] fn uudoc_check_test() { let pages = run_write_doc(); println!("Pages written: {pages:?}\n"); // assert wrote to the correct file let path_test = pages.iter().find(|line| line.contains("test.md")).unwrap(); - let correct_path_test = path_test - .strip_prefix("Wrote to '") - .unwrap() - .strip_suffix("'") - .unwrap() - .to_string(); - assert_eq!(correct_path_test, "docs/src/utils/test.md"); + let (_correct_path, content) = get_doc_file_from_output(path_test); // open the file - let content = std::fs::read_to_string(correct_path_test).unwrap(); assert!(content.contains( "``` test EXPRESSION @@ -98,28 +113,8 @@ fn uudoc_check_sums() { "b3sum", ]; for one_sum in sums { - let path = pages.iter().find(|line| line.contains(one_sum)).unwrap(); - let correct_path = path - .strip_prefix("Wrote to '") - .unwrap() - .strip_suffix("'") - .unwrap() - .to_string(); - assert!(correct_path.contains("docs/src/utils/")); - assert!(correct_path.contains(one_sum)); - // open the file - let content = std::fs::read_to_string(&correct_path); - let content = match content { - Ok(content) => content, - Err(e) => { - panic!( - "Failed to read file {}: {} from {:?}", - correct_path, - e, - env::current_dir() - ); - } - }; + let output_path = pages.iter().find(|line| line.contains(one_sum)).unwrap(); + let (correct_path, content) = get_doc_file_from_output(output_path); let formatted = format!("```\n{} [OPTIONS]... [FILE]...\n```", one_sum); assert!( content.contains(&formatted), From 13b80c45ccbaf8b44e4f93b16f653ca45bba0258 Mon Sep 17 00:00:00 2001 From: n4n5 Date: Sun, 25 May 2025 18:00:31 -0500 Subject: [PATCH 09/19] gate behind feature --- tests/test_uudoc.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_uudoc.rs b/tests/test_uudoc.rs index b1ab37b83..c5e00083f 100644 --- a/tests/test_uudoc.rs +++ b/tests/test_uudoc.rs @@ -9,6 +9,7 @@ //! ``` //! cargo test --features uudoc //! ``` +#![cfg(feature = "uudoc")] use std::env; pub const TESTS_BINARY: &str = env!("CARGO_BIN_EXE_uudoc"); From a2d6232b9a3ff8c9e2b8659f39dc36f0d586fdfd Mon Sep 17 00:00:00 2001 From: n4n5 Date: Sun, 9 Nov 2025 15:37:37 -0700 Subject: [PATCH 10/19] fix name variable --- src/bin/uudoc.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/bin/uudoc.rs b/src/bin/uudoc.rs index 8b0a9bb47..6ef07f609 100644 --- a/src/bin/uudoc.rs +++ b/src/bin/uudoc.rs @@ -290,7 +290,6 @@ fn main() -> io::Result<()> { println!("Writing to utils"); for (&name, (_, command)) in utils { - let mut usage_name = name.to_string(); let name = match name { "[" => { continue; @@ -299,9 +298,9 @@ fn main() -> io::Result<()> { | "sha3sum" | "sha3-224sum" | "sha3-256sum" | "sha3-384sum" | "sha3-512sum" | "shake128sum" | "shake256sum" | "b2sum" | "b3sum" => { // These use the hashsum - usage_name = "hashsum".to_string(); + "hashsum" } - _ => {} + n => n }; let p = format!("docs/src/utils/{name}.md"); From 262c638bd8764d6f0cb6e2919648fd604f7219e4 Mon Sep 17 00:00:00 2001 From: n4n5 Date: Sun, 9 Nov 2025 15:38:31 -0700 Subject: [PATCH 11/19] fmt --- src/bin/uudoc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/uudoc.rs b/src/bin/uudoc.rs index 6ef07f609..b9479cd62 100644 --- a/src/bin/uudoc.rs +++ b/src/bin/uudoc.rs @@ -300,7 +300,7 @@ fn main() -> io::Result<()> { // These use the hashsum "hashsum" } - n => n + n => n, }; let p = format!("docs/src/utils/{name}.md"); From 014f5c237e60e0acae112b061d342b05a39a3116 Mon Sep 17 00:00:00 2001 From: n4n5 Date: Sun, 9 Nov 2025 15:41:42 -0700 Subject: [PATCH 12/19] fix list --- src/bin/uudoc.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/bin/uudoc.rs b/src/bin/uudoc.rs index b9479cd62..38ac8dd52 100644 --- a/src/bin/uudoc.rs +++ b/src/bin/uudoc.rs @@ -294,9 +294,7 @@ fn main() -> io::Result<()> { "[" => { continue; } - "md5sum" | "sha1sum" | "sha224sum" | "sha256sum" | "sha384sum" | "sha512sum" - | "sha3sum" | "sha3-224sum" | "sha3-256sum" | "sha3-384sum" | "sha3-512sum" - | "shake128sum" | "shake256sum" | "b2sum" | "b3sum" => { + name if is_hashsum_family(name) => { // These use the hashsum "hashsum" } @@ -357,10 +355,18 @@ fn fix_usage(name: &str, usage: String) -> String { .collect::>() .join("\n"); } + "hashsum" => usage, + name if is_hashsum_family(name) => usage.replace("-- ", ""), + _ => usage, + } +} + +fn is_hashsum_family(name: &str) { + match name { "md5sum" | "sha1sum" | "sha224sum" | "sha256sum" | "sha384sum" | "sha512sum" | "sha3sum" | "sha3-224sum" | "sha3-256sum" | "sha3-384sum" | "sha3-512sum" - | "shake128sum" | "shake256sum" | "b2sum" | "b3sum" => usage.replace("-- ", ""), - _ => usage, + | "shake128sum" | "shake256sum" | "b2sum" | "b3sum" => true, + _ => false, } } From f406d672ced8841f96cf1d4b6e8c640ce85a60a6 Mon Sep 17 00:00:00 2001 From: n4n5 Date: Sun, 9 Nov 2025 15:42:43 -0700 Subject: [PATCH 13/19] return bool --- src/bin/uudoc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/uudoc.rs b/src/bin/uudoc.rs index 38ac8dd52..4e252dccf 100644 --- a/src/bin/uudoc.rs +++ b/src/bin/uudoc.rs @@ -361,7 +361,7 @@ fn fix_usage(name: &str, usage: String) -> String { } } -fn is_hashsum_family(name: &str) { +fn is_hashsum_family(name: &str) -> bool { match name { "md5sum" | "sha1sum" | "sha224sum" | "sha256sum" | "sha384sum" | "sha512sum" | "sha3sum" | "sha3-224sum" | "sha3-256sum" | "sha3-384sum" | "sha3-512sum" From bf9e9880b390411821c862f1606e12db260fa1cc Mon Sep 17 00:00:00 2001 From: n4n5 Date: Sun, 9 Nov 2025 16:02:36 -0700 Subject: [PATCH 14/19] fix: broken manpage displaying uudoc --- src/bin/uudoc.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/bin/uudoc.rs b/src/bin/uudoc.rs index 4e252dccf..de6f1f4c6 100644 --- a/src/bin/uudoc.rs +++ b/src/bin/uudoc.rs @@ -83,6 +83,8 @@ fn gen_manpage( } else { validation::setup_localization_or_exit(utility); let mut cmd = util_map.get(utility).unwrap().1(); + cmd.set_bin_name(utility.clone()); + let mut cmd = cmd.display_name(utility); if let Some(zip) = tldr { if let Ok(examples) = write_zip_examples(zip, utility, false) { cmd = cmd.after_help(examples); From 0f10e216cf99ea801055d3ae5f1ce44aedcb0090 Mon Sep 17 00:00:00 2001 From: n4n5 Date: Sun, 9 Nov 2025 17:08:10 -0700 Subject: [PATCH 15/19] fix: tests --- build.rs | 4 ++ src/bin/uudoc.rs | 97 ++++++++++++++++++++++++----------- src/uu/test/locales/en-US.ftl | 2 +- src/uu/test/locales/fr-FR.ftl | 2 +- tests/test_uudoc.rs | 30 +++++------ 5 files changed, 87 insertions(+), 48 deletions(-) diff --git a/build.rs b/build.rs index 9b35eac5e..1d8926234 100644 --- a/build.rs +++ b/build.rs @@ -85,7 +85,11 @@ pub fn main() { phf_map.entry("sha256sum", map_value.clone()); phf_map.entry("sha384sum", map_value.clone()); phf_map.entry("sha512sum", map_value.clone()); + phf_map.entry("sha3sum", map_value.clone()); + phf_map.entry("shake128sum", map_value.clone()); + phf_map.entry("shake256sum", map_value.clone()); phf_map.entry("b2sum", map_value.clone()); + phf_map.entry("b3sum", map_value.clone()); } _ => { phf_map.entry(krate, map_value.clone()); diff --git a/src/bin/uudoc.rs b/src/bin/uudoc.rs index de6f1f4c6..ab0043331 100644 --- a/src/bin/uudoc.rs +++ b/src/bin/uudoc.rs @@ -291,20 +291,27 @@ fn main() -> io::Result<()> { } println!("Writing to utils"); + let hashsum_cmd = utils + .iter() + .find(|n| *n.0 == "hashsum") + .unwrap() + .clone() + .1 + .1; for (&name, (_, command)) in utils { - let name = match name { + let (utils_name, usage_name, command) = match name { "[" => { continue; } name if is_hashsum_family(name) => { // These use the hashsum - "hashsum" + ("hashsum", name, &hashsum_cmd) } - n => n, + n => (n, n, command), }; - let p = format!("docs/src/utils/{name}.md"); + let p = format!("docs/src/utils/{usage_name}.md"); - let fluent = File::open(format!("src/uu/{name}/locales/en-US.ftl")) + let fluent = File::open(format!("src/uu/{utils_name}/locales/en-US.ftl")) .and_then(|mut f: File| { let mut s = String::new(); f.read_to_string(&mut s)?; @@ -316,35 +323,27 @@ fn main() -> io::Result<()> { MDWriter { w: Box::new(f), command: command(), - name, + name: usage_name, tldr_zip: &mut tldr_zip, utils_per_platform: &utils_per_platform, fluent, + fluent_key: utils_name.to_string(), } .markdown()?; println!("Wrote to '{p}'"); } else { println!("Error writing to {p}"); } - writeln!(summary, "* [{name}](utils/{name}.md)")?; + writeln!(summary, "* [{usage_name}](utils/{usage_name}.md)")?; } Ok(()) } -struct MDWriter<'a, 'b> { - w: Box, - command: Command, - name: &'a str, - tldr_zip: &'b mut Option>, - utils_per_platform: &'b HashMap<&'b str, Vec>, - fluent: Option, -} - fn fix_usage(name: &str, usage: String) -> String { match name { "test" => { // replace to [ but not the first two line - return usage + usage .lines() .enumerate() .map(|(i, l)| { @@ -355,21 +354,45 @@ fn fix_usage(name: &str, usage: String) -> String { } }) .collect::>() - .join("\n"); + .join("\n") } "hashsum" => usage, - name if is_hashsum_family(name) => usage.replace("-- ", ""), + name if is_hashsum_family(name) => { + usage.replace("-- ", "").replace("hashsum", name) + } _ => usage, } } fn is_hashsum_family(name: &str) -> bool { - match name { - "md5sum" | "sha1sum" | "sha224sum" | "sha256sum" | "sha384sum" | "sha512sum" - | "sha3sum" | "sha3-224sum" | "sha3-256sum" | "sha3-384sum" | "sha3-512sum" - | "shake128sum" | "shake256sum" | "b2sum" | "b3sum" => true, - _ => false, - } + matches!( + name, + "md5sum" + | "sha1sum" + | "sha224sum" + | "sha256sum" + | "sha384sum" + | "sha512sum" + | "sha3sum" + | "sha3-224sum" + | "sha3-256sum" + | "sha3-384sum" + | "sha3-512sum" + | "shake128sum" + | "shake256sum" + | "b2sum" + | "b3sum" + ) +} + +struct MDWriter<'a, 'b> { + w: Box, + command: Command, + name: &'a str, + tldr_zip: &'b mut Option>, + utils_per_platform: &'b HashMap<&'b str, Vec>, + fluent: Option, + fluent_key: String, } impl MDWriter<'_, '_> { @@ -389,7 +412,6 @@ impl MDWriter<'_, '_> { fn extract_fluent_value(&self, key: &str) -> Option { let content = self.fluent.as_ref()?; let resource = parser::parse(content.clone()).ok()?; - for entry in resource.body { if let Entry::Message(Message { id, @@ -400,8 +422,19 @@ impl MDWriter<'_, '_> { if id.name == key { // Simple text extraction - just concatenate text elements let mut result = String::new(); + use fluent_syntax::ast::{ + Expression, InlineExpression, + PatternElement::{Placeable, TextElement}, + }; for element in elements { - if let fluent_syntax::ast::PatternElement::TextElement { value } = element { + if let TextElement { ref value } = element { + result.push_str(&value); + } + if let Placeable { + expression: + Expression::Inline(InlineExpression::StringLiteral { ref value }), + } = element + { result.push_str(&value); } } @@ -460,7 +493,7 @@ impl MDWriter<'_, '_> { /// # Errors /// Returns an error if the writer fails. fn usage(&mut self) -> io::Result<()> { - if let Some(usage) = self.extract_fluent_value(&format!("{}-usage", self.name)) { + if let Some(usage) = self.extract_fluent_value(&format!("{}-usage", self.fluent_key)) { let usage = fix_usage(self.name, usage); writeln!(self.w, "\n```")?; writeln!(self.w, "{usage}")?; @@ -473,7 +506,7 @@ impl MDWriter<'_, '_> { /// # Errors /// Returns an error if the writer fails. fn about(&mut self) -> io::Result<()> { - if let Some(about) = self.extract_fluent_value(&format!("{}-about", self.name)) { + if let Some(about) = self.extract_fluent_value(&format!("{}-about", self.fluent_key)) { writeln!(self.w, "{about}") } else { Ok(()) @@ -483,7 +516,9 @@ impl MDWriter<'_, '_> { /// # Errors /// Returns an error if the writer fails. fn after_help(&mut self) -> io::Result<()> { - if let Some(after_help) = self.extract_fluent_value(&format!("{}-after-help", self.name)) { + if let Some(after_help) = + self.extract_fluent_value(&format!("{}-after-help", self.fluent_key)) + { writeln!(self.w, "\n\n{after_help}") } else { Ok(()) @@ -554,7 +589,7 @@ impl MDWriter<'_, '_> { writeln!(self.w, "")?; let help_text = arg.get_help().unwrap_or_default().to_string(); // Try to resolve Fluent key if it looks like one, otherwise use as-is - let resolved_help = if help_text.starts_with(&format!("{}-help-", self.name)) { + let resolved_help = if help_text.starts_with(&format!("{}-help-", self.fluent_key)) { self.extract_fluent_value(&help_text).unwrap_or(help_text) } else { help_text diff --git a/src/uu/test/locales/en-US.ftl b/src/uu/test/locales/en-US.ftl index 86871637f..66d7c0a83 100644 --- a/src/uu/test/locales/en-US.ftl +++ b/src/uu/test/locales/en-US.ftl @@ -3,7 +3,7 @@ test-usage = test EXPRESSION test {"[ EXPRESSION ]"} {"[ ]"} - {"[ OPTION ]"} + {"[ OPTION"} test-after-help = Exit with the status determined by EXPRESSION. An omitted EXPRESSION defaults to false. diff --git a/src/uu/test/locales/fr-FR.ftl b/src/uu/test/locales/fr-FR.ftl index 78cae9b44..36729d3f7 100644 --- a/src/uu/test/locales/fr-FR.ftl +++ b/src/uu/test/locales/fr-FR.ftl @@ -3,7 +3,7 @@ test-usage = test EXPRESSION test {"[ EXPRESSION ]"} {"[ ]"} - {"[ OPTION ]"} + {"[ OPTION"} test-after-help = Quitter avec le statut déterminé par EXPRESSION. Une EXPRESSION omise vaut false par défaut. diff --git a/tests/test_uudoc.rs b/tests/test_uudoc.rs index c5e00083f..2c4a2a311 100644 --- a/tests/test_uudoc.rs +++ b/tests/test_uudoc.rs @@ -75,22 +75,25 @@ fn get_doc_file_from_output(output: &str) -> (String, String) { #[test] fn uudoc_check_test() { let pages = run_write_doc(); - println!("Pages written: {pages:?}\n"); // assert wrote to the correct file let path_test = pages.iter().find(|line| line.contains("test.md")).unwrap(); - let (_correct_path, content) = get_doc_file_from_output(path_test); + let (correct_path, content) = get_doc_file_from_output(path_test); // open the file - assert!(content.contains( - "``` + assert!( + content.contains( + "``` test EXPRESSION test [ EXPRESSION ] [ ] [ OPTION ``` -" - )); +", + ), + "{} does not contains the required text", + correct_path + ); } #[test] @@ -104,24 +107,21 @@ fn uudoc_check_sums() { "sha384sum", "sha512sum", "sha3sum", - "sha3-224sum", - "sha3-256sum", - "sha3-384sum", - "sha3-512sum", "shake128sum", "shake256sum", "b2sum", "b3sum", ]; for one_sum in sums { - let output_path = pages.iter().find(|line| line.contains(one_sum)).unwrap(); + let output_path = pages + .iter() + .find(|one_line| one_line.contains(one_sum)) + .expect(&format!("{one_sum} was not generated in {pages:?}")); let (correct_path, content) = get_doc_file_from_output(output_path); - let formatted = format!("```\n{} [OPTIONS]... [FILE]...\n```", one_sum); + let formatted = format!("```\n{one_sum} [OPTIONS]... [FILE]...\n```"); assert!( content.contains(&formatted), - "Content of {} does not contain the expected format: {}", - correct_path, - formatted + "Content of {correct_path} does not contain the expected format: {formatted}", ); } } From ce44b459df0cde442bd514ed59e995c207ded447 Mon Sep 17 00:00:00 2001 From: n4n5 Date: Sun, 9 Nov 2025 17:15:36 -0700 Subject: [PATCH 16/19] clippy --- src/bin/uudoc.rs | 12 +++--------- tests/test_uudoc.rs | 5 ++--- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/bin/uudoc.rs b/src/bin/uudoc.rs index ab0043331..e506b196e 100644 --- a/src/bin/uudoc.rs +++ b/src/bin/uudoc.rs @@ -291,13 +291,7 @@ fn main() -> io::Result<()> { } println!("Writing to utils"); - let hashsum_cmd = utils - .iter() - .find(|n| *n.0 == "hashsum") - .unwrap() - .clone() - .1 - .1; + let hashsum_cmd = (*utils.iter().find(|n| *n.0 == "hashsum").unwrap()).1.1; for (&name, (_, command)) in utils { let (utils_name, usage_name, command) = match name { "[" => { @@ -428,14 +422,14 @@ impl MDWriter<'_, '_> { }; for element in elements { if let TextElement { ref value } = element { - result.push_str(&value); + result.push_str(value); } if let Placeable { expression: Expression::Inline(InlineExpression::StringLiteral { ref value }), } = element { - result.push_str(&value); + result.push_str(value); } } return Some(result); diff --git a/tests/test_uudoc.rs b/tests/test_uudoc.rs index 2c4a2a311..1023697ef 100644 --- a/tests/test_uudoc.rs +++ b/tests/test_uudoc.rs @@ -91,8 +91,7 @@ test ``` ", ), - "{} does not contains the required text", - correct_path + "{correct_path} does not contains the required text" ); } @@ -116,7 +115,7 @@ fn uudoc_check_sums() { let output_path = pages .iter() .find(|one_line| one_line.contains(one_sum)) - .expect(&format!("{one_sum} was not generated in {pages:?}")); + .unwrap(); let (correct_path, content) = get_doc_file_from_output(output_path); let formatted = format!("```\n{one_sum} [OPTIONS]... [FILE]...\n```"); assert!( From 78a98c73c8bea02c0cdebcce30be1fd907c66c64 Mon Sep 17 00:00:00 2001 From: n4n5 Date: Sun, 9 Nov 2025 17:19:18 -0700 Subject: [PATCH 17/19] dumb clippy double fmt --- src/bin/uudoc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/uudoc.rs b/src/bin/uudoc.rs index e506b196e..cadc70472 100644 --- a/src/bin/uudoc.rs +++ b/src/bin/uudoc.rs @@ -291,7 +291,7 @@ fn main() -> io::Result<()> { } println!("Writing to utils"); - let hashsum_cmd = (*utils.iter().find(|n| *n.0 == "hashsum").unwrap()).1.1; + let hashsum_cmd = utils.iter().find(|n| *n.0 == "hashsum").unwrap().1.1; for (&name, (_, command)) in utils { let (utils_name, usage_name, command) = match name { "[" => { From f8d8a73d725e2f48556f73a2ccd1edbba162ac02 Mon Sep 17 00:00:00 2001 From: n4n5 Date: Wed, 19 Nov 2025 18:21:13 +0100 Subject: [PATCH 18/19] Update build.rs --- build.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/build.rs b/build.rs index 1d8926234..9b35eac5e 100644 --- a/build.rs +++ b/build.rs @@ -85,11 +85,7 @@ pub fn main() { phf_map.entry("sha256sum", map_value.clone()); phf_map.entry("sha384sum", map_value.clone()); phf_map.entry("sha512sum", map_value.clone()); - phf_map.entry("sha3sum", map_value.clone()); - phf_map.entry("shake128sum", map_value.clone()); - phf_map.entry("shake256sum", map_value.clone()); phf_map.entry("b2sum", map_value.clone()); - phf_map.entry("b3sum", map_value.clone()); } _ => { phf_map.entry(krate, map_value.clone()); From b246f101cddb77b937d7c21f013263be5f9c61ed Mon Sep 17 00:00:00 2001 From: n4n5 Date: Wed, 19 Nov 2025 18:21:46 +0100 Subject: [PATCH 19/19] Update test_uudoc.rs --- tests/test_uudoc.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/test_uudoc.rs b/tests/test_uudoc.rs index 1023697ef..d8e80f7a1 100644 --- a/tests/test_uudoc.rs +++ b/tests/test_uudoc.rs @@ -105,11 +105,7 @@ fn uudoc_check_sums() { "sha256sum", "sha384sum", "sha512sum", - "sha3sum", - "shake128sum", - "shake256sum", "b2sum", - "b3sum", ]; for one_sum in sums { let output_path = pages