diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index df9cb0293..913cf2769 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -469,37 +469,49 @@ pub fn uu_app<'a>() -> Command<'a> { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let matches = uu_app() - .after_help(&*format!( - "{}\n{}", - LONG_HELP, - backup_control::BACKUP_CONTROL_LONG_HELP - )) - .try_get_matches_from(args)?; + let after_help = &*format!( + "{}\n{}", + LONG_HELP, + backup_control::BACKUP_CONTROL_LONG_HELP + ); + let matches = uu_app().after_help(after_help).try_get_matches_from(args); - let options = Options::from_matches(&matches)?; + // The error is parsed here because we do not want version or help being printed to stderr. + if let Err(e) = matches { + let mut app = uu_app().after_help(after_help); - if options.overwrite == OverwriteMode::NoClobber && options.backup != BackupMode::NoBackup { - show_usage_error!("options --backup and --no-clobber are mutually exclusive"); - return Err(ExitCode(EXIT_ERR).into()); - } - - let paths: Vec = matches - .values_of(options::PATHS) - .map(|v| v.map(ToString::to_string).collect()) - .unwrap_or_default(); - - let (sources, target) = parse_path_args(&paths, &options)?; - - if let Err(error) = copy(&sources, &target, &options) { - match error { - // Error::NotAllFilesCopied is non-fatal, but the error - // code should still be EXIT_ERR as does GNU cp - Error::NotAllFilesCopied => {} - // Else we caught a fatal bubbled-up error, log it to stderr - _ => show_error!("{}", error), + match e.kind() { + clap::ErrorKind::DisplayHelp => { + app.print_help()?; + } + clap::ErrorKind::DisplayVersion => println!("{}", app.render_version()), + _ => return Err(Box::new(e)), }; - set_exit_code(EXIT_ERR); + } else if let Ok(matches) = matches { + let options = Options::from_matches(&matches)?; + + if options.overwrite == OverwriteMode::NoClobber && options.backup != BackupMode::NoBackup { + show_usage_error!("options --backup and --no-clobber are mutually exclusive"); + return Err(ExitCode(EXIT_ERR).into()); + } + + let paths: Vec = matches + .values_of(options::PATHS) + .map(|v| v.map(ToString::to_string).collect()) + .unwrap_or_default(); + + let (sources, target) = parse_path_args(&paths, &options)?; + + if let Err(error) = copy(&sources, &target, &options) { + match error { + // Error::NotAllFilesCopied is non-fatal, but the error + // code should still be EXIT_ERR as does GNU cp + Error::NotAllFilesCopied => {} + // Else we caught a fatal bubbled-up error, log it to stderr + _ => show_error!("{}", error), + }; + set_exit_code(EXIT_ERR); + } } Ok(()) diff --git a/src/uu/false/src/false.rs b/src/uu/false/src/false.rs index 687235f70..0ee6128b2 100644 --- a/src/uu/false/src/false.rs +++ b/src/uu/false/src/false.rs @@ -28,7 +28,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { if let Ok(matches) = command.try_get_matches_from_mut(args) { let error = if matches.index_of("help").is_some() { - command.print_long_help() + command.print_help() } else if matches.index_of("version").is_some() { writeln!(std::io::stdout(), "{}", command.render_version()) } else { diff --git a/src/uu/pr/src/pr.rs b/src/uu/pr/src/pr.rs index e18d29730..ca12f0be0 100644 --- a/src/uu/pr/src/pr.rs +++ b/src/uu/pr/src/pr.rs @@ -399,7 +399,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } if matches.is_present(options::HELP) { - command.print_long_help()?; + command.print_help()?; return Ok(()); } diff --git a/src/uu/sort/src/sort.rs b/src/uu/sort/src/sort.rs index 77d81c54c..141a7dd2c 100644 --- a/src/uu/sort/src/sort.rs +++ b/src/uu/sort/src/sort.rs @@ -1272,6 +1272,7 @@ pub fn uu_app<'a>() -> Command<'a> { Command::new(uucore::util_name()) .version(crate_version!()) .about(ABOUT) + .after_help(LONG_HELP_KEYS) .override_usage(format_usage(USAGE)) .infer_long_args(true) .arg( @@ -1421,7 +1422,6 @@ pub fn uu_app<'a>() -> Command<'a> { .short('k') .long(options::KEY) .help("sort by a key") - .long_help(LONG_HELP_KEYS) .multiple_occurrences(true) .number_of_values(1) .takes_value(true), @@ -1466,8 +1466,7 @@ pub fn uu_app<'a>() -> Command<'a> { .arg( Arg::new(options::COMPRESS_PROG) .long(options::COMPRESS_PROG) - .help("compress temporary files with PROG, decompress with PROG -d") - .long_help("PROG has to take input from stdin and output to stdout") + .help("compress temporary files with PROG, decompress with PROG -d; PROG has to take input from stdin and output to stdout") .value_name("PROG"), ) .arg( diff --git a/src/uu/true/src/true.rs b/src/uu/true/src/true.rs index 57c3d2af5..7742e9ee1 100644 --- a/src/uu/true/src/true.rs +++ b/src/uu/true/src/true.rs @@ -22,7 +22,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { if let Ok(matches) = command.try_get_matches_from_mut(args) { let error = if matches.index_of("help").is_some() { - command.print_long_help() + command.print_help() } else if matches.index_of("version").is_some() { writeln!(std::io::stdout(), "{}", command.render_version()) } else { diff --git a/src/uu/unexpand/src/unexpand.rs b/src/uu/unexpand/src/unexpand.rs index 910ff91d3..70a763f3b 100644 --- a/src/uu/unexpand/src/unexpand.rs +++ b/src/uu/unexpand/src/unexpand.rs @@ -127,7 +127,7 @@ pub fn uu_app<'a>() -> Command<'a> { Arg::new(options::TABS) .short('t') .long(options::TABS) - .long_help("use comma separated LIST of tab positions or have tabs N characters apart instead of 8 (enables -a)") + .help("use comma separated LIST of tab positions or have tabs N characters apart instead of 8 (enables -a)") .takes_value(true) ) .arg( diff --git a/util/build-gnu.sh b/util/build-gnu.sh index 0aad35ff1..6f0ec32f7 100755 --- a/util/build-gnu.sh +++ b/util/build-gnu.sh @@ -183,8 +183,6 @@ sed -i -e "s~ sed -n \"1s/'\\\/'/'OPT'/p\" < err >> pat || framework_failure_~ sed -i -e "s/rcexp=1$/rcexp=2\n case \"\$prg\" in chcon|runcon) return;; esac/" -e "s/rcexp=125 ;;/rcexp=2 ;;\ncp|truncate|pr) rcexp=1;;/" tests/misc/usage_vs_getopt.sh # GNU has option=[SUFFIX], clap is sed -i -e "s/cat opts/sed -i -e \"s| <.\*>$||g\" opts/" tests/misc/usage_vs_getopt.sh -# Strip empty lines for the diff - see https://github.com/uutils/coreutils/issues/3370 -sed -i -e "s~out 2>err1~out 2>err1\nsed '/^$/d' out > out\nsed '/^$/d' help > help~" tests/misc/usage_vs_getopt.sh # for some reasons, some stuff are duplicated, strip that sed -i -e "s/provoked error./provoked error\ncat pat |sort -u > pat/" tests/misc/usage_vs_getopt.sh