diff options
author | Ben Wiederhake <BenWiederhake.GitHub@gmx.de> | 2024-03-31 21:15:37 +0200 |
---|---|---|
committer | Ben Wiederhake <BenWiederhake.GitHub@gmx.de> | 2024-04-01 22:57:18 +0200 |
commit | 4a1bd78f482f31b183d07ff4d91cfbcd95ebd5cd (patch) | |
tree | fac68ee6c8409217b6352f2527f269f206788783 | |
parent | 8f791da213f826d130369a74466ae14199cf6efe (diff) |
ls: compute correct exit code on error
Note in particular that this seems to be the only tool where invalid
stringly-enum values cause a different exit code than invalid arguments.
-rw-r--r-- | src/uu/ls/src/ls.rs | 20 | ||||
-rw-r--r-- | tests/by-util/test_ls.rs | 53 |
2 files changed, 71 insertions, 2 deletions
diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index 333360f50..209745ade 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -3,7 +3,7 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. -// spell-checker:ignore (ToDO) somegroup nlink tabsize dired subdired dtype colorterm +// spell-checker:ignore (ToDO) somegroup nlink tabsize dired subdired dtype colorterm stringly use clap::{ builder::{NonEmptyStringValueParser, ValueParser}, @@ -36,6 +36,7 @@ use std::{ }; use term_grid::{Cell, Direction, Filling, Grid, GridOptions}; use unicode_width::UnicodeWidthStr; +use uucore::error::USimpleError; #[cfg(all(unix, not(any(target_os = "android", target_os = "macos"))))] use uucore::fsxattr::has_acl; #[cfg(any( @@ -1150,7 +1151,22 @@ impl Config { pub fn uumain(args: impl uucore::Args) -> UResult<()> { let command = uu_app(); - let matches = command.try_get_matches_from(args)?; + let matches = match command.try_get_matches_from(args) { + // clap successfully parsed the arguments: + Ok(matches) => matches, + // --help, --version, etc.: + Err(e) if e.exit_code() == 0 => { + return Err(e.into()); + } + // Errors in argument *values* cause exit code 1: + Err(e) if e.kind() == clap::error::ErrorKind::InvalidValue => { + return Err(USimpleError::new(1, e.to_string())); + } + // All other argument parsing errors cause exit code 2: + Err(e) => { + return Err(USimpleError::new(2, e.to_string())); + } + }; let config = Config::from(&matches)?; diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index 3f0154f7a..efe9e1056 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -45,11 +45,64 @@ const COMMA_ARGS: &[&str] = &["-m", "--format=commas", "--for=commas"]; const COLUMN_ARGS: &[&str] = &["-C", "--format=columns", "--for=columns"]; #[test] +fn test_invalid_flag() { + new_ucmd!() + .arg("--invalid-argument") + .fails() + .no_stdout() + .code_is(2); +} + +#[test] +fn test_invalid_value_returns_1() { + // Invalid values to flags *sometimes* result in error code 1: + for flag in [ + "--classify", + "--color", + "--format", + "--hyperlink", + "--indicator-style", + "--quoting-style", + "--sort", + "--time", + ] { + new_ucmd!() + .arg(&format!("{flag}=definitely_invalid_value")) + .fails() + .no_stdout() + .code_is(1); + } +} + +#[test] +fn test_invalid_value_returns_2() { + // Invalid values to flags *sometimes* result in error code 2: + for flag in ["--block-size", "--width", "--tab-size"] { + new_ucmd!() + .arg(&format!("{flag}=definitely_invalid_value")) + .fails() + .no_stdout() + .code_is(2); + } +} + +#[test] fn test_ls_ls() { new_ucmd!().succeeds(); } #[test] +fn test_ls_help() { + // Because we have to work around a lot of clap's error handling and + // modify the exit-code, this is actually non-trivial. + new_ucmd!() + .arg("--help") + .succeeds() + .stdout_contains("--version") + .no_stderr(); +} + +#[test] fn test_ls_i() { new_ucmd!().arg("-i").succeeds(); new_ucmd!().arg("-il").succeeds(); |