From 15315f820eadb055e4cc0ccba92024caeff36722 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 10 Aug 2025 09:38:53 +0200 Subject: [PATCH] Port factor for translation --- src/uucore/src/lib/mods/clap_localization.rs | 36 +++++++++++--------- tests/by-util/test_factor.rs | 13 +++++++ 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/src/uucore/src/lib/mods/clap_localization.rs b/src/uucore/src/lib/mods/clap_localization.rs index 89065019e..0aa3bbb46 100644 --- a/src/uucore/src/lib/mods/clap_localization.rs +++ b/src/uucore/src/lib/mods/clap_localization.rs @@ -124,11 +124,15 @@ pub fn handle_clap_error_with_exit_code(err: Error, util_name: &str, exit_code: _ => 1, }; - // UnknownArgument gets special handling for suggestions, but should still show simple help + // For UnknownArgument, we need to preserve clap's built-in tips (like using -- for values) + // while still allowing localization of the main error message + let rendered_str = err.render().to_string(); + let lines: Vec<&str> = rendered_str.lines().collect(); + if let Some(invalid_arg) = err.get(ContextKind::InvalidArg) { let arg_str = invalid_arg.to_string(); - // Get the uncolored words from common strings with fallbacks + // Get localized error word with fallback let error_word = { let translated = translate!("common-error"); if translated == "common-error" { @@ -137,18 +141,9 @@ pub fn handle_clap_error_with_exit_code(err: Error, util_name: &str, exit_code: translated } }; - let tip_word = { - let translated = translate!("common-tip"); - if translated == "common-tip" { - "tip".to_string() - } else { - translated - } - }; let colored_arg = maybe_colorize(&arg_str, Color::Yellow); let colored_error_word = maybe_colorize(&error_word, Color::Red); - let colored_tip_word = maybe_colorize(&tip_word, Color::Green); // Print main error message with fallback let error_msg = { @@ -169,9 +164,20 @@ pub fn handle_clap_error_with_exit_code(err: Error, util_name: &str, exit_code: eprintln!("{error_msg}"); eprintln!(); - // Show suggestion if available + // Look for clap's built-in tips in the original error rendering + // These usually start with " tip:" and contain useful information + for line in &lines { + if line.trim().starts_with("tip:") { + eprintln!("{}", line); + eprintln!(); + } + } + + // Show suggestion if available (different from tips) let suggestion = err.get(ContextKind::SuggestedArg); if let Some(suggested_arg) = suggestion { + let tip_word = translate!("common-tip"); + let colored_tip_word = maybe_colorize(&tip_word, Color::Green); let colored_suggestion = maybe_colorize(&suggested_arg.to_string(), Color::Green); let suggestion_msg = { @@ -193,9 +199,8 @@ pub fn handle_clap_error_with_exit_code(err: Error, util_name: &str, exit_code: eprintln!(); } - // Show usage information for unknown arguments but use simple --help format - // Try to get usage information from localization with fallback - let usage_key = format!("{}-usage", util_name); + // Show usage information for unknown arguments + let usage_key = format!("{util_name}-usage"); let usage_text = translate!(&usage_key); let formatted_usage = crate::format_usage(&usage_text); let usage_label = { @@ -208,7 +213,6 @@ pub fn handle_clap_error_with_exit_code(err: Error, util_name: &str, exit_code: }; eprintln!("{}: {}", usage_label, formatted_usage); eprintln!(); - // Use simple --help format for GNU test compatibility eprintln!("For more information, try '--help'."); std::process::exit(exit_code); diff --git a/tests/by-util/test_factor.rs b/tests/by-util/test_factor.rs index 2324da2a0..f06e7a616 100644 --- a/tests/by-util/test_factor.rs +++ b/tests/by-util/test_factor.rs @@ -28,6 +28,19 @@ fn test_invalid_arg() { new_ucmd!().arg("--definitely-invalid").fails_with_code(1); } +#[test] +fn test_invalid_negative_arg_shows_tip() { + // Test that factor shows a tip when given an invalid negative argument + // This replicates the GNU test issue where "-1" was interpreted as an invalid option + new_ucmd!() + .arg("-1") + .fails() + .code_is(1) + .stderr_contains("unexpected argument '-1' found") + .stderr_contains("tip: to pass '-1' as a value, use '-- -1'") + .stderr_contains("Usage: factor"); +} + #[test] fn test_valid_arg_exponents() { new_ucmd!().arg("-h").succeeds();