From c6cff20f1886a092e37a96683ec88a8e94062b29 Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Thu, 29 Sep 2022 19:59:27 +0200 Subject: [PATCH] ls: update to clap 4 --- src/uu/ls/Cargo.toml | 2 +- src/uu/ls/src/ls.rs | 276 ++++++++++++++++++++++----------------- tests/by-util/test_ls.rs | 2 + 3 files changed, 161 insertions(+), 119 deletions(-) diff --git a/src/uu/ls/Cargo.toml b/src/uu/ls/Cargo.toml index 922affea5..6160040ca 100644 --- a/src/uu/ls/Cargo.toml +++ b/src/uu/ls/Cargo.toml @@ -16,7 +16,7 @@ path = "src/ls.rs" [dependencies] chrono = { version="^0.4.19", default-features=false, features=["std", "alloc", "clock"]} -clap = { version = "3.2", features = ["wrap_help", "cargo", "env"] } +clap = { version = "4.0", features = ["wrap_help", "cargo", "env"] } unicode-width = "0.1.8" number_prefix = "0.4" term_grid = "0.1.5" diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index 962ce164b..a30cda01d 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -12,7 +12,7 @@ extern crate uucore; use clap::{ builder::{NonEmptyStringValueParser, ValueParser}, - crate_version, Arg, Command, + crate_version, Arg, ArgAction, Command, }; use glob::{MatchOptions, Pattern}; use lscolors::LsColors; @@ -268,7 +268,7 @@ impl Display for LsError { } } -#[derive(PartialEq, Eq)] +#[derive(PartialEq, Eq, Debug)] pub enum Format { Columns, Long, @@ -328,7 +328,7 @@ fn parse_time_style(options: &clap::ArgMatches) -> Result { if let Some(field) = options.get_one::(options::TIME_STYLE) { //If both FULL_TIME and TIME_STYLE are present //The one added last is dominant - if options.contains_id(options::FULL_TIME) + if options.get_flag(options::FULL_TIME) && options.indices_of(options::FULL_TIME).unwrap().last() > options.indices_of(options::TIME_STYLE).unwrap().last() { @@ -348,7 +348,7 @@ fn parse_time_style(options: &clap::ArgMatches) -> Result { }, } } - } else if options.contains_id(options::FULL_TIME) { + } else if options.get_flag(options::FULL_TIME) { Ok(TimeStyle::FullIso) } else { Ok(TimeStyle::Locale) @@ -425,7 +425,7 @@ struct PaddingCollection { impl Config { #[allow(clippy::cognitive_complexity)] pub fn from(options: &clap::ArgMatches) -> UResult { - let context = options.contains_id(options::CONTEXT); + let context = options.get_flag(options::CONTEXT); let (mut format, opt) = if let Some(format_) = options.get_one::(options::FORMAT) { ( match format_.as_str() { @@ -439,13 +439,13 @@ impl Config { }, Some(options::FORMAT), ) - } else if options.contains_id(options::format::LONG) { + } else if options.get_flag(options::format::LONG) { (Format::Long, Some(options::format::LONG)) - } else if options.contains_id(options::format::ACROSS) { + } else if options.get_flag(options::format::ACROSS) { (Format::Across, Some(options::format::ACROSS)) - } else if options.contains_id(options::format::COMMAS) { + } else if options.get_flag(options::format::COMMAS) { (Format::Commas, Some(options::format::COMMAS)) - } else if options.contains_id(options::format::COLUMNS) { + } else if options.get_flag(options::format::COLUMNS) { (Format::Columns, Some(options::format::COLUMNS)) } else if atty::is(atty::Stream::Stdout) { (Format::Columns, None) @@ -479,21 +479,30 @@ impl Config { options::FULL_TIME, ] .iter() - .flat_map(|opt| options.indices_of(opt)) + .flat_map(|opt| { + if options.value_source(opt) == Some(clap::parser::ValueSource::CommandLine) { + options.indices_of(opt) + } else { + None + } + }) .flatten() .any(|i| i >= idx) { format = Format::Long; } else if let Some(mut indices) = options.indices_of(options::format::ONE_LINE) { - if indices.any(|i| i > idx) { + if options.value_source(options::format::ONE_LINE) + == Some(clap::parser::ValueSource::CommandLine) + && indices.any(|i| i > idx) + { format = Format::OneLine; } } } - let files = if options.contains_id(options::files::ALL) { + let files = if options.get_flag(options::files::ALL) { Files::All - } else if options.contains_id(options::files::ALMOST_ALL) { + } else if options.get_flag(options::files::ALMOST_ALL) { Files::AlmostAll } else { Files::Normal @@ -510,15 +519,15 @@ impl Config { // below should never happen as clap already restricts the values. _ => unreachable!("Invalid field for --sort"), } - } else if options.contains_id(options::sort::TIME) { + } else if options.get_flag(options::sort::TIME) { Sort::Time - } else if options.contains_id(options::sort::SIZE) { + } else if options.get_flag(options::sort::SIZE) { Sort::Size - } else if options.contains_id(options::sort::NONE) { + } else if options.get_flag(options::sort::NONE) { Sort::None - } else if options.contains_id(options::sort::VERSION) { + } else if options.get_flag(options::sort::VERSION) { Sort::Version - } else if options.contains_id(options::sort::EXTENSION) { + } else if options.get_flag(options::sort::EXTENSION) { Sort::Extension } else { Sort::Name @@ -532,9 +541,9 @@ impl Config { // below should never happen as clap already restricts the values. _ => unreachable!("Invalid field for --time"), } - } else if options.contains_id(options::time::ACCESS) { + } else if options.get_flag(options::time::ACCESS) { Time::Access - } else if options.contains_id(options::time::CHANGE) { + } else if options.get_flag(options::time::CHANGE) { Time::Change } else { Time::Modification @@ -555,14 +564,14 @@ impl Config { .get_one::(options::size::BLOCK_SIZE) .unwrap() .eq("si") - || options.contains_id(options::size::SI); + || options.get_flag(options::size::SI); let opt_hr = (cmd_line_bs.is_some() && options .get_one::(options::size::BLOCK_SIZE) .unwrap() .eq("human-readable")) - || options.contains_id(options::size::HUMAN_READABLE); - let opt_kb = options.contains_id(options::size::KIBIBYTES); + || options.get_flag(options::size::HUMAN_READABLE); + let opt_kb = options.get_flag(options::size::KIBIBYTES); let bs_env_var = std::env::var_os("BLOCK_SIZE"); let ls_bs_env_var = std::env::var_os("LS_BLOCK_SIZE"); @@ -611,12 +620,12 @@ impl Config { }; let long = { - let author = options.contains_id(options::AUTHOR); - let group = !options.contains_id(options::NO_GROUP) - && !options.contains_id(options::format::LONG_NO_GROUP); - let owner = !options.contains_id(options::format::LONG_NO_OWNER); + let author = options.get_flag(options::AUTHOR); + let group = !options.get_flag(options::NO_GROUP) + && !options.get_flag(options::format::LONG_NO_GROUP); + let owner = !options.get_flag(options::format::LONG_NO_OWNER); #[cfg(unix)] - let numeric_uid_gid = options.contains_id(options::format::LONG_NUMERIC_UID_GID); + let numeric_uid_gid = options.get_flag(options::format::LONG_NUMERIC_UID_GID); LongFormat { author, group, @@ -660,9 +669,9 @@ impl Config { }; #[allow(clippy::needless_bool)] - let mut show_control = if options.contains_id(options::HIDE_CONTROL_CHARS) { + let mut show_control = if options.get_flag(options::HIDE_CONTROL_CHARS) { false - } else if options.contains_id(options::SHOW_CONTROL_CHARS) { + } else if options.get_flag(options::SHOW_CONTROL_CHARS) { true } else { !atty::is(atty::Stream::Stdout) @@ -703,13 +712,13 @@ impl Config { }, _ => unreachable!("Should have been caught by Clap"), } - } else if options.contains_id(options::quoting::LITERAL) { + } else if options.get_flag(options::quoting::LITERAL) { QuotingStyle::Literal { show_control } - } else if options.contains_id(options::quoting::ESCAPE) { + } else if options.get_flag(options::quoting::ESCAPE) { QuotingStyle::C { quotes: quoting_style::Quotes::None, } - } else if options.contains_id(options::quoting::C) { + } else if options.get_flag(options::quoting::C) { QuotingStyle::C { quotes: quoting_style::Quotes::Double, } @@ -745,9 +754,9 @@ impl Config { } &_ => IndicatorStyle::None, } - } else if options.contains_id(options::indicator_style::SLASH) { + } else if options.get_flag(options::indicator_style::SLASH) { IndicatorStyle::Slash - } else if options.contains_id(options::indicator_style::FILE_TYPE) { + } else if options.get_flag(options::indicator_style::FILE_TYPE) { IndicatorStyle::FileType } else { IndicatorStyle::None @@ -756,7 +765,7 @@ impl Config { let mut ignore_patterns: Vec = Vec::new(); - if options.contains_id(options::IGNORE_BACKUPS) { + if options.get_flag(options::IGNORE_BACKUPS) { ignore_patterns.push(Pattern::new("*~").unwrap()); ignore_patterns.push(Pattern::new(".*~").unwrap()); } @@ -815,7 +824,13 @@ impl Config { options::quoting::ESCAPE, options::quoting::LITERAL, ]; - let get_last = |flag: &str| -> usize { options.index_of(flag).unwrap_or(0) }; + let get_last = |flag: &str| -> usize { + if options.value_source(flag) == Some(clap::parser::ValueSource::CommandLine) { + options.index_of(flag).unwrap_or(0) + } else { + 0 + } + }; if get_last(options::ZERO) > zero_formats_opts .into_iter() @@ -863,13 +878,13 @@ impl Config { None }; - let dereference = if options.contains_id(options::dereference::ALL) { + let dereference = if options.get_flag(options::dereference::ALL) { Dereference::All - } else if options.contains_id(options::dereference::ARGS) { + } else if options.get_flag(options::dereference::ARGS) { Dereference::Args - } else if options.contains_id(options::dereference::DIR_ARGS) { + } else if options.get_flag(options::dereference::DIR_ARGS) { Dereference::DirArgs - } else if options.contains_id(options::DIRECTORY) + } else if options.get_flag(options::DIRECTORY) || indicator_style == IndicatorStyle::Classify || format == Format::Long { @@ -882,18 +897,18 @@ impl Config { format, files, sort, - recursive: options.contains_id(options::RECURSIVE), - reverse: options.contains_id(options::REVERSE), + recursive: options.get_flag(options::RECURSIVE), + reverse: options.get_flag(options::REVERSE), dereference, ignore_patterns, size_format, - directory: options.contains_id(options::DIRECTORY), + directory: options.get_flag(options::DIRECTORY), time, color, #[cfg(unix)] - inode: options.contains_id(options::INODE), + inode: options.get_flag(options::INODE), long, - alloc_size: options.contains_id(options::size::ALLOCATION_SIZE), + alloc_size: options.get_flag(options::size::ALLOCATION_SIZE), block_size, width, quoting_style, @@ -910,8 +925,8 @@ impl Config { false } }, - group_directories_first: options.contains_id(options::GROUP_DIRECTORIES_FIRST), - eol: if options.contains_id(options::ZERO) { + group_directories_first: options.get_flag(options::GROUP_DIRECTORIES_FIRST), + eol: if options.get_flag(options::ZERO) { '\0' } else { '\n' @@ -936,23 +951,24 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { list(locs, &config) } -pub fn uu_app<'a>() -> Command<'a> { +pub fn uu_app() -> Command { Command::new(uucore::util_name()) .version(crate_version!()) .override_usage(format_usage(USAGE)) .about(ABOUT) .infer_long_args(true) + .disable_help_flag(true) .arg( Arg::new(options::HELP) .long(options::HELP) - .help("Print help information."), + .help("Print help information.") + .action(ArgAction::Help), ) // Format arguments .arg( Arg::new(options::FORMAT) .long(options::FORMAT) .help("Set the display format.") - .takes_value(true) .value_parser([ "long", "verbose", @@ -983,7 +999,8 @@ pub fn uu_app<'a>() -> Command<'a> { options::format::LONG, options::format::ACROSS, options::format::COLUMNS, - ]), + ]) + .action(ArgAction::SetTrue), ) .arg( Arg::new(options::format::LONG) @@ -996,7 +1013,8 @@ pub fn uu_app<'a>() -> Command<'a> { options::format::LONG, options::format::ACROSS, options::format::COLUMNS, - ]), + ]) + .action(ArgAction::SetTrue), ) .arg( Arg::new(options::format::ACROSS) @@ -1008,7 +1026,8 @@ pub fn uu_app<'a>() -> Command<'a> { options::format::LONG, options::format::ACROSS, options::format::COLUMNS, - ]), + ]) + .action(ArgAction::SetTrue), ) .arg( // silently ignored (see #3624) @@ -1016,7 +1035,6 @@ pub fn uu_app<'a>() -> Command<'a> { .short('T') .long(options::format::TAB_SIZE) .env("TABSIZE") - .takes_value(true) .value_name("COLS") .help("Assume tab stops at each COLS instead of 8 (unimplemented)"), ) @@ -1030,20 +1048,23 @@ pub fn uu_app<'a>() -> Command<'a> { options::format::LONG, options::format::ACROSS, options::format::COLUMNS, - ]), + ]) + .action(ArgAction::SetTrue), ) .arg( Arg::new(options::ZERO) .long(options::ZERO) .conflicts_with(options::DIRED) .overrides_with(options::ZERO) - .help("List entries separated by ASCII NUL characters."), + .help("List entries separated by ASCII NUL characters.") + .action(ArgAction::SetTrue), ) .arg( Arg::new(options::DIRED) .long(options::DIRED) .short('D') - .hide(true), + .hide(true) + .action(ArgAction::SetTrue), ) // The next four arguments do not override with the other format // options, see the comment in Config::from for the reason. @@ -1055,7 +1076,7 @@ pub fn uu_app<'a>() -> Command<'a> { Arg::new(options::format::ONE_LINE) .short('1') .help("List one file per line.") - .multiple_occurrences(true), + .action(ArgAction::SetTrue), ) .arg( Arg::new(options::format::LONG_NO_GROUP) @@ -1064,26 +1085,25 @@ pub fn uu_app<'a>() -> Command<'a> { "Long format without group information. \ Identical to --format=long with --no-group.", ) - .multiple_occurrences(true), + .action(ArgAction::SetTrue), ) .arg( Arg::new(options::format::LONG_NO_OWNER) .short('g') .help("Long format without owner information.") - .multiple_occurrences(true), + .action(ArgAction::SetTrue), ) .arg( Arg::new(options::format::LONG_NUMERIC_UID_GID) .short('n') .long(options::format::LONG_NUMERIC_UID_GID) .help("-l with numeric UIDs and GIDs.") - .multiple_occurrences(true), + .action(ArgAction::SetTrue), ) // Quoting style .arg( Arg::new(options::QUOTING_STYLE) .long(options::QUOTING_STYLE) - .takes_value(true) .help("Set quoting style.") .value_parser([ "literal", @@ -1111,7 +1131,8 @@ pub fn uu_app<'a>() -> Command<'a> { options::quoting::LITERAL, options::quoting::ESCAPE, options::quoting::C, - ]), + ]) + .action(ArgAction::SetTrue), ) .arg( Arg::new(options::quoting::ESCAPE) @@ -1123,7 +1144,8 @@ pub fn uu_app<'a>() -> Command<'a> { options::quoting::LITERAL, options::quoting::ESCAPE, options::quoting::C, - ]), + ]) + .action(ArgAction::SetTrue), ) .arg( Arg::new(options::quoting::C) @@ -1135,7 +1157,8 @@ pub fn uu_app<'a>() -> Command<'a> { options::quoting::LITERAL, options::quoting::ESCAPE, options::quoting::C, - ]), + ]) + .action(ArgAction::SetTrue), ) // Control characters .arg( @@ -1143,13 +1166,15 @@ pub fn uu_app<'a>() -> Command<'a> { .short('q') .long(options::HIDE_CONTROL_CHARS) .help("Replace control characters with '?' if they are not escaped.") - .overrides_with_all(&[options::HIDE_CONTROL_CHARS, options::SHOW_CONTROL_CHARS]), + .overrides_with_all(&[options::HIDE_CONTROL_CHARS, options::SHOW_CONTROL_CHARS]) + .action(ArgAction::SetTrue), ) .arg( Arg::new(options::SHOW_CONTROL_CHARS) .long(options::SHOW_CONTROL_CHARS) .help("Show control characters 'as is' if they are not escaped.") - .overrides_with_all(&[options::HIDE_CONTROL_CHARS, options::SHOW_CONTROL_CHARS]), + .overrides_with_all(&[options::HIDE_CONTROL_CHARS, options::SHOW_CONTROL_CHARS]) + .action(ArgAction::SetTrue), ) // Time arguments .arg( @@ -1162,7 +1187,6 @@ pub fn uu_app<'a>() -> Command<'a> { \tbirth time: birth, creation;", ) .value_name("field") - .takes_value(true) .value_parser([ "atime", "access", "use", "ctime", "status", "birth", "creation", ]) @@ -1179,7 +1203,8 @@ pub fn uu_app<'a>() -> Command<'a> { time. When explicitly sorting by time (--sort=time or -t) or when not \ using a long listing format, sort according to the status change time.", ) - .overrides_with_all(&[options::TIME, options::time::ACCESS, options::time::CHANGE]), + .overrides_with_all(&[options::TIME, options::time::ACCESS, options::time::CHANGE]) + .action(ArgAction::SetTrue), ) .arg( Arg::new(options::time::ACCESS) @@ -1190,14 +1215,14 @@ pub fn uu_app<'a>() -> Command<'a> { sorting by time (--sort=time or -t) or when not using a long listing \ format, sort according to the access time.", ) - .overrides_with_all(&[options::TIME, options::time::ACCESS, options::time::CHANGE]), + .overrides_with_all(&[options::TIME, options::time::ACCESS, options::time::CHANGE]) + .action(ArgAction::SetTrue), ) // Hide and ignore .arg( Arg::new(options::HIDE) .long(options::HIDE) - .takes_value(true) - .multiple_occurrences(true) + .action(ArgAction::Append) .value_name("PATTERN") .help( "do not list implied entries matching shell PATTERN (overridden by -a or -A)", @@ -1207,8 +1232,7 @@ pub fn uu_app<'a>() -> Command<'a> { Arg::new(options::IGNORE) .short('I') .long(options::IGNORE) - .takes_value(true) - .multiple_occurrences(true) + .action(ArgAction::Append) .value_name("PATTERN") .help("do not list implied entries matching shell PATTERN"), ) @@ -1216,7 +1240,8 @@ pub fn uu_app<'a>() -> Command<'a> { Arg::new(options::IGNORE_BACKUPS) .short('B') .long(options::IGNORE_BACKUPS) - .help("Ignore entries which end with ~."), + .help("Ignore entries which end with ~.") + .action(ArgAction::SetTrue), ) // Sort arguments .arg( @@ -1224,7 +1249,6 @@ pub fn uu_app<'a>() -> Command<'a> { .long(options::SORT) .help("Sort by : name, none (-U), time (-t), size (-S) or extension (-X)") .value_name("field") - .takes_value(true) .value_parser(["name", "none", "time", "size", "version", "extension"]) .require_equals(true) .overrides_with_all(&[ @@ -1247,7 +1271,8 @@ pub fn uu_app<'a>() -> Command<'a> { options::sort::NONE, options::sort::VERSION, options::sort::EXTENSION, - ]), + ]) + .action(ArgAction::SetTrue), ) .arg( Arg::new(options::sort::TIME) @@ -1260,7 +1285,8 @@ pub fn uu_app<'a>() -> Command<'a> { options::sort::NONE, options::sort::VERSION, options::sort::EXTENSION, - ]), + ]) + .action(ArgAction::SetTrue), ) .arg( Arg::new(options::sort::VERSION) @@ -1273,7 +1299,8 @@ pub fn uu_app<'a>() -> Command<'a> { options::sort::NONE, options::sort::VERSION, options::sort::EXTENSION, - ]), + ]) + .action(ArgAction::SetTrue), ) .arg( Arg::new(options::sort::EXTENSION) @@ -1286,7 +1313,8 @@ pub fn uu_app<'a>() -> Command<'a> { options::sort::NONE, options::sort::VERSION, options::sort::EXTENSION, - ]), + ]) + .action(ArgAction::SetTrue), ) .arg( Arg::new(options::sort::NONE) @@ -1303,7 +1331,8 @@ pub fn uu_app<'a>() -> Command<'a> { options::sort::NONE, options::sort::VERSION, options::sort::EXTENSION, - ]), + ]) + .action(ArgAction::SetTrue), ) // Dereferencing .arg( @@ -1318,7 +1347,8 @@ pub fn uu_app<'a>() -> Command<'a> { options::dereference::ALL, options::dereference::DIR_ARGS, options::dereference::ARGS, - ]), + ]) + .action(ArgAction::SetTrue), ) .arg( Arg::new(options::dereference::DIR_ARGS) @@ -1331,7 +1361,8 @@ pub fn uu_app<'a>() -> Command<'a> { options::dereference::ALL, options::dereference::DIR_ARGS, options::dereference::ARGS, - ]), + ]) + .action(ArgAction::SetTrue), ) .arg( Arg::new(options::dereference::ARGS) @@ -1342,40 +1373,42 @@ pub fn uu_app<'a>() -> Command<'a> { options::dereference::ALL, options::dereference::DIR_ARGS, options::dereference::ARGS, - ]), + ]) + .action(ArgAction::SetTrue), ) // Long format options .arg( Arg::new(options::NO_GROUP) .long(options::NO_GROUP) .short('G') - .help("Do not show group in long format."), + .help("Do not show group in long format.") + .action(ArgAction::SetTrue), ) .arg(Arg::new(options::AUTHOR).long(options::AUTHOR).help( - "Show author in long format. \ - On the supported platforms, the author always matches the file owner.", - )) + "Show author in long format. On the supported platforms, \ + the author always matches the file owner.", + ).action(ArgAction::SetTrue)) // Other Flags .arg( Arg::new(options::files::ALL) .short('a') .long(options::files::ALL) // Overrides -A (as the order matters) - .overrides_with(options::files::ALMOST_ALL) - .multiple_occurrences(true) - .help("Do not ignore hidden files (files with names that start with '.')."), + .overrides_with_all([options::files::ALL, options::files::ALMOST_ALL]) + .help("Do not ignore hidden files (files with names that start with '.').") + .action(ArgAction::SetTrue), ) .arg( Arg::new(options::files::ALMOST_ALL) .short('A') .long(options::files::ALMOST_ALL) // Overrides -a (as the order matters) - .overrides_with(options::files::ALL) - .multiple_occurrences(true) + .overrides_with_all([options::files::ALL, options::files::ALMOST_ALL]) .help( "In a directory, do not ignore all file names that start with '.', \ only ignore '.' and '..'.", - ), + ) + .action(ArgAction::SetTrue), ) .arg( Arg::new(options::DIRECTORY) @@ -1386,14 +1419,16 @@ pub fn uu_app<'a>() -> Command<'a> { This will not follow symbolic links unless one of `--dereference-command-line \ (-H)`, `--dereference (-L)`, or `--dereference-command-line-symlink-to-dir` is \ specified.", - ), + ) + .action(ArgAction::SetTrue), ) .arg( Arg::new(options::size::HUMAN_READABLE) .short('h') .long(options::size::HUMAN_READABLE) .help("Print human readable file sizes (e.g. 1K 234M 56G).") - .overrides_with(options::size::SI), + .overrides_with(options::size::SI) + .action(ArgAction::SetTrue), ) .arg( Arg::new(options::size::KIBIBYTES) @@ -1402,17 +1437,18 @@ pub fn uu_app<'a>() -> Command<'a> { .help( "default to 1024-byte blocks for file system usage; used only with -s and per \ directory totals", - ), + ) + .action(ArgAction::SetTrue), ) .arg( Arg::new(options::size::SI) .long(options::size::SI) - .help("Print human readable file sizes using powers of 1000 instead of 1024."), + .help("Print human readable file sizes using powers of 1000 instead of 1024.") + .action(ArgAction::SetTrue), ) .arg( Arg::new(options::size::BLOCK_SIZE) .long(options::size::BLOCK_SIZE) - .takes_value(true) .require_equals(true) .value_name("BLOCK_SIZE") .help("scale sizes by BLOCK_SIZE when printing them"), @@ -1421,7 +1457,8 @@ pub fn uu_app<'a>() -> Command<'a> { Arg::new(options::INODE) .short('i') .long(options::INODE) - .help("print the index number of each file"), + .help("print the index number of each file") + .action(ArgAction::SetTrue), ) .arg( Arg::new(options::REVERSE) @@ -1430,38 +1467,39 @@ pub fn uu_app<'a>() -> Command<'a> { .help( "Reverse whatever the sorting method is e.g., list files in reverse \ alphabetical order, youngest first, smallest first, or whatever.", - ), + ) + .action(ArgAction::SetTrue), ) .arg( Arg::new(options::RECURSIVE) .short('R') .long(options::RECURSIVE) - .help("List the contents of all directories recursively."), + .help("List the contents of all directories recursively.") + .action(ArgAction::SetTrue), ) .arg( Arg::new(options::WIDTH) .long(options::WIDTH) .short('w') .help("Assume that the terminal is COLS columns wide.") - .value_name("COLS") - .takes_value(true), + .value_name("COLS"), ) .arg( Arg::new(options::size::ALLOCATION_SIZE) .short('s') .long(options::size::ALLOCATION_SIZE) - .help("print the allocated size of each file, in blocks"), + .help("print the allocated size of each file, in blocks") + .action(ArgAction::SetTrue), ) .arg( Arg::new(options::COLOR) .long(options::COLOR) .help("Color output based on file type.") - .takes_value(true) .value_parser([ "always", "yes", "force", "auto", "tty", "if-tty", "never", "no", "none", ]) .require_equals(true) - .min_values(0), + .num_args(0..=1), ) .arg( Arg::new(options::INDICATOR_STYLE) @@ -1470,7 +1508,6 @@ pub fn uu_app<'a>() -> Command<'a> { "Append indicator with style WORD to entry names: \ none (default), slash (-p), file-type (--file-type), classify (-F)", ) - .takes_value(true) .value_parser(["none", "slash", "file-type", "classify"]) .overrides_with_all(&[ options::indicator_style::FILE_TYPE, @@ -1501,14 +1538,13 @@ pub fn uu_app<'a>() -> Command<'a> { --dereference-command-line (-H), --dereference (-L), or \ --dereference-command-line-symlink-to-dir options are specified.", ) - .takes_value(true) .value_name("when") .value_parser([ "always", "yes", "force", "auto", "tty", "if-tty", "never", "no", "none", ]) .default_missing_value("always") .require_equals(true) - .min_values(0) + .num_args(0..=1) .overrides_with_all(&[ options::indicator_style::FILE_TYPE, options::indicator_style::SLASH, @@ -1525,7 +1561,8 @@ pub fn uu_app<'a>() -> Command<'a> { options::indicator_style::SLASH, options::indicator_style::CLASSIFY, options::INDICATOR_STYLE, - ]), + ]) + .action(ArgAction::SetTrue), ) .arg( Arg::new(options::indicator_style::SLASH) @@ -1536,7 +1573,8 @@ pub fn uu_app<'a>() -> Command<'a> { options::indicator_style::SLASH, options::indicator_style::CLASSIFY, options::INDICATOR_STYLE, - ]), + ]) + .action(ArgAction::SetTrue), ) .arg( //This still needs support for posix-* @@ -1552,13 +1590,15 @@ pub fn uu_app<'a>() -> Command<'a> { Arg::new(options::FULL_TIME) .long(options::FULL_TIME) .overrides_with(options::FULL_TIME) - .help("like -l --time-style=full-iso"), + .help("like -l --time-style=full-iso") + .action(ArgAction::SetTrue), ) .arg( Arg::new(options::CONTEXT) .short('Z') .long(options::CONTEXT) - .help(CONTEXT_HELP_TEXT), + .help(CONTEXT_HELP_TEXT) + .action(ArgAction::SetTrue), ) .arg( Arg::new(options::GROUP_DIRECTORIES_FIRST) @@ -1566,13 +1606,13 @@ pub fn uu_app<'a>() -> Command<'a> { .help( "group directories before files; can be augmented with \ a --sort option, but any use of --sort=none (-U) disables grouping", - ), + ) + .action(ArgAction::SetTrue), ) // Positional arguments .arg( Arg::new(options::PATHS) - .multiple_occurrences(true) - .takes_value(true) + .action(ArgAction::Append) .value_hint(clap::ValueHint::AnyPath) .value_parser(ValueParser::os_string()), ) diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index a7891e737..920f8148f 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -3248,6 +3248,7 @@ fn test_ls_multiple_a_A() { } #[test] +#[cfg(feature = "ln")] fn test_ls_quoting() { let scene = TestScenario::new(util_name!()); @@ -3267,6 +3268,7 @@ fn test_ls_quoting() { } #[test] +#[cfg(feature = "ln")] fn test_ls_quoting_color() { let scene = TestScenario::new(util_name!());