sort: update to clap 4

This commit is contained in:
Terts Diepraam 2022-10-01 00:00:53 +02:00
parent 6a98c4c7d0
commit c11d6b45cc
2 changed files with 64 additions and 49 deletions

View file

@ -16,7 +16,7 @@ path = "src/sort.rs"
[dependencies]
binary-heap-plus = "0.4.1"
clap = { version = "3.2", features = ["wrap_help", "cargo"] }
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
compare = "0.1.0"
ctrlc = { version = "3.0", features = ["termination"] }
fnv = "1.0.7"

View file

@ -26,7 +26,7 @@ mod tmp_dir;
use chunks::LineData;
use clap::builder::ValueParser;
use clap::{crate_version, Arg, Command};
use clap::{crate_version, Arg, ArgAction, Command};
use custom_str_cmp::custom_str_cmp;
use ext_sort::ext_sort;
use fnv::FnvHasher;
@ -99,6 +99,7 @@ mod options {
}
pub const HELP: &str = "help";
pub const VERSION: &str = "version";
pub const DICTIONARY_ORDER: &str = "dictionary-order";
pub const MERGE: &str = "merge";
pub const DEBUG: &str = "debug";
@ -1044,8 +1045,12 @@ impl FieldSelector {
}
/// Creates an `Arg` that conflicts with all other sort modes.
fn make_sort_mode_arg<'a>(mode: &'a str, short: char, help: &'a str) -> Arg<'a> {
let mut arg = Arg::new(mode).short(short).long(mode).help(help);
fn make_sort_mode_arg(mode: &'static str, short: char, help: &'static str) -> Arg {
let mut arg = Arg::new(mode)
.short(short)
.long(mode)
.help(help)
.action(ArgAction::SetTrue);
for possible_mode in &options::modes::ALL_SORT_MODES {
if *possible_mode != mode {
arg = arg.conflicts_with(possible_mode);
@ -1075,7 +1080,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
}
};
settings.debug = matches.contains_id(options::DEBUG);
settings.debug = matches.get_flag(options::DEBUG);
// check whether user specified a zero terminated list of files for input, otherwise read files from args
let mut files: Vec<OsString> = if matches.contains_id(options::FILES0_FROM) {
@ -1103,42 +1108,42 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
.unwrap_or_default()
};
settings.mode = if matches.contains_id(options::modes::HUMAN_NUMERIC)
settings.mode = if matches.get_flag(options::modes::HUMAN_NUMERIC)
|| matches
.get_one::<String>(options::modes::SORT)
.map(|s| s.as_str())
== Some("human-numeric")
{
SortMode::HumanNumeric
} else if matches.contains_id(options::modes::MONTH)
} else if matches.get_flag(options::modes::MONTH)
|| matches
.get_one::<String>(options::modes::SORT)
.map(|s| s.as_str())
== Some("month")
{
SortMode::Month
} else if matches.contains_id(options::modes::GENERAL_NUMERIC)
} else if matches.get_flag(options::modes::GENERAL_NUMERIC)
|| matches
.get_one::<String>(options::modes::SORT)
.map(|s| s.as_str())
== Some("general-numeric")
{
SortMode::GeneralNumeric
} else if matches.contains_id(options::modes::NUMERIC)
} else if matches.get_flag(options::modes::NUMERIC)
|| matches
.get_one::<String>(options::modes::SORT)
.map(|s| s.as_str())
== Some("numeric")
{
SortMode::Numeric
} else if matches.contains_id(options::modes::VERSION)
} else if matches.get_flag(options::modes::VERSION)
|| matches
.get_one::<String>(options::modes::SORT)
.map(|s| s.as_str())
== Some("version")
{
SortMode::Version
} else if matches.contains_id(options::modes::RANDOM)
} else if matches.get_flag(options::modes::RANDOM)
|| matches
.get_one::<String>(options::modes::SORT)
.map(|s| s.as_str())
@ -1150,8 +1155,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
SortMode::Default
};
settings.dictionary_order = matches.contains_id(options::DICTIONARY_ORDER);
settings.ignore_non_printing = matches.contains_id(options::IGNORE_NONPRINTING);
settings.dictionary_order = matches.get_flag(options::DICTIONARY_ORDER);
settings.ignore_non_printing = matches.get_flag(options::IGNORE_NONPRINTING);
if matches.contains_id(options::PARALLEL) {
// "0" is default - threads = num of cores
settings.threads = matches
@ -1190,11 +1195,11 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
})?;
}
settings.zero_terminated = matches.contains_id(options::ZERO_TERMINATED);
settings.merge = matches.contains_id(options::MERGE);
settings.zero_terminated = matches.get_flag(options::ZERO_TERMINATED);
settings.merge = matches.get_flag(options::MERGE);
settings.check = matches.contains_id(options::check::CHECK);
if matches.contains_id(options::check::CHECK_SILENT)
if matches.get_flag(options::check::CHECK_SILENT)
|| matches!(
matches
.get_one::<String>(options::check::CHECK)
@ -1206,13 +1211,13 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
settings.check = true;
};
settings.ignore_case = matches.contains_id(options::IGNORE_CASE);
settings.ignore_case = matches.get_flag(options::IGNORE_CASE);
settings.ignore_leading_blanks = matches.contains_id(options::IGNORE_LEADING_BLANKS);
settings.ignore_leading_blanks = matches.get_flag(options::IGNORE_LEADING_BLANKS);
settings.reverse = matches.contains_id(options::REVERSE);
settings.stable = matches.contains_id(options::STABLE);
settings.unique = matches.contains_id(options::UNIQUE);
settings.reverse = matches.get_flag(options::REVERSE);
settings.stable = matches.get_flag(options::STABLE);
settings.unique = matches.get_flag(options::UNIQUE);
if files.is_empty() {
/* if no file, default to stdin */
@ -1299,22 +1304,30 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
result
}
pub fn uu_app<'a>() -> Command<'a> {
pub fn uu_app() -> Command {
Command::new(uucore::util_name())
.version(crate_version!())
.about(ABOUT)
.after_help(LONG_HELP_KEYS)
.override_usage(format_usage(USAGE))
.infer_long_args(true)
.disable_help_flag(true)
.disable_version_flag(true)
.arg(
Arg::new(options::HELP)
.long(options::HELP)
.help("Print help information."),
.help("Print help information.")
.action(ArgAction::Help),
)
.arg(
Arg::new(options::VERSION)
.long(options::VERSION)
.help("Print version information.")
.action(ArgAction::Version),
)
.arg(
Arg::new(options::modes::SORT)
.long(options::modes::SORT)
.takes_value(true)
.value_parser([
"general-numeric",
"human-numeric",
@ -1365,21 +1378,22 @@ pub fn uu_app<'a>() -> Command<'a> {
options::modes::GENERAL_NUMERIC,
options::modes::HUMAN_NUMERIC,
options::modes::MONTH,
]),
])
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(options::MERGE)
.short('m')
.long(options::MERGE)
.help("merge already sorted files; do not sort"),
.help("merge already sorted files; do not sort")
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(options::check::CHECK)
.short('c')
.long(options::check::CHECK)
.takes_value(true)
.require_equals(true)
.min_values(0)
.num_args(0..)
.value_parser([
options::check::SILENT,
options::check::QUIET,
@ -1396,13 +1410,15 @@ pub fn uu_app<'a>() -> Command<'a> {
.help(
"exit successfully if the given file is already sorted, \
and exit with status 1 otherwise.",
),
)
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(options::IGNORE_CASE)
.short('f')
.long(options::IGNORE_CASE)
.help("fold lower case to upper case characters"),
.help("fold lower case to upper case characters")
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(options::IGNORE_NONPRINTING)
@ -1414,20 +1430,21 @@ pub fn uu_app<'a>() -> Command<'a> {
options::modes::GENERAL_NUMERIC,
options::modes::HUMAN_NUMERIC,
options::modes::MONTH,
]),
])
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(options::IGNORE_LEADING_BLANKS)
.short('b')
.long(options::IGNORE_LEADING_BLANKS)
.help("ignore leading blanks when finding sort keys in each line"),
.help("ignore leading blanks when finding sort keys in each line")
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(options::OUTPUT)
.short('o')
.long(options::OUTPUT)
.help("write output to FILENAME instead of stdout")
.takes_value(true)
.value_name("FILENAME")
.value_hint(clap::ValueHint::FilePath),
)
@ -1435,48 +1452,49 @@ pub fn uu_app<'a>() -> Command<'a> {
Arg::new(options::REVERSE)
.short('r')
.long(options::REVERSE)
.help("reverse the output"),
.help("reverse the output")
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(options::STABLE)
.short('s')
.long(options::STABLE)
.help("stabilize sort by disabling last-resort comparison"),
.help("stabilize sort by disabling last-resort comparison")
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(options::UNIQUE)
.short('u')
.long(options::UNIQUE)
.help("output only the first of an equal run"),
.help("output only the first of an equal run")
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(options::KEY)
.short('k')
.long(options::KEY)
.help("sort by a key")
.multiple_occurrences(true)
.number_of_values(1)
.takes_value(true),
.action(ArgAction::Append)
.num_args(1),
)
.arg(
Arg::new(options::SEPARATOR)
.short('t')
.long(options::SEPARATOR)
.help("custom separator for -k")
.takes_value(true)
.value_parser(ValueParser::os_string()),
)
.arg(
Arg::new(options::ZERO_TERMINATED)
.short('z')
.long(options::ZERO_TERMINATED)
.help("line delimiter is NUL, not newline"),
.help("line delimiter is NUL, not newline")
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(options::PARALLEL)
.long(options::PARALLEL)
.help("change the number of threads running concurrently to NUM_THREADS")
.takes_value(true)
.value_name("NUM_THREADS"),
)
.arg(
@ -1484,7 +1502,6 @@ pub fn uu_app<'a>() -> Command<'a> {
.short('S')
.long(options::BUF_SIZE)
.help("sets the maximum SIZE of each segment in number of sorted items")
.takes_value(true)
.value_name("SIZE"),
)
.arg(
@ -1492,7 +1509,6 @@ pub fn uu_app<'a>() -> Command<'a> {
.short('T')
.long(options::TMP_DIR)
.help("use DIR for temporaries, not $TMPDIR or /tmp")
.takes_value(true)
.value_name("DIR")
.value_hint(clap::ValueHint::DirPath),
)
@ -1513,21 +1529,20 @@ pub fn uu_app<'a>() -> Command<'a> {
Arg::new(options::FILES0_FROM)
.long(options::FILES0_FROM)
.help("read input from the files specified by NUL-terminated NUL_FILES")
.takes_value(true)
.value_name("NUL_FILES")
.multiple_occurrences(true)
.action(ArgAction::Append)
.value_parser(ValueParser::os_string())
.value_hint(clap::ValueHint::FilePath),
)
.arg(
Arg::new(options::DEBUG)
.long(options::DEBUG)
.help("underline the parts of the line that are actually used for sorting"),
.help("underline the parts of the line that are actually used for sorting")
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(options::FILES)
.multiple_occurrences(true)
.takes_value(true)
.action(ArgAction::Append)
.value_parser(ValueParser::os_string())
.value_hint(clap::ValueHint::FilePath),
)