fix: Make arg!(--flag <value>) optional by default

This was ported over from the usage parser which modeled after docopt.
We just never got around to implementing the rest of the syntax.

However, when considering this as a standalone feature, an
`arg!(--flag <value>)`, outside of other context, should be optional.
This is how the help would display it.

Fixes #4206
This commit is contained in:
Ed Page 2022-09-12 16:59:57 -05:00
parent 75a73f3fe0
commit c9eef44213
31 changed files with 177 additions and 301 deletions

View file

@ -183,6 +183,7 @@ Subtle changes (i.e. compiler won't catch):
- By default, an `Arg`s default action is `ArgAction::Set`, rather than `ArgAction::IncOccurrence` to reduce confusing magic through consistency (#2687, #4032, see also #3977) - By default, an `Arg`s default action is `ArgAction::Set`, rather than `ArgAction::IncOccurrence` to reduce confusing magic through consistency (#2687, #4032, see also #3977)
- `mut_arg` can no longer be used to customize help and version arguments, instead disable them (`Command::disable_help_flag`, `Command::disable_version_flag`) and provide your own (#4056) - `mut_arg` can no longer be used to customize help and version arguments, instead disable them (`Command::disable_help_flag`, `Command::disable_version_flag`) and provide your own (#4056)
- Removed lifetimes from `Command`, `Arg`, `ArgGroup`, and `PossibleValue` - Removed lifetimes from `Command`, `Arg`, `ArgGroup`, and `PossibleValue`
- `arg!(--flag <value>)` is now optional, instead of required. Add `.required(true)` at the end to restore the original behavior (#4206)
- *(parser)* Always fill in `""` argument for external subcommands to make it easier to distinguish them from built-in commands (#3263) - *(parser)* Always fill in `""` argument for external subcommands to make it easier to distinguish them from built-in commands (#3263)
- *(parser)* Short flags now have higher precedence than hyphen values with `Arg::allow_hyphen_values`, to be consistent with `Command::allow_hyphen_values` (#4187) - *(parser)* Short flags now have higher precedence than hyphen values with `Arg::allow_hyphen_values`, to be consistent with `Command::allow_hyphen_values` (#4187)
- *(parser)* `Arg::value_terminator` must be its own argument on the CLI rather than being in a delimited list (#4025) - *(parser)* `Arg::value_terminator` must be its own argument on the CLI rather than being in a delimited list (#4025)

View file

@ -8,7 +8,7 @@ macro_rules! create_app {
.about("tests clap library") .about("tests clap library")
.author("Kevin K. <kbknapp@gmail.com>") .author("Kevin K. <kbknapp@gmail.com>")
.arg(arg!(-f --flag "tests flags")) .arg(arg!(-f --flag "tests flags"))
.arg(arg!(-o --option <opt> "tests options").required(false)) .arg(arg!(-o --option <opt> "tests options"))
.arg(arg!([positional] "tests positional")) .arg(arg!([positional] "tests positional"))
}}; }};
} }
@ -34,14 +34,14 @@ pub fn build_with_flag_ref(c: &mut Criterion) {
pub fn build_with_opt(c: &mut Criterion) { pub fn build_with_opt(c: &mut Criterion) {
c.bench_function("build_with_opt", |b| { c.bench_function("build_with_opt", |b| {
b.iter(|| Command::new("claptests").arg(arg!(-s --some <FILE> "something"))) b.iter(|| Command::new("claptests").arg(arg!(-s --some <FILE> "something").required(true)))
}); });
} }
pub fn build_with_opt_ref(c: &mut Criterion) { pub fn build_with_opt_ref(c: &mut Criterion) {
c.bench_function("build_with_opt_ref", |b| { c.bench_function("build_with_opt_ref", |b| {
b.iter(|| { b.iter(|| {
let arg = arg!(-s --some <FILE> "something"); let arg = arg!(-s --some <FILE> "something").required(true);
Command::new("claptests").arg(&arg) Command::new("claptests").arg(&arg)
}) })
}); });

View file

@ -10,7 +10,7 @@ macro_rules! create_app {
.version("0.1") .version("0.1")
.about("tests clap library") .about("tests clap library")
.author("Kevin K. <kbknapp@gmail.com>") .author("Kevin K. <kbknapp@gmail.com>")
.arg(arg!(-o --option <opt> ... "tests options").required(false)) .arg(arg!(-o --option <opt> ... "tests options"))
.arg(arg!([positional] "tests positionals")) .arg(arg!([positional] "tests positionals"))
.arg(arg!(-f --flag ... "tests flags").global(true)) .arg(arg!(-f --flag ... "tests flags").global(true))
.args([ .args([
@ -18,28 +18,26 @@ macro_rules! create_app {
.conflicts_with("flag") .conflicts_with("flag")
.requires("option2"), .requires("option2"),
arg!(option2: --"long-option-2" <option2> "tests long options with exclusions") arg!(option2: --"long-option-2" <option2> "tests long options with exclusions")
.required(false)
.conflicts_with("option") .conflicts_with("option")
.requires("positional2"), .requires("positional2"),
arg!([positional2] "tests positionals with exclusions"), arg!([positional2] "tests positionals with exclusions"),
arg!(-O --Option <option3> "tests options with specific value sets") arg!(-O --Option <option3> "tests options with specific value sets")
.required(false)
.value_parser(OPT3_VALS), .value_parser(OPT3_VALS),
arg!([positional3] ... "tests positionals with specific values") arg!([positional3] ... "tests positionals with specific values")
.value_parser(POS3_VALS), .value_parser(POS3_VALS),
arg!(--multvals <s> "Tests multiple values not mult occs").required(false).value_names(["one", "two"]), arg!(--multvals <s> "Tests multiple values not mult occs").value_names(["one", "two"]),
arg!( arg!(
--multvalsmo <s> "Tests multiple values, not mult occs" --multvalsmo <s> "Tests multiple values, not mult occs"
).required(false).value_names(["one", "two"]), ).required(false).value_names(["one", "two"]),
arg!(--minvals2 <minvals> ... "Tests 2 min vals").num_args(2..).required(false), arg!(--minvals2 <minvals> ... "Tests 2 min vals").num_args(2..),
arg!(--maxvals3 <maxvals> ... "Tests 3 max vals").num_args(1..=3).required(false), arg!(--maxvals3 <maxvals> ... "Tests 3 max vals").num_args(1..=3),
]) ])
.subcommand( .subcommand(
Command::new("subcmd") Command::new("subcmd")
.about("tests subcommands") .about("tests subcommands")
.version("0.1") .version("0.1")
.author("Kevin K. <kbknapp@gmail.com>") .author("Kevin K. <kbknapp@gmail.com>")
.arg(arg!(-o --option <scoption> ... "tests options").required(false)) .arg(arg!(-o --option <scoption> ... "tests options"))
.arg(arg!([scpositional] "tests positionals")) .arg(arg!([scpositional] "tests positionals"))
) )
}}; }};

View file

@ -19,7 +19,6 @@ And a few newlines.",
.arg( .arg(
arg!(-c --config <FILE> "Sets a custom config file") arg!(-c --config <FILE> "Sets a custom config file")
.long_help("Some more text about how to set a custom config file") .long_help("Some more text about how to set a custom config file")
.required(false)
.default_value("config.toml") .default_value("config.toml")
.env("CONFIG_FILE"), .env("CONFIG_FILE"),
) )

View file

@ -5,7 +5,6 @@ fn main() {
.subcommand( .subcommand(
clap::command!("example").arg( clap::command!("example").arg(
clap::arg!(--"manifest-path" <PATH>) clap::arg!(--"manifest-path" <PATH>)
.required(false)
.value_parser(clap::value_parser!(std::path::PathBuf)), .value_parser(clap::value_parser!(std::path::PathBuf)),
), ),
); );

View file

@ -3,11 +3,7 @@ use clap::{arg, command, value_parser, ArgAction};
fn main() { fn main() {
let matches = command!() // requires `cargo` feature let matches = command!() // requires `cargo` feature
.arg(arg!(eff: -f).action(ArgAction::SetTrue)) .arg(arg!(eff: -f).action(ArgAction::SetTrue))
.arg( .arg(arg!(pea: -p <PEAR>).value_parser(value_parser!(String)))
arg!(pea: -p <PEAR>)
.required(false)
.value_parser(value_parser!(String)),
)
.arg( .arg(
// Indicates that `slop` is only accessible after `--`. // Indicates that `slop` is only accessible after `--`.
arg!(slop: [SLOP]) arg!(slop: [SLOP])

View file

@ -4,7 +4,7 @@
$ find --help $ find --help
A simple to use, efficient, and full-featured Command Line Argument Parser A simple to use, efficient, and full-featured Command Line Argument Parser
Usage: find[EXE] [OPTIONS] --name <NAME> Usage: find[EXE] [OPTIONS]
Options: Options:
-h, --help Print help information -h, --help Print help information

View file

@ -45,7 +45,7 @@ fn cli() -> Command {
} }
fn push_args() -> Vec<clap::Arg> { fn push_args() -> Vec<clap::Arg> {
vec![arg!(-m --message <MESSAGE>).required(false)] vec![arg!(-m --message <MESSAGE>)]
} }
fn main() { fn main() {

View file

@ -3,8 +3,8 @@ use clap::{arg, command, ArgAction};
fn main() { fn main() {
let matches = command!() // requires `cargo` feature let matches = command!() // requires `cargo` feature
.next_line_help(true) .next_line_help(true)
.arg(arg!(--two <VALUE>).action(ArgAction::Set)) .arg(arg!(--two <VALUE>).required(true).action(ArgAction::Set))
.arg(arg!(--one <VALUE>).action(ArgAction::Set)) .arg(arg!(--one <VALUE>).required(true).action(ArgAction::Set))
.get_matches(); .get_matches();
println!( println!(

View file

@ -5,8 +5,8 @@ fn main() {
.version("1.0") .version("1.0")
.author("Kevin K. <kbknapp@gmail.com>") .author("Kevin K. <kbknapp@gmail.com>")
.about("Does awesome things") .about("Does awesome things")
.arg(arg!(--two <VALUE>)) .arg(arg!(--two <VALUE>).required(true))
.arg(arg!(--one <VALUE>)) .arg(arg!(--one <VALUE>).required(true))
.get_matches(); .get_matches();
println!( println!(

View file

@ -3,8 +3,8 @@ use clap::{arg, command};
fn main() { fn main() {
// requires `cargo` feature, reading name, version, author, and description from `Cargo.toml` // requires `cargo` feature, reading name, version, author, and description from `Cargo.toml`
let matches = command!() let matches = command!()
.arg(arg!(--two <VALUE>)) .arg(arg!(--two <VALUE>).required(true))
.arg(arg!(--one <VALUE>)) .arg(arg!(--one <VALUE>).required(true))
.get_matches(); .get_matches();
println!( println!(

View file

@ -6,7 +6,7 @@ fn main() {
// Create application like normal // Create application like normal
let matches = command!() // requires `cargo` feature let matches = command!() // requires `cargo` feature
// Add the version arguments // Add the version arguments
.arg(arg!(--"set-ver" <VER> "set version manually").required(false)) .arg(arg!(--"set-ver" <VER> "set version manually"))
.arg(arg!(--major "auto inc major").action(ArgAction::SetTrue)) .arg(arg!(--major "auto inc major").action(ArgAction::SetTrue))
.arg(arg!(--minor "auto inc minor").action(ArgAction::SetTrue)) .arg(arg!(--minor "auto inc minor").action(ArgAction::SetTrue))
.arg(arg!(--patch "auto inc patch").action(ArgAction::SetTrue)) .arg(arg!(--patch "auto inc patch").action(ArgAction::SetTrue))
@ -25,7 +25,6 @@ fn main() {
) )
.arg( .arg(
arg!(--"spec-in" <SPEC_IN> "some special input argument") arg!(--"spec-in" <SPEC_IN> "some special input argument")
.required(false)
.value_parser(value_parser!(PathBuf)) .value_parser(value_parser!(PathBuf))
.group("input"), .group("input"),
) )
@ -33,7 +32,6 @@ fn main() {
// (but **not** both) the "input" arguments // (but **not** both) the "input" arguments
.arg( .arg(
arg!(config: -c <CONFIG>) arg!(config: -c <CONFIG>)
.required(false)
.value_parser(value_parser!(PathBuf)) .value_parser(value_parser!(PathBuf))
.requires("input"), .requires("input"),
) )

View file

@ -7,7 +7,7 @@ fn main() {
// Create application like normal // Create application like normal
let mut cmd = command!() // requires `cargo` feature let mut cmd = command!() // requires `cargo` feature
// Add the version arguments // Add the version arguments
.arg(arg!(--"set-ver" <VER> "set version manually").required(false)) .arg(arg!(--"set-ver" <VER> "set version manually"))
.arg(arg!(--major "auto inc major").action(ArgAction::SetTrue)) .arg(arg!(--major "auto inc major").action(ArgAction::SetTrue))
.arg(arg!(--minor "auto inc minor").action(ArgAction::SetTrue)) .arg(arg!(--minor "auto inc minor").action(ArgAction::SetTrue))
.arg(arg!(--patch "auto inc patch").action(ArgAction::SetTrue)) .arg(arg!(--patch "auto inc patch").action(ArgAction::SetTrue))
@ -16,16 +16,11 @@ fn main() {
.arg(arg!([INPUT_FILE] "some regular input").value_parser(value_parser!(PathBuf))) .arg(arg!([INPUT_FILE] "some regular input").value_parser(value_parser!(PathBuf)))
.arg( .arg(
arg!(--"spec-in" <SPEC_IN> "some special input argument") arg!(--"spec-in" <SPEC_IN> "some special input argument")
.required(false)
.value_parser(value_parser!(PathBuf)), .value_parser(value_parser!(PathBuf)),
) )
// Now let's assume we have a -c [config] argument which requires one of // Now let's assume we have a -c [config] argument which requires one of
// (but **not** both) the "input" arguments // (but **not** both) the "input" arguments
.arg( .arg(arg!(config: -c <CONFIG>).value_parser(value_parser!(PathBuf)));
arg!(config: -c <CONFIG>)
.required(false)
.value_parser(value_parser!(PathBuf)),
);
let matches = cmd.get_matches_mut(); let matches = cmd.get_matches_mut();
// Let's assume the old version 1.2.3 // Let's assume the old version 1.2.3

View file

@ -36,7 +36,7 @@ use crate::util::Id;
/// ```rust /// ```rust
/// # use clap::{Command, arg, ArgGroup, error::ErrorKind}; /// # use clap::{Command, arg, ArgGroup, error::ErrorKind};
/// let result = Command::new("cmd") /// let result = Command::new("cmd")
/// .arg(arg!(--"set-ver" <ver> "set the version manually").required(false)) /// .arg(arg!(--"set-ver" <ver> "set the version manually"))
/// .arg(arg!(--major "auto increase major")) /// .arg(arg!(--major "auto increase major"))
/// .arg(arg!(--minor "auto increase minor")) /// .arg(arg!(--minor "auto increase minor"))
/// .arg(arg!(--patch "auto increase patch")) /// .arg(arg!(--patch "auto increase patch"))
@ -54,7 +54,7 @@ use crate::util::Id;
/// ```rust /// ```rust
/// # use clap::{Command, arg, ArgGroup, Id}; /// # use clap::{Command, arg, ArgGroup, Id};
/// let result = Command::new("cmd") /// let result = Command::new("cmd")
/// .arg(arg!(--"set-ver" <ver> "set the version manually").required(false)) /// .arg(arg!(--"set-ver" <ver> "set the version manually"))
/// .arg(arg!(--major "auto increase major")) /// .arg(arg!(--major "auto increase major"))
/// .arg(arg!(--minor "auto increase minor")) /// .arg(arg!(--minor "auto increase minor"))
/// .arg(arg!(--patch "auto increase patch")) /// .arg(arg!(--patch "auto increase patch"))

View file

@ -923,8 +923,8 @@ impl Command {
/// # use clap::{Command, arg}; /// # use clap::{Command, arg};
/// let cmd = Command::new("cmd") /// let cmd = Command::new("cmd")
/// .ignore_errors(true) /// .ignore_errors(true)
/// .arg(arg!(-c --config <FILE> "Sets a custom config file").required(false)) /// .arg(arg!(-c --config <FILE> "Sets a custom config file"))
/// .arg(arg!(-x --stuff <FILE> "Sets a custom stuff file").required(false)) /// .arg(arg!(-x --stuff <FILE> "Sets a custom stuff file"))
/// .arg(arg!(f: -f "Flag")); /// .arg(arg!(f: -f "Flag"));
/// ///
/// let r = cmd.try_get_matches_from(vec!["cmd", "-c", "file", "-f", "-x"]); /// let r = cmd.try_get_matches_from(vec!["cmd", "-c", "file", "-f", "-x"]);

View file

@ -295,7 +295,9 @@ macro_rules! arg_impl {
let mut arg = $arg; let mut arg = $arg;
arg = arg.required(true); if arg.get_long().is_none() && arg.get_short().is_none() {
arg = arg.required(true);
}
let value_name = $crate::arg_impl! { @string $value_name }; let value_name = $crate::arg_impl! { @string $value_name };
if arg.get_id() == "" { if arg.get_id() == "" {
@ -322,7 +324,9 @@ macro_rules! arg_impl {
let mut arg = $arg; let mut arg = $arg;
arg = arg.required(true); if arg.get_long().is_none() && arg.get_short().is_none() {
arg = arg.required(true);
}
let value_name = $crate::arg_impl! { @string $value_name }; let value_name = $crate::arg_impl! { @string $value_name };
if arg.get_id() == "" { if arg.get_id() == "" {

View file

@ -376,11 +376,9 @@ impl ArgMatches {
/// ///
/// let m = Command::new("myprog") /// let m = Command::new("myprog")
/// .arg(arg!(--color <when>) /// .arg(arg!(--color <when>)
/// .value_parser(["auto", "always", "never"]) /// .value_parser(["auto", "always", "never"]))
/// .required(false))
/// .arg(arg!(--config <path>) /// .arg(arg!(--config <path>)
/// .value_parser(value_parser!(std::path::PathBuf)) /// .value_parser(value_parser!(std::path::PathBuf)))
/// .required(false))
/// .get_matches_from(["myprog", "--config=config.toml", "--color=auto"]); /// .get_matches_from(["myprog", "--config=config.toml", "--color=auto"]);
/// assert_eq!(m.ids().len(), 2); /// assert_eq!(m.ids().len(), 2);
/// assert_eq!( /// assert_eq!(
@ -1168,11 +1166,9 @@ pub(crate) struct SubCommand {
/// ///
/// let m = Command::new("myprog") /// let m = Command::new("myprog")
/// .arg(arg!(--color <when>) /// .arg(arg!(--color <when>)
/// .value_parser(["auto", "always", "never"]) /// .value_parser(["auto", "always", "never"]))
/// .required(false))
/// .arg(arg!(--config <path>) /// .arg(arg!(--config <path>)
/// .value_parser(value_parser!(std::path::PathBuf)) /// .value_parser(value_parser!(std::path::PathBuf)))
/// .required(false))
/// .get_matches_from(["myprog", "--config=config.toml", "--color=auto"]); /// .get_matches_from(["myprog", "--config=config.toml", "--color=auto"]);
/// assert_eq!( /// assert_eq!(
/// m.ids() /// m.ids()

View file

@ -108,7 +108,7 @@ fn arg_required_else_help_over_req_subcommand() {
fn arg_required_else_help_with_default() { fn arg_required_else_help_with_default() {
let result = Command::new("arg_required") let result = Command::new("arg_required")
.arg_required_else_help(true) .arg_required_else_help(true)
.arg(arg!(--input <PATH>).required(false).default_value("-")) .arg(arg!(--input <PATH>).default_value("-"))
.try_get_matches_from(vec![""]); .try_get_matches_from(vec![""]);
assert!(result.is_err()); assert!(result.is_err());
@ -298,9 +298,7 @@ Options:
.version("1.3") .version("1.3")
.hide_possible_values(true) .hide_possible_values(true)
.args(&[ .args(&[
arg!(-o --opt <opt> "some option") arg!(-o --opt <opt> "some option").value_parser(["one", "two"]),
.required(false)
.value_parser(["one", "two"]),
arg!([arg1] "some pos arg").value_parser(["three", "four"]), arg!([arg1] "some pos arg").value_parser(["three", "four"]),
]); ]);
@ -311,10 +309,7 @@ Options:
fn stop_delim_values_only_pos_follows() { fn stop_delim_values_only_pos_follows() {
let r = Command::new("onlypos") let r = Command::new("onlypos")
.dont_delimit_trailing_values(true) .dont_delimit_trailing_values(true)
.args(&[ .args(&[arg!(f: -f <flag> "some opt"), arg!([arg] ... "some arg")])
arg!(f: -f <flag> "some opt").required(false),
arg!([arg] ... "some arg"),
])
.try_get_matches_from(vec!["", "--", "-f", "-g,x"]); .try_get_matches_from(vec!["", "--", "-f", "-g,x"]);
assert!(r.is_ok(), "{}", r.unwrap_err()); assert!(r.is_ok(), "{}", r.unwrap_err());
let m = r.unwrap(); let m = r.unwrap();
@ -843,7 +838,11 @@ fn missing_positional_hyphen_req_error() {
#[test] #[test]
fn issue_1066_allow_leading_hyphen_and_unknown_args_option() { fn issue_1066_allow_leading_hyphen_and_unknown_args_option() {
let res = Command::new("prog") let res = Command::new("prog")
.arg(arg!(--"some-argument" <val>).allow_hyphen_values(true)) .arg(
arg!(--"some-argument" <val>)
.required(true)
.allow_hyphen_values(true),
)
.try_get_matches_from(vec!["prog", "-fish"]); .try_get_matches_from(vec!["prog", "-fish"]);
assert!(res.is_err()); assert!(res.is_err());
@ -1027,7 +1026,11 @@ fn aaos_flags_mult() {
fn aaos_opts() { fn aaos_opts() {
// opts // opts
let res = Command::new("posix") let res = Command::new("posix")
.arg(arg!(--opt <val> "some option").action(ArgAction::Set)) .arg(
arg!(--opt <val> "some option")
.required(true)
.action(ArgAction::Set),
)
.try_get_matches_from(vec!["", "--opt=some", "--opt=other"]); .try_get_matches_from(vec!["", "--opt=some", "--opt=other"]);
assert!(res.is_ok(), "{}", res.unwrap_err()); assert!(res.is_ok(), "{}", res.unwrap_err());
let m = res.unwrap(); let m = res.unwrap();
@ -1042,14 +1045,9 @@ fn aaos_opts() {
fn aaos_opts_w_other_overrides() { fn aaos_opts_w_other_overrides() {
// opts with other overrides // opts with other overrides
let res = Command::new("posix") let res = Command::new("posix")
.arg( .arg(arg!(--opt <val> "some option").action(ArgAction::Set))
arg!(--opt <val> "some option")
.required(false)
.action(ArgAction::Set),
)
.arg( .arg(
arg!(--other <val> "some other option") arg!(--other <val> "some other option")
.required(false)
.overrides_with("opt") .overrides_with("opt")
.action(ArgAction::Set), .action(ArgAction::Set),
) )
@ -1096,15 +1094,10 @@ fn aaos_opts_w_other_overrides_2() {
let res = Command::new("posix") let res = Command::new("posix")
.arg( .arg(
arg!(--opt <val> "some option") arg!(--opt <val> "some option")
.required(false)
.overrides_with("other") .overrides_with("other")
.action(ArgAction::Set), .action(ArgAction::Set),
) )
.arg( .arg(arg!(--other <val> "some other option").action(ArgAction::Set))
arg!(--other <val> "some other option")
.required(false)
.action(ArgAction::Set),
)
.try_get_matches_from(vec!["", "--opt=some", "--other=test", "--opt=other"]); .try_get_matches_from(vec!["", "--opt=some", "--other=test", "--opt=other"]);
assert!(res.is_ok(), "{}", res.unwrap_err()); assert!(res.is_ok(), "{}", res.unwrap_err());
let m = res.unwrap(); let m = res.unwrap();
@ -1266,7 +1259,11 @@ fn aaos_pos_mult() {
#[test] #[test]
fn aaos_option_use_delim_false() { fn aaos_option_use_delim_false() {
let m = Command::new("posix") let m = Command::new("posix")
.arg(arg!(--opt <val> "some option").action(ArgAction::Set)) .arg(
arg!(--opt <val> "some option")
.required(true)
.action(ArgAction::Set),
)
.try_get_matches_from(vec!["", "--opt=some,other", "--opt=one,two"]) .try_get_matches_from(vec!["", "--opt=some,other", "--opt=one,two"])
.unwrap(); .unwrap();
assert!(m.contains_id("opt")); assert!(m.contains_id("opt"));

View file

@ -5,16 +5,8 @@ use clap::{Arg, ArgAction};
#[test] #[test]
fn ids() { fn ids() {
let m = Command::new("test") let m = Command::new("test")
.arg( .arg(arg!(--color <when>).value_parser(["auto", "always", "never"]))
arg!(--color <when>) .arg(arg!(--config <path>).value_parser(value_parser!(std::path::PathBuf)))
.value_parser(["auto", "always", "never"])
.required(false),
)
.arg(
arg!(--config <path>)
.value_parser(value_parser!(std::path::PathBuf))
.required(false),
)
.try_get_matches_from(["test", "--config=config.toml", "--color=auto"]) .try_get_matches_from(["test", "--config=config.toml", "--color=auto"])
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
@ -27,16 +19,8 @@ fn ids() {
#[test] #[test]
fn ids_ignore_unused() { fn ids_ignore_unused() {
let m = Command::new("test") let m = Command::new("test")
.arg( .arg(arg!(--color <when>).value_parser(["auto", "always", "never"]))
arg!(--color <when>) .arg(arg!(--config <path>).value_parser(value_parser!(std::path::PathBuf)))
.value_parser(["auto", "always", "never"])
.required(false),
)
.arg(
arg!(--config <path>)
.value_parser(value_parser!(std::path::PathBuf))
.required(false),
)
.try_get_matches_from(["test", "--config=config.toml"]) .try_get_matches_from(["test", "--config=config.toml"])
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
@ -49,15 +33,10 @@ fn ids_ignore_unused() {
#[test] #[test]
fn ids_ignore_overridden() { fn ids_ignore_overridden() {
let m = Command::new("test") let m = Command::new("test")
.arg( .arg(arg!(--color <when>).value_parser(["auto", "always", "never"]))
arg!(--color <when>)
.value_parser(["auto", "always", "never"])
.required(false),
)
.arg( .arg(
arg!(--config <path>) arg!(--config <path>)
.value_parser(value_parser!(std::path::PathBuf)) .value_parser(value_parser!(std::path::PathBuf))
.required(false)
.overrides_with("color"), .overrides_with("color"),
) )
.try_get_matches_from(["test", "--config=config.toml", "--color=auto"]) .try_get_matches_from(["test", "--config=config.toml", "--color=auto"])

View file

@ -49,12 +49,8 @@ fn exclusive_flag() {
#[test] #[test]
fn exclusive_option() { fn exclusive_option() {
let result = Command::new("flag_conflict") let result = Command::new("flag_conflict")
.arg( .arg(arg!(-f --flag <VALUE> "some flag").exclusive(true))
arg!(-f --flag <VALUE> "some flag") .arg(arg!(-o --other <VALUE> "some flag"))
.required(false)
.exclusive(true),
)
.arg(arg!(-o --other <VALUE> "some flag").required(false))
.try_get_matches_from(vec!["myprog", "-o=val1", "-f=val2"]); .try_get_matches_from(vec!["myprog", "-o=val1", "-f=val2"]);
assert!(result.is_err()); assert!(result.is_err());
let err = result.err().unwrap(); let err = result.err().unwrap();
@ -64,11 +60,7 @@ fn exclusive_option() {
#[test] #[test]
fn not_exclusive_with_defaults() { fn not_exclusive_with_defaults() {
let result = Command::new("flag_conflict") let result = Command::new("flag_conflict")
.arg( .arg(arg!(-f --flag <VALUE> "some flag").exclusive(true))
arg!(-f --flag <VALUE> "some flag")
.required(false)
.exclusive(true),
)
.arg( .arg(
arg!(-o --other <VALUE> "some flag") arg!(-o --other <VALUE> "some flag")
.required(false) .required(false)
@ -83,15 +75,10 @@ fn default_doesnt_activate_exclusive() {
let result = Command::new("flag_conflict") let result = Command::new("flag_conflict")
.arg( .arg(
arg!(-f --flag <VALUE> "some flag") arg!(-f --flag <VALUE> "some flag")
.required(false)
.exclusive(true) .exclusive(true)
.default_value("val2"), .default_value("val2"),
) )
.arg( .arg(arg!(-o --other <VALUE> "some flag").default_value("val1"))
arg!(-o --other <VALUE> "some flag")
.required(false)
.default_value("val1"),
)
.try_get_matches_from(vec!["myprog"]); .try_get_matches_from(vec!["myprog"]);
assert!(result.is_ok(), "{}", result.unwrap_err()); assert!(result.is_ok(), "{}", result.unwrap_err());
} }
@ -135,14 +122,9 @@ fn arg_conflicts_with_group_with_multiple_sources() {
let mut cmd = clap::Command::new("group_conflict") let mut cmd = clap::Command::new("group_conflict")
.arg(clap::arg!(-f --flag "some flag").conflicts_with("gr")) .arg(clap::arg!(-f --flag "some flag").conflicts_with("gr"))
.group(clap::ArgGroup::new("gr").multiple(true)) .group(clap::ArgGroup::new("gr").multiple(true))
.arg( .arg(clap::arg!(--some <name> "some arg").group("gr"))
clap::arg!(--some <name> "some arg")
.required(false)
.group("gr"),
)
.arg( .arg(
clap::arg!(--other <secs> "other arg") clap::arg!(--other <secs> "other arg")
.required(false)
.default_value("1000") .default_value("1000")
.group("gr"), .group("gr"),
); );
@ -480,11 +462,7 @@ fn conflicts_with_invalid_arg() {
#[test] #[test]
fn conflict_with_unused_default() { fn conflict_with_unused_default() {
let result = Command::new("conflict") let result = Command::new("conflict")
.arg( .arg(arg!(-o --opt <opt> "some opt").default_value("default"))
arg!(-o --opt <opt> "some opt")
.required(false)
.default_value("default"),
)
.arg( .arg(
arg!(-f --flag "some flag") arg!(-f --flag "some flag")
.conflicts_with("opt") .conflicts_with("opt")
@ -508,7 +486,6 @@ fn conflicts_with_alongside_default() {
.arg( .arg(
arg!(-o --opt <opt> "some opt") arg!(-o --opt <opt> "some opt")
.default_value("default") .default_value("default")
.required(false)
.conflicts_with("flag"), .conflicts_with("flag"),
) )
.arg(arg!(-f --flag "some flag").action(ArgAction::SetTrue)) .arg(arg!(-f --flag "some flag").action(ArgAction::SetTrue))
@ -644,7 +621,7 @@ fn subcommand_conflict_negates_required() {
let cmd = Command::new("test") let cmd = Command::new("test")
.args_conflicts_with_subcommands(true) .args_conflicts_with_subcommands(true)
.subcommand(Command::new("config")) .subcommand(Command::new("config"))
.arg(arg!(-p --place <"place id"> "Place ID to open")); .arg(arg!(-p --place <"place id"> "Place ID to open").required(true));
let result = cmd.try_get_matches_from(["test", "config"]); let result = cmd.try_get_matches_from(["test", "config"]);
assert!( assert!(

View file

@ -8,11 +8,7 @@ use clap::{arg, error::ErrorKind, value_parser, Arg, ArgAction, Command};
#[test] #[test]
fn opts() { fn opts() {
let r = Command::new("df") let r = Command::new("df")
.arg( .arg(arg!(o: -o <opt> "some opt").default_value("default"))
arg!(o: -o <opt> "some opt")
.required(false)
.default_value("default"),
)
.try_get_matches_from(vec![""]); .try_get_matches_from(vec![""]);
assert!(r.is_ok(), "{}", r.unwrap_err()); assert!(r.is_ok(), "{}", r.unwrap_err());
let m = r.unwrap(); let m = r.unwrap();
@ -26,11 +22,7 @@ fn opts() {
#[test] #[test]
fn default_has_index() { fn default_has_index() {
let r = Command::new("df") let r = Command::new("df")
.arg( .arg(arg!(o: -o <opt> "some opt").default_value("default"))
arg!(o: -o <opt> "some opt")
.required(false)
.default_value("default"),
)
.try_get_matches_from(vec![""]); .try_get_matches_from(vec![""]);
assert!(r.is_ok(), "{}", r.unwrap_err()); assert!(r.is_ok(), "{}", r.unwrap_err());
let m = r.unwrap(); let m = r.unwrap();
@ -42,7 +34,6 @@ fn opt_without_value_fail() {
let r = Command::new("df") let r = Command::new("df")
.arg( .arg(
arg!(o: -o <opt> "some opt") arg!(o: -o <opt> "some opt")
.required(false)
.default_value("default") .default_value("default")
.value_parser(clap::builder::NonEmptyStringValueParser::new()), .value_parser(clap::builder::NonEmptyStringValueParser::new()),
) )
@ -58,11 +49,7 @@ fn opt_without_value_fail() {
#[test] #[test]
fn opt_user_override() { fn opt_user_override() {
let r = Command::new("df") let r = Command::new("df")
.arg( .arg(arg!(--opt <FILE> "some arg").default_value("default"))
arg!(--opt <FILE> "some arg")
.required(false)
.default_value("default"),
)
.try_get_matches_from(vec!["", "--opt", "value"]); .try_get_matches_from(vec!["", "--opt", "value"]);
assert!(r.is_ok(), "{}", r.unwrap_err()); assert!(r.is_ok(), "{}", r.unwrap_err());
let m = r.unwrap(); let m = r.unwrap();
@ -109,11 +96,7 @@ fn osstr_opts() {
let expected = OsStr::new("default"); let expected = OsStr::new("default");
let r = Command::new("df") let r = Command::new("df")
.arg( .arg(arg!(o: -o <opt> "some opt").default_value(expected))
arg!(o: -o <opt> "some opt")
.required(false)
.default_value(expected),
)
.try_get_matches_from(vec![""]); .try_get_matches_from(vec![""]);
assert!(r.is_ok(), "{}", r.unwrap_err()); assert!(r.is_ok(), "{}", r.unwrap_err());
let m = r.unwrap(); let m = r.unwrap();
@ -130,11 +113,7 @@ fn osstr_opt_user_override() {
let default = OsStr::new("default"); let default = OsStr::new("default");
let r = Command::new("df") let r = Command::new("df")
.arg( .arg(arg!(--opt <FILE> "some arg").default_value(default))
arg!(--opt <FILE> "some arg")
.required(false)
.default_value(default),
)
.try_get_matches_from(vec!["", "--opt", "value"]); .try_get_matches_from(vec!["", "--opt", "value"]);
assert!(r.is_ok(), "{}", r.unwrap_err()); assert!(r.is_ok(), "{}", r.unwrap_err());
let m = r.unwrap(); let m = r.unwrap();
@ -203,7 +182,7 @@ fn default_if_arg_present_no_default() {
#[test] #[test]
fn default_if_arg_present_no_default_user_override() { fn default_if_arg_present_no_default_user_override() {
let r = Command::new("df") let r = Command::new("df")
.arg(arg!(--opt <FILE> "some arg").required(false)) .arg(arg!(--opt <FILE> "some arg"))
.arg(arg!([arg] "some arg").default_value_if( .arg(arg!([arg] "some arg").default_value_if(
"opt", "opt",
ArgPredicate::IsPresent, ArgPredicate::IsPresent,
@ -222,7 +201,7 @@ fn default_if_arg_present_no_default_user_override() {
#[test] #[test]
fn default_if_arg_present_no_arg_with_default() { fn default_if_arg_present_no_arg_with_default() {
let r = Command::new("df") let r = Command::new("df")
.arg(arg!(--opt <FILE> "some arg").required(false)) .arg(arg!(--opt <FILE> "some arg"))
.arg( .arg(
arg!([arg] "some arg") arg!([arg] "some arg")
.default_value("first") .default_value("first")
@ -241,7 +220,7 @@ fn default_if_arg_present_no_arg_with_default() {
#[test] #[test]
fn default_if_arg_present_with_default() { fn default_if_arg_present_with_default() {
let r = Command::new("df") let r = Command::new("df")
.arg(arg!(--opt <FILE> "some arg").required(false)) .arg(arg!(--opt <FILE> "some arg"))
.arg( .arg(
arg!([arg] "some arg") arg!([arg] "some arg")
.default_value("first") .default_value("first")
@ -260,7 +239,7 @@ fn default_if_arg_present_with_default() {
#[test] #[test]
fn default_if_arg_present_with_default_user_override() { fn default_if_arg_present_with_default_user_override() {
let r = Command::new("df") let r = Command::new("df")
.arg(arg!(--opt <FILE> "some arg").required(false)) .arg(arg!(--opt <FILE> "some arg"))
.arg( .arg(
arg!([arg] "some arg") arg!([arg] "some arg")
.default_value("first") .default_value("first")
@ -279,7 +258,7 @@ fn default_if_arg_present_with_default_user_override() {
#[test] #[test]
fn default_if_arg_present_no_arg_with_default_user_override() { fn default_if_arg_present_no_arg_with_default_user_override() {
let r = Command::new("df") let r = Command::new("df")
.arg(arg!(--opt <FILE> "some arg").required(false)) .arg(arg!(--opt <FILE> "some arg"))
.arg( .arg(
arg!([arg] "some arg") arg!([arg] "some arg")
.default_value("first") .default_value("first")
@ -300,7 +279,7 @@ fn default_if_arg_present_no_arg_with_default_user_override() {
#[test] #[test]
fn default_if_arg_present_with_value_no_default() { fn default_if_arg_present_with_value_no_default() {
let r = Command::new("df") let r = Command::new("df")
.arg(arg!(--opt <FILE> "some arg").required(false)) .arg(arg!(--opt <FILE> "some arg"))
.arg(arg!([arg] "some arg").default_value_if("opt", "value", Some("default"))) .arg(arg!([arg] "some arg").default_value_if("opt", "value", Some("default")))
.try_get_matches_from(vec!["", "--opt", "value"]); .try_get_matches_from(vec!["", "--opt", "value"]);
assert!(r.is_ok(), "{}", r.unwrap_err()); assert!(r.is_ok(), "{}", r.unwrap_err());
@ -315,7 +294,7 @@ fn default_if_arg_present_with_value_no_default() {
#[test] #[test]
fn default_if_arg_present_with_value_no_default_fail() { fn default_if_arg_present_with_value_no_default_fail() {
let r = Command::new("df") let r = Command::new("df")
.arg(arg!(--opt <FILE> "some arg").required(false)) .arg(arg!(--opt <FILE> "some arg"))
.arg(arg!([arg] "some arg").default_value_if("opt", "value", Some("default"))) .arg(arg!([arg] "some arg").default_value_if("opt", "value", Some("default")))
.try_get_matches_from(vec!["", "--opt", "other"]); .try_get_matches_from(vec!["", "--opt", "other"]);
assert!(r.is_ok(), "{}", r.unwrap_err()); assert!(r.is_ok(), "{}", r.unwrap_err());
@ -327,7 +306,7 @@ fn default_if_arg_present_with_value_no_default_fail() {
#[test] #[test]
fn default_if_arg_present_with_value_no_default_user_override() { fn default_if_arg_present_with_value_no_default_user_override() {
let r = Command::new("df") let r = Command::new("df")
.arg(arg!(--opt <FILE> "some arg").required(false)) .arg(arg!(--opt <FILE> "some arg"))
.arg(arg!([arg] "some arg").default_value_if("opt", "some", Some("default"))) .arg(arg!([arg] "some arg").default_value_if("opt", "some", Some("default")))
.try_get_matches_from(vec!["", "--opt", "some", "other"]); .try_get_matches_from(vec!["", "--opt", "some", "other"]);
assert!(r.is_ok(), "{}", r.unwrap_err()); assert!(r.is_ok(), "{}", r.unwrap_err());
@ -342,7 +321,7 @@ fn default_if_arg_present_with_value_no_default_user_override() {
#[test] #[test]
fn default_if_arg_present_with_value_no_arg_with_default() { fn default_if_arg_present_with_value_no_arg_with_default() {
let r = Command::new("df") let r = Command::new("df")
.arg(arg!(--opt <FILE> "some arg").required(false)) .arg(arg!(--opt <FILE> "some arg"))
.arg( .arg(
arg!([arg] "some arg") arg!([arg] "some arg")
.default_value("first") .default_value("first")
@ -361,7 +340,7 @@ fn default_if_arg_present_with_value_no_arg_with_default() {
#[test] #[test]
fn default_if_arg_present_with_value_no_arg_with_default_fail() { fn default_if_arg_present_with_value_no_arg_with_default_fail() {
let r = Command::new("df") let r = Command::new("df")
.arg(arg!(--opt <FILE> "some arg").required(false)) .arg(arg!(--opt <FILE> "some arg"))
.arg( .arg(
arg!([arg] "some arg") arg!([arg] "some arg")
.default_value("first") .default_value("first")
@ -380,7 +359,7 @@ fn default_if_arg_present_with_value_no_arg_with_default_fail() {
#[test] #[test]
fn default_if_arg_present_with_value_with_default() { fn default_if_arg_present_with_value_with_default() {
let r = Command::new("df") let r = Command::new("df")
.arg(arg!(--opt <FILE> "some arg").required(false)) .arg(arg!(--opt <FILE> "some arg"))
.arg( .arg(
arg!([arg] "some arg") arg!([arg] "some arg")
.default_value("first") .default_value("first")
@ -399,7 +378,7 @@ fn default_if_arg_present_with_value_with_default() {
#[test] #[test]
fn default_if_arg_present_with_value_with_default_user_override() { fn default_if_arg_present_with_value_with_default_user_override() {
let r = Command::new("df") let r = Command::new("df")
.arg(arg!(--opt <FILE> "some arg").required(false)) .arg(arg!(--opt <FILE> "some arg"))
.arg( .arg(
arg!([arg] "some arg") arg!([arg] "some arg")
.default_value("first") .default_value("first")
@ -418,7 +397,7 @@ fn default_if_arg_present_with_value_with_default_user_override() {
#[test] #[test]
fn default_if_arg_present_no_arg_with_value_with_default_user_override() { fn default_if_arg_present_no_arg_with_value_with_default_user_override() {
let r = Command::new("df") let r = Command::new("df")
.arg(arg!(--opt <FILE> "some arg").required(false)) .arg(arg!(--opt <FILE> "some arg"))
.arg( .arg(
arg!([arg] "some arg") arg!([arg] "some arg")
.default_value("first") .default_value("first")
@ -437,7 +416,7 @@ fn default_if_arg_present_no_arg_with_value_with_default_user_override() {
#[test] #[test]
fn default_if_arg_present_no_arg_with_value_with_default_user_override_fail() { fn default_if_arg_present_no_arg_with_value_with_default_user_override_fail() {
let r = Command::new("df") let r = Command::new("df")
.arg(arg!(--opt <FILE> "some arg").required(false)) .arg(arg!(--opt <FILE> "some arg"))
.arg( .arg(
arg!([arg] "some arg") arg!([arg] "some arg")
.default_value("first") .default_value("first")
@ -458,7 +437,7 @@ fn default_if_arg_present_no_arg_with_value_with_default_user_override_fail() {
#[test] #[test]
fn no_default_if_arg_present_with_value_no_default() { fn no_default_if_arg_present_with_value_no_default() {
let r = Command::new("df") let r = Command::new("df")
.arg(arg!(--opt <FILE> "some arg").required(false)) .arg(arg!(--opt <FILE> "some arg"))
.arg(arg!([arg] "some arg").default_value_if("opt", "value", None)) .arg(arg!([arg] "some arg").default_value_if("opt", "value", None))
.try_get_matches_from(vec!["", "--opt", "value"]); .try_get_matches_from(vec!["", "--opt", "value"]);
assert!(r.is_ok(), "{}", r.unwrap_err()); assert!(r.is_ok(), "{}", r.unwrap_err());
@ -469,7 +448,7 @@ fn no_default_if_arg_present_with_value_no_default() {
#[test] #[test]
fn no_default_if_arg_present_with_value_with_default() { fn no_default_if_arg_present_with_value_with_default() {
let r = Command::new("df") let r = Command::new("df")
.arg(arg!(--opt <FILE> "some arg").required(false)) .arg(arg!(--opt <FILE> "some arg"))
.arg( .arg(
arg!([arg] "some arg") arg!([arg] "some arg")
.default_value("default") .default_value("default")
@ -485,7 +464,7 @@ fn no_default_if_arg_present_with_value_with_default() {
#[test] #[test]
fn no_default_if_arg_present_with_value_with_default_user_override() { fn no_default_if_arg_present_with_value_with_default_user_override() {
let r = Command::new("df") let r = Command::new("df")
.arg(arg!(--opt <FILE> "some arg").required(false)) .arg(arg!(--opt <FILE> "some arg"))
.arg( .arg(
arg!([arg] "some arg") arg!([arg] "some arg")
.default_value("default") .default_value("default")
@ -504,7 +483,7 @@ fn no_default_if_arg_present_with_value_with_default_user_override() {
#[test] #[test]
fn no_default_if_arg_present_no_arg_with_value_with_default() { fn no_default_if_arg_present_no_arg_with_value_with_default() {
let r = Command::new("df") let r = Command::new("df")
.arg(arg!(--opt <FILE> "some arg").required(false)) .arg(arg!(--opt <FILE> "some arg"))
.arg( .arg(
arg!([arg] "some arg") arg!([arg] "some arg")
.default_value("default") .default_value("default")
@ -525,7 +504,7 @@ fn no_default_if_arg_present_no_arg_with_value_with_default() {
#[test] #[test]
fn default_ifs_arg_present() { fn default_ifs_arg_present() {
let r = Command::new("df") let r = Command::new("df")
.arg(arg!(--opt <FILE> "some arg").required(false)) .arg(arg!(--opt <FILE> "some arg"))
.arg(arg!(--flag "some arg")) .arg(arg!(--flag "some arg"))
.arg( .arg(
arg!([arg] "some arg") arg!([arg] "some arg")
@ -548,7 +527,7 @@ fn default_ifs_arg_present() {
#[test] #[test]
fn no_default_ifs_arg_present() { fn no_default_ifs_arg_present() {
let r = Command::new("df") let r = Command::new("df")
.arg(arg!(--opt <FILE> "some arg").required(false)) .arg(arg!(--opt <FILE> "some arg"))
.arg(arg!(--flag "some arg")) .arg(arg!(--flag "some arg"))
.arg( .arg(
arg!([arg] "some arg") arg!([arg] "some arg")
@ -568,7 +547,7 @@ fn no_default_ifs_arg_present() {
#[test] #[test]
fn default_ifs_arg_present_user_override() { fn default_ifs_arg_present_user_override() {
let r = Command::new("df") let r = Command::new("df")
.arg(arg!(--opt <FILE> "some arg").required(false)) .arg(arg!(--opt <FILE> "some arg"))
.arg(arg!(--flag "some arg")) .arg(arg!(--flag "some arg"))
.arg( .arg(
arg!([arg] "some arg") arg!([arg] "some arg")
@ -591,7 +570,7 @@ fn default_ifs_arg_present_user_override() {
#[test] #[test]
fn default_ifs_arg_present_order() { fn default_ifs_arg_present_order() {
let r = Command::new("df") let r = Command::new("df")
.arg(arg!(--opt <FILE> "some arg").required(false)) .arg(arg!(--opt <FILE> "some arg"))
.arg(arg!(--flag "some arg")) .arg(arg!(--flag "some arg"))
.arg( .arg(
arg!([arg] "some arg") arg!([arg] "some arg")

View file

@ -55,11 +55,11 @@ fn propagate_global_arg_in_subcommand_to_subsubcommand_1385() {
fn propagate_global_arg_to_subcommand_in_subsubcommand_2053() { fn propagate_global_arg_to_subcommand_in_subsubcommand_2053() {
let m = Command::new("opts") let m = Command::new("opts")
.arg(arg!(--"global-flag").global(true)) .arg(arg!(--"global-flag").global(true))
.arg(arg!(--"global-str" <str>).required(false).global(true)) .arg(arg!(--"global-str" <str>).global(true))
.subcommand( .subcommand(
Command::new("test") Command::new("test")
.arg(arg!(--"sub-flag").global(true)) .arg(arg!(--"sub-flag").global(true))
.arg(arg!(--"sub-str" <str>).required(false).global(true)) .arg(arg!(--"sub-str" <str>).global(true))
.subcommand(Command::new("test")), .subcommand(Command::new("test")),
) )
.try_get_matches_from(&[ .try_get_matches_from(&[

View file

@ -84,7 +84,7 @@ fn arg_group_new_of_arg_name() {
fn group_single_value() { fn group_single_value() {
let res = Command::new("group") let res = Command::new("group")
.arg(arg!(-c --color [color] "some option")) .arg(arg!(-c --color [color] "some option"))
.arg(arg!(-n --hostname <name> "another option").required(false)) .arg(arg!(-n --hostname <name> "another option"))
.group(ArgGroup::new("grp").args(["hostname", "color"])) .group(ArgGroup::new("grp").args(["hostname", "color"]))
.try_get_matches_from(vec!["", "-c", "blue"]); .try_get_matches_from(vec!["", "-c", "blue"]);
assert!(res.is_ok(), "{}", res.unwrap_err()); assert!(res.is_ok(), "{}", res.unwrap_err());
@ -98,7 +98,7 @@ fn group_single_value() {
fn group_empty() { fn group_empty() {
let res = Command::new("group") let res = Command::new("group")
.arg(arg!(-c --color [color] "some option")) .arg(arg!(-c --color [color] "some option"))
.arg(arg!(-n --hostname <name> "another option").required(false)) .arg(arg!(-n --hostname <name> "another option"))
.group(ArgGroup::new("grp").args(["hostname", "color"])) .group(ArgGroup::new("grp").args(["hostname", "color"]))
.try_get_matches_from(vec![""]); .try_get_matches_from(vec![""]);
assert!(res.is_ok(), "{}", res.unwrap_err()); assert!(res.is_ok(), "{}", res.unwrap_err());
@ -112,7 +112,7 @@ fn group_empty() {
fn group_required_flags_empty() { fn group_required_flags_empty() {
let result = Command::new("group") let result = Command::new("group")
.arg(arg!(-c --color "some option")) .arg(arg!(-c --color "some option"))
.arg(arg!(-n --hostname <name> "another option").required(false)) .arg(arg!(-n --hostname <name> "another option"))
.group( .group(
ArgGroup::new("grp") ArgGroup::new("grp")
.required(true) .required(true)
@ -128,7 +128,7 @@ fn group_required_flags_empty() {
fn group_multi_value_single_arg() { fn group_multi_value_single_arg() {
let res = Command::new("group") let res = Command::new("group")
.arg(arg!(-c --color <color> "some option").num_args(1..)) .arg(arg!(-c --color <color> "some option").num_args(1..))
.arg(arg!(-n --hostname <name> "another option").required(false)) .arg(arg!(-n --hostname <name> "another option"))
.group(ArgGroup::new("grp").args(["hostname", "color"])) .group(ArgGroup::new("grp").args(["hostname", "color"]))
.try_get_matches_from(vec!["", "-c", "blue", "red", "green"]); .try_get_matches_from(vec!["", "-c", "blue", "red", "green"]);
assert!(res.is_ok(), "{:?}", res.unwrap_err().kind()); assert!(res.is_ok(), "{:?}", res.unwrap_err().kind());
@ -246,8 +246,8 @@ fn group_multiple_args_error() {
#[test] #[test]
fn group_overrides_required() { fn group_overrides_required() {
let command = Command::new("group") let command = Command::new("group")
.arg(arg!(--foo <FOO>)) .arg(arg!(--foo <FOO>).required(true))
.arg(arg!(--bar <BAR>)) .arg(arg!(--bar <BAR>).required(true))
.group(ArgGroup::new("group").args(["foo", "bar"]).required(true)); .group(ArgGroup::new("group").args(["foo", "bar"]).required(true));
let result = command.try_get_matches_from(vec!["group", "--foo", "value"]); let result = command.try_get_matches_from(vec!["group", "--foo", "value"]);
assert!(result.is_ok(), "{}", result.unwrap_err()); assert!(result.is_ok(), "{}", result.unwrap_err());

View file

@ -1063,7 +1063,7 @@ Options:
let cmd = Command::new("prog") let cmd = Command::new("prog")
.version("1.0") .version("1.0")
.subcommand_negates_reqs(true) .subcommand_negates_reqs(true)
.arg(arg!(-o --opt <FILE> "tests options")) .arg(arg!(-o --opt <FILE> "tests options").required(true))
.arg(Arg::new("PATH").help("help")) .arg(Arg::new("PATH").help("help"))
.subcommand(Command::new("test")); .subcommand(Command::new("test"));
utils::assert_output(cmd, "prog --help", SC_NEGATES_REQS, false); utils::assert_output(cmd, "prog --help", SC_NEGATES_REQS, false);
@ -1084,7 +1084,7 @@ Options:
let cmd = Command::new("prog") let cmd = Command::new("prog")
.version("1.0") .version("1.0")
.arg(arg!(-f --flag "testing flags")) .arg(arg!(-f --flag "testing flags"))
.arg(arg!(-o --opt <FILE> "tests options").required(false)) .arg(arg!(-o --opt <FILE> "tests options"))
.arg(Arg::new("pos").hide(true)); .arg(Arg::new("pos").hide(true));
utils::assert_output(cmd, "prog --help", HIDDEN_ARGS, false); utils::assert_output(cmd, "prog --help", HIDDEN_ARGS, false);
} }
@ -1113,7 +1113,7 @@ Options:
.version("1.0") .version("1.0")
.args_conflicts_with_subcommands(true) .args_conflicts_with_subcommands(true)
.arg(arg!(-f --flag "testing flags")) .arg(arg!(-f --flag "testing flags"))
.arg(arg!(-o --opt <FILE> "tests options").required(false)) .arg(arg!(-o --opt <FILE> "tests options"))
.arg(Arg::new("PATH").help("help")) .arg(Arg::new("PATH").help("help"))
.subcommand(Command::new("test")); .subcommand(Command::new("test"));
utils::assert_output(cmd, "prog --help", ARGS_NEGATE_SC, false); utils::assert_output(cmd, "prog --help", ARGS_NEGATE_SC, false);
@ -1137,7 +1137,7 @@ Options:
let cmd = Command::new("prog") let cmd = Command::new("prog")
.version("1.0") .version("1.0")
.arg(arg!(-f --flag "testing flags")) .arg(arg!(-f --flag "testing flags"))
.arg(arg!(-o --opt <FILE> "tests options").required(false)) .arg(arg!(-o --opt <FILE> "tests options"))
.arg(Arg::new("PATH").help("some")) .arg(Arg::new("PATH").help("some"))
.subcommand(Command::new("test").hide(true)); .subcommand(Command::new("test").hide(true));
utils::assert_output(cmd, "prog --help", ISSUE_1046_HIDDEN_SCS, false); utils::assert_output(cmd, "prog --help", ISSUE_1046_HIDDEN_SCS, false);
@ -1623,16 +1623,16 @@ fn multiple_custom_help_headers() {
.next_help_heading(Some("SPECIAL")) .next_help_heading(Some("SPECIAL"))
.arg( .arg(
arg!(-b --"birthday-song" <song> "Change which song is played for birthdays") arg!(-b --"birthday-song" <song> "Change which song is played for birthdays")
.required(true)
.help_heading(Some("OVERRIDE SPECIAL")), .help_heading(Some("OVERRIDE SPECIAL")),
) )
.arg(arg!(--style <style> "Choose musical style to play the song").help_heading(None))
.arg( .arg(
arg!(--style <style> "Choose musical style to play the song") arg!(
.required(false) -v --"birthday-song-volume" <volume> "Change the volume of the birthday song"
.help_heading(None), )
.required(true),
) )
.arg(arg!(
-v --"birthday-song-volume" <volume> "Change the volume of the birthday song"
))
.next_help_heading(None) .next_help_heading(None)
.arg( .arg(
Arg::new("server-addr") Arg::new("server-addr")
@ -1688,11 +1688,15 @@ fn custom_help_headers_hide_args() {
.next_help_heading(Some("SPECIAL")) .next_help_heading(Some("SPECIAL"))
.arg( .arg(
arg!(-b --song <song> "Change which song is played for birthdays") arg!(-b --song <song> "Change which song is played for birthdays")
.required(true)
.help_heading(Some("OVERRIDE SPECIAL")), .help_heading(Some("OVERRIDE SPECIAL")),
) )
.arg(arg!( .arg(
-v --"song-volume" <volume> "Change the volume of the birthday song" arg!(
)) -v --"song-volume" <volume> "Change the volume of the birthday song"
)
.required(true),
)
.next_help_heading(None) .next_help_heading(None)
.arg( .arg(
Arg::new("server-addr") Arg::new("server-addr")
@ -2225,7 +2229,7 @@ fn only_custom_heading_opts_no_args() {
.disable_help_flag(true) .disable_help_flag(true)
.arg(arg!(--help).action(ArgAction::Help).hide(true)) .arg(arg!(--help).action(ArgAction::Help).hide(true))
.next_help_heading(Some("NETWORKING")) .next_help_heading(Some("NETWORKING"))
.arg(arg!(-s --speed <SPEED> "How fast").required(false)); .arg(arg!(-s --speed <SPEED> "How fast"));
utils::assert_output(cmd, "test --help", ONLY_CUSTOM_HEADING_OPTS_NO_ARGS, false); utils::assert_output(cmd, "test --help", ONLY_CUSTOM_HEADING_OPTS_NO_ARGS, false);
} }
@ -2589,7 +2593,7 @@ Arguments:
#[test] #[test]
fn help_without_short() { fn help_without_short() {
let mut cmd = clap::Command::new("test") let mut cmd = clap::Command::new("test")
.arg(arg!(-h --hex <NUM>)) .arg(arg!(-h --hex <NUM>).required(true))
.arg(arg!(--help).action(ArgAction::Help)) .arg(arg!(--help).action(ArgAction::Help))
.disable_help_flag(true); .disable_help_flag(true);

View file

@ -23,7 +23,7 @@ fn hide_args() {
.args(&[ .args(&[
arg!(-f --flag "some flag").hide(true), arg!(-f --flag "some flag").hide(true),
arg!(-F --flag2 "some other flag"), arg!(-F --flag2 "some other flag"),
arg!(--option <opt> "some option").required(false), arg!(--option <opt> "some option"),
Arg::new("DUMMY").hide(true), Arg::new("DUMMY").hide(true),
]); ]);
utils::assert_output(cmd, "test --help", HIDDEN_ARGS, false); utils::assert_output(cmd, "test --help", HIDDEN_ARGS, false);
@ -234,11 +234,7 @@ fn hide_opt_args_only() {
.disable_version_flag(true) .disable_version_flag(true)
.arg(arg!(-h - -help).action(ArgAction::Help).hide(true)) .arg(arg!(-h - -help).action(ArgAction::Help).hide(true))
.arg(arg!(-v - -version).hide(true)) .arg(arg!(-v - -version).hide(true))
.arg( .arg(arg!(--option <opt> "some option").hide(true));
arg!(--option <opt> "some option")
.required(false)
.hide(true),
);
utils::assert_output(cmd, "test --help", HIDDEN_OPT_ARGS_ONLY, false); utils::assert_output(cmd, "test --help", HIDDEN_OPT_ARGS_ONLY, false);
} }

View file

@ -174,7 +174,7 @@ fn opts_using_short() {
#[test] #[test]
fn lots_o_vals() { fn lots_o_vals() {
let r = Command::new("opts") let r = Command::new("opts")
.arg(arg!(o: -o <opt> "some opt").num_args(1..)) .arg(arg!(o: -o <opt> "some opt").num_args(1..).required(true))
.try_get_matches_from(vec![ .try_get_matches_from(vec![
"", "-o", "some", "some", "some", "some", "some", "some", "some", "some", "some", "", "-o", "some", "some", "some", "some", "some", "some", "some", "some", "some",
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
@ -344,7 +344,11 @@ fn require_delims_no_delim() {
#[test] #[test]
fn require_delims() { fn require_delims() {
let r = Command::new("mvae") let r = Command::new("mvae")
.arg(arg!(o: -o <opt> "some opt").value_delimiter(',')) .arg(
arg!(o: -o <opt> "some opt")
.value_delimiter(',')
.required(true),
)
.arg(arg!([file] "some file")) .arg(arg!([file] "some file"))
.try_get_matches_from(vec!["", "-o", "1,2", "some"]); .try_get_matches_from(vec!["", "-o", "1,2", "some"]);
assert!(r.is_ok(), "{}", r.unwrap_err()); assert!(r.is_ok(), "{}", r.unwrap_err());
@ -369,6 +373,7 @@ fn leading_hyphen_pass() {
let r = Command::new("mvae") let r = Command::new("mvae")
.arg( .arg(
arg!(o: -o <opt> "some opt") arg!(o: -o <opt> "some opt")
.required(true)
.num_args(1..) .num_args(1..)
.allow_hyphen_values(true), .allow_hyphen_values(true),
) )
@ -388,7 +393,7 @@ fn leading_hyphen_pass() {
#[test] #[test]
fn leading_hyphen_fail() { fn leading_hyphen_fail() {
let r = Command::new("mvae") let r = Command::new("mvae")
.arg(arg!(o: -o <opt> "some opt")) .arg(arg!(o: -o <opt> "some opt").required(true))
.try_get_matches_from(vec!["", "-o", "-2"]); .try_get_matches_from(vec!["", "-o", "-2"]);
assert!(r.is_err()); assert!(r.is_err());
let m = r.unwrap_err(); let m = r.unwrap_err();
@ -400,6 +405,7 @@ fn leading_hyphen_with_flag_after() {
let r = Command::new("mvae") let r = Command::new("mvae")
.arg( .arg(
arg!(o: -o <opt> "some opt") arg!(o: -o <opt> "some opt")
.required(true)
.num_args(1..) .num_args(1..)
.allow_hyphen_values(true), .allow_hyphen_values(true),
) )
@ -488,7 +494,7 @@ fn issue_1047_min_zero_vals_default_val() {
fn issue_1105_setup(argv: Vec<&'static str>) -> Result<ArgMatches, clap::Error> { fn issue_1105_setup(argv: Vec<&'static str>) -> Result<ArgMatches, clap::Error> {
Command::new("opts") Command::new("opts")
.arg(arg!(-o --option <opt> "some option")) .arg(arg!(-o --option <opt> "some option").required(true))
.arg(arg!(--flag "some flag")) .arg(arg!(--flag "some flag"))
.try_get_matches_from(argv) .try_get_matches_from(argv)
} }
@ -572,7 +578,7 @@ fn issue_1073_suboptimal_flag_suggestion() {
#[test] #[test]
fn short_non_ascii_no_space() { fn short_non_ascii_no_space() {
let matches = Command::new("cmd") let matches = Command::new("cmd")
.arg(arg!(opt: -'磨' <opt>)) .arg(arg!(opt: -'磨' <opt>).required(true))
.try_get_matches_from(&["test", "-磨VALUE"]) .try_get_matches_from(&["test", "-磨VALUE"])
.unwrap(); .unwrap();
@ -588,7 +594,7 @@ fn short_non_ascii_no_space() {
#[test] #[test]
fn short_eq_val_starts_with_eq() { fn short_eq_val_starts_with_eq() {
let matches = Command::new("cmd") let matches = Command::new("cmd")
.arg(arg!(opt: -f <opt>)) .arg(arg!(opt: -f <opt>).required(true))
.try_get_matches_from(&["test", "-f==value"]) .try_get_matches_from(&["test", "-f==value"])
.unwrap(); .unwrap();
@ -604,7 +610,7 @@ fn short_eq_val_starts_with_eq() {
#[test] #[test]
fn long_eq_val_starts_with_eq() { fn long_eq_val_starts_with_eq() {
let matches = Command::new("cmd") let matches = Command::new("cmd")
.arg(arg!(opt: --foo <opt>)) .arg(arg!(opt: --foo <opt>).required(true))
.try_get_matches_from(&["test", "--foo==value"]) .try_get_matches_from(&["test", "--foo==value"])
.unwrap(); .unwrap();

View file

@ -76,12 +76,8 @@ fn posix_compatible_flags_short_rev() {
#[test] #[test]
fn posix_compatible_opts_long() { fn posix_compatible_opts_long() {
let m = Command::new("posix") let m = Command::new("posix")
.arg( .arg(arg!(--flag <flag> "some flag").overrides_with("color"))
arg!(--flag <flag> "some flag") .arg(arg!(--color <color> "some other flag"))
.required(false)
.overrides_with("color"),
)
.arg(arg!(--color <color> "some other flag").required(false))
.try_get_matches_from(vec!["", "--flag", "some", "--color", "other"]) .try_get_matches_from(vec!["", "--flag", "some", "--color", "other"])
.unwrap(); .unwrap();
assert!(m.contains_id("color")); assert!(m.contains_id("color"));
@ -95,12 +91,8 @@ fn posix_compatible_opts_long() {
#[test] #[test]
fn posix_compatible_opts_long_rev() { fn posix_compatible_opts_long_rev() {
let m = Command::new("posix") let m = Command::new("posix")
.arg( .arg(arg!(--flag <flag> "some flag").overrides_with("color"))
arg!(--flag <flag> "some flag") .arg(arg!(--color <color> "some other flag"))
.required(false)
.overrides_with("color"),
)
.arg(arg!(--color <color> "some other flag").required(false))
.try_get_matches_from(vec!["", "--color", "some", "--flag", "other"]) .try_get_matches_from(vec!["", "--color", "some", "--flag", "other"])
.unwrap(); .unwrap();
assert!(!m.contains_id("color")); assert!(!m.contains_id("color"));
@ -114,12 +106,8 @@ fn posix_compatible_opts_long_rev() {
#[test] #[test]
fn posix_compatible_opts_long_equals() { fn posix_compatible_opts_long_equals() {
let m = Command::new("posix") let m = Command::new("posix")
.arg( .arg(arg!(--flag <flag> "some flag").overrides_with("color"))
arg!(--flag <flag> "some flag") .arg(arg!(--color <color> "some other flag"))
.required(false)
.overrides_with("color"),
)
.arg(arg!(--color <color> "some other flag").required(false))
.try_get_matches_from(vec!["", "--flag=some", "--color=other"]) .try_get_matches_from(vec!["", "--flag=some", "--color=other"])
.unwrap(); .unwrap();
assert!(m.contains_id("color")); assert!(m.contains_id("color"));
@ -133,12 +121,8 @@ fn posix_compatible_opts_long_equals() {
#[test] #[test]
fn posix_compatible_opts_long_equals_rev() { fn posix_compatible_opts_long_equals_rev() {
let m = Command::new("posix") let m = Command::new("posix")
.arg( .arg(arg!(--flag <flag> "some flag").overrides_with("color"))
arg!(--flag <flag> "some flag") .arg(arg!(--color <color> "some other flag"))
.required(false)
.overrides_with("color"),
)
.arg(arg!(--color <color> "some other flag").required(false))
.try_get_matches_from(vec!["", "--color=some", "--flag=other"]) .try_get_matches_from(vec!["", "--color=some", "--flag=other"])
.unwrap(); .unwrap();
assert!(!m.contains_id("color")); assert!(!m.contains_id("color"));
@ -152,12 +136,8 @@ fn posix_compatible_opts_long_equals_rev() {
#[test] #[test]
fn posix_compatible_opts_short() { fn posix_compatible_opts_short() {
let m = Command::new("posix") let m = Command::new("posix")
.arg( .arg(arg!(f: -f <flag> "some flag").overrides_with("c"))
arg!(f: -f <flag> "some flag") .arg(arg!(c: -c <color> "some other flag"))
.required(false)
.overrides_with("c"),
)
.arg(arg!(c: -c <color> "some other flag").required(false))
.try_get_matches_from(vec!["", "-f", "some", "-c", "other"]) .try_get_matches_from(vec!["", "-f", "some", "-c", "other"])
.unwrap(); .unwrap();
assert!(m.contains_id("c")); assert!(m.contains_id("c"));
@ -171,12 +151,8 @@ fn posix_compatible_opts_short() {
#[test] #[test]
fn posix_compatible_opts_short_rev() { fn posix_compatible_opts_short_rev() {
let m = Command::new("posix") let m = Command::new("posix")
.arg( .arg(arg!(f: -f <flag> "some flag").overrides_with("c"))
arg!(f: -f <flag> "some flag") .arg(arg!(c: -c <color> "some other flag"))
.required(false)
.overrides_with("c"),
)
.arg(arg!(c: -c <color> "some other flag").required(false))
.try_get_matches_from(vec!["", "-c", "some", "-f", "other"]) .try_get_matches_from(vec!["", "-c", "some", "-f", "other"])
.unwrap(); .unwrap();
assert!(!m.contains_id("c")); assert!(!m.contains_id("c"));
@ -323,7 +299,7 @@ fn require_overridden_4() {
#[test] #[test]
fn incremental_override() { fn incremental_override() {
let mut cmd = Command::new("test") let mut cmd = Command::new("test")
.arg(arg!(--name <NAME>).action(ArgAction::Append)) .arg(arg!(--name <NAME> ...).required(true))
.arg( .arg(
arg!(--"no-name") arg!(--"no-name")
.overrides_with("name") .overrides_with("name")

View file

@ -79,8 +79,8 @@ fn flag_required_2() {
#[test] #[test]
fn option_required() { fn option_required() {
let result = Command::new("option_required") let result = Command::new("option_required")
.arg(arg!(f: -f <flag> "some flag").required(false).requires("c")) .arg(arg!(f: -f <flag> "some flag").requires("c"))
.arg(arg!(c: -c <color> "third flag").required(false)) .arg(arg!(c: -c <color> "third flag"))
.try_get_matches_from(vec!["", "-f", "val"]); .try_get_matches_from(vec!["", "-f", "val"]);
assert!(result.is_err()); assert!(result.is_err());
let err = result.err().unwrap(); let err = result.err().unwrap();
@ -90,8 +90,8 @@ fn option_required() {
#[test] #[test]
fn option_required_2() { fn option_required_2() {
let m = Command::new("option_required") let m = Command::new("option_required")
.arg(arg!(f: -f <flag> "some flag").required(false).requires("c")) .arg(arg!(f: -f <flag> "some flag").requires("c"))
.arg(arg!(c: -c <color> "third flag").required(false)) .arg(arg!(c: -c <color> "third flag"))
.try_get_matches_from(vec!["", "-f", "val", "-c", "other_val"]) .try_get_matches_from(vec!["", "-f", "val", "-c", "other_val"])
.unwrap(); .unwrap();
assert!(m.contains_id("c")); assert!(m.contains_id("c"));
@ -295,15 +295,10 @@ fn issue_753() {
) )
.arg( .arg(
arg!(-f --file <TESTFILE> "Fetch NTP packets from pcap file") arg!(-f --file <TESTFILE> "Fetch NTP packets from pcap file")
.required(false)
.conflicts_with("iface") .conflicts_with("iface")
.required_unless_present("list"), .required_unless_present("list"),
) )
.arg( .arg(arg!(-s --server <SERVER_IP> "NTP server IP address").required_unless_present("list"))
arg!(-s --server <SERVER_IP> "NTP server IP address")
.required(false)
.required_unless_present("list"),
)
.try_get_matches_from(vec!["test", "--list"]); .try_get_matches_from(vec!["test", "--list"]);
assert!(m.is_ok(), "{}", m.unwrap_err()); assert!(m.is_ok(), "{}", m.unwrap_err());
} }
@ -1040,7 +1035,6 @@ fn issue_1158_app() -> Command {
Command::new("example") Command::new("example")
.arg( .arg(
arg!(-c --config <FILE> "Custom config file.") arg!(-c --config <FILE> "Custom config file.")
.required(false)
.required_unless_present("ID") .required_unless_present("ID")
.conflicts_with("ID"), .conflicts_with("ID"),
) )
@ -1054,9 +1048,9 @@ fn issue_1158_app() -> Command {
(ArgPredicate::IsPresent, "z"), (ArgPredicate::IsPresent, "z"),
]), ]),
) )
.arg(arg!(x: -x <X> "X").required(false)) .arg(arg!(x: -x <X> "X"))
.arg(arg!(y: -y <Y> "Y").required(false)) .arg(arg!(y: -y <Y> "Y"))
.arg(arg!(z: -z <Z> "Z").required(false)) .arg(arg!(z: -z <Z> "Z"))
} }
#[test] #[test]

View file

@ -183,9 +183,8 @@ Usage: dym [COMMAND]
For more information try --help For more information try --help
"; ";
let cmd = Command::new("dym").subcommand( let cmd = Command::new("dym")
Command::new("subcmd").arg(arg!(-s --subcmdarg <subcmdarg> "tests").required(false)), .subcommand(Command::new("subcmd").arg(arg!(-s --subcmdarg <subcmdarg> "tests")));
);
utils::assert_output(cmd, "dym --subcmarg subcmd", EXPECTED, true); utils::assert_output(cmd, "dym --subcmarg subcmd", EXPECTED, true);
} }
@ -203,9 +202,8 @@ Usage: dym [COMMAND]
For more information try --help For more information try --help
"; ";
let cmd = Command::new("dym").subcommand( let cmd = Command::new("dym")
Command::new("subcmd").arg(arg!(-s --subcmdarg <subcmdarg> "tests").required(false)), .subcommand(Command::new("subcmd").arg(arg!(-s --subcmdarg <subcmdarg> "tests")));
);
utils::assert_output(cmd, "dym --subcmarg foo", EXPECTED, true); utils::assert_output(cmd, "dym --subcmarg foo", EXPECTED, true);
} }
@ -260,7 +258,7 @@ fn replace() {
#[test] #[test]
fn issue_1031_args_with_same_name() { fn issue_1031_args_with_same_name() {
let res = Command::new("prog") let res = Command::new("prog")
.arg(arg!(--"ui-path" <PATH>)) .arg(arg!(--"ui-path" <PATH>).required(true))
.subcommand(Command::new("signer")) .subcommand(Command::new("signer"))
.try_get_matches_from(vec!["prog", "--ui-path", "signer"]); .try_get_matches_from(vec!["prog", "--ui-path", "signer"]);
@ -275,7 +273,7 @@ fn issue_1031_args_with_same_name() {
#[test] #[test]
fn issue_1031_args_with_same_name_no_more_vals() { fn issue_1031_args_with_same_name_no_more_vals() {
let res = Command::new("prog") let res = Command::new("prog")
.arg(arg!(--"ui-path" <PATH>)) .arg(arg!(--"ui-path" <PATH>).required(true))
.subcommand(Command::new("signer")) .subcommand(Command::new("signer"))
.try_get_matches_from(vec!["prog", "--ui-path", "value", "signer"]); .try_get_matches_from(vec!["prog", "--ui-path", "value", "signer"]);

View file

@ -72,33 +72,21 @@ pub fn complex_app() -> Command {
.requires("long-option-2") .requires("long-option-2")
.action(ArgAction::SetTrue), .action(ArgAction::SetTrue),
arg!(--"long-option-2" <option2> "tests long options with exclusions") arg!(--"long-option-2" <option2> "tests long options with exclusions")
.required(false)
.conflicts_with("option") .conflicts_with("option")
.requires("positional2"), .requires("positional2"),
arg!([positional2] "tests positionals with exclusions"), arg!([positional2] "tests positionals with exclusions"),
arg!(-O --option3 <option3> "specific vals") arg!(-O --option3 <option3> "specific vals").value_parser(opt3_vals),
.required(false)
.value_parser(opt3_vals),
arg!([positional3] ... "tests specific values").value_parser(pos3_vals), arg!([positional3] ... "tests specific values").value_parser(pos3_vals),
arg!(--multvals <val> "Tests multiple values, not mult occs") arg!(--multvals <val> "Tests multiple values, not mult occs")
.value_names(["one", "two"]) .value_names(["one", "two"]),
.required(false),
arg!(--multvalsmo <val> ... "Tests multiple values, and mult occs") arg!(--multvalsmo <val> ... "Tests multiple values, and mult occs")
.value_names(["one", "two"]) .value_names(["one", "two"]),
.required(false), arg!(--minvals2 <minvals> "Tests 2 min vals").num_args(2..),
arg!(--minvals2 <minvals> "Tests 2 min vals") arg!(--maxvals3 <maxvals> "Tests 3 max vals").num_args(1..=3),
.required(false)
.num_args(2..),
arg!(--maxvals3 <maxvals> "Tests 3 max vals")
.required(false)
.num_args(1..=3),
arg!(--optvaleq <optval> "Tests optional value, require = sign") arg!(--optvaleq <optval> "Tests optional value, require = sign")
.required(false)
.num_args(0..=1) .num_args(0..=1)
.require_equals(true), .require_equals(true),
arg!(--optvalnoeq <optval> "Tests optional value") arg!(--optvalnoeq <optval> "Tests optional value").num_args(0..=1),
.required(false)
.num_args(0..=1),
]) ])
.subcommand( .subcommand(
Command::new("subcmd") Command::new("subcmd")
@ -106,12 +94,8 @@ pub fn complex_app() -> Command {
.version("0.1") .version("0.1")
.author("Kevin K. <kbknapp@gmail.com>") .author("Kevin K. <kbknapp@gmail.com>")
.help_template(FULL_TEMPLATE) .help_template(FULL_TEMPLATE)
.arg( .arg(arg!(-o --option <scoption> "tests options").num_args(1..))
arg!(-o --option <scoption> "tests options") .arg(arg!(-s --subcmdarg <subcmdarg> "tests other args"))
.required(false)
.num_args(1..),
)
.arg(arg!(-s --subcmdarg <subcmdarg> "tests other args").required(false))
.arg(arg!([scpositional] "tests positionals")), .arg(arg!([scpositional] "tests positionals")),
) )
} }

View file

@ -5,7 +5,7 @@ mod arg {
assert_eq!(arg.get_id(), "foo"); assert_eq!(arg.get_id(), "foo");
assert_eq!(arg.get_long(), Some("bar")); assert_eq!(arg.get_long(), Some("bar"));
assert_eq!(arg.get_value_names(), Some(vec!["NUM".into()].as_slice())); assert_eq!(arg.get_value_names(), Some(vec!["NUM".into()].as_slice()));
assert!(arg.is_required_set()); assert!(!arg.is_required_set());
} }
#[test] #[test]
@ -14,7 +14,7 @@ mod arg {
assert_eq!(arg.get_id(), "bar"); assert_eq!(arg.get_id(), "bar");
assert_eq!(arg.get_long(), Some("bar")); assert_eq!(arg.get_long(), Some("bar"));
assert_eq!(arg.get_value_names(), Some(vec!["NUM".into()].as_slice())); assert_eq!(arg.get_value_names(), Some(vec!["NUM".into()].as_slice()));
assert!(arg.is_required_set()); assert!(!arg.is_required_set());
} }
#[test] #[test]
@ -191,7 +191,7 @@ mod arg {
assert_eq!(arg.get_short(), Some('b')); assert_eq!(arg.get_short(), Some('b'));
assert!(matches!(arg.get_action(), clap::ArgAction::Set)); assert!(matches!(arg.get_action(), clap::ArgAction::Set));
assert_eq!(arg.get_num_args(), None); assert_eq!(arg.get_num_args(), None);
assert!(arg.is_required_set()); assert!(!arg.is_required_set());
assert_eq!(arg.get_help().map(|s| s.to_string()), None); assert_eq!(arg.get_help().map(|s| s.to_string()), None);
let arg = clap::arg!(foo: -'b' <NUM>); let arg = clap::arg!(foo: -'b' <NUM>);
@ -199,7 +199,7 @@ mod arg {
assert_eq!(arg.get_short(), Some('b')); assert_eq!(arg.get_short(), Some('b'));
assert!(matches!(arg.get_action(), clap::ArgAction::Set)); assert!(matches!(arg.get_action(), clap::ArgAction::Set));
assert_eq!(arg.get_num_args(), None); assert_eq!(arg.get_num_args(), None);
assert!(arg.is_required_set()); assert!(!arg.is_required_set());
assert_eq!(arg.get_help().map(|s| s.to_string()), None); assert_eq!(arg.get_help().map(|s| s.to_string()), None);
let arg = clap::arg!(foo: -b <NUM> ...); let arg = clap::arg!(foo: -b <NUM> ...);
@ -207,7 +207,7 @@ mod arg {
assert_eq!(arg.get_short(), Some('b')); assert_eq!(arg.get_short(), Some('b'));
assert!(matches!(arg.get_action(), clap::ArgAction::Append)); assert!(matches!(arg.get_action(), clap::ArgAction::Append));
assert_eq!(arg.get_num_args(), None); assert_eq!(arg.get_num_args(), None);
assert!(arg.is_required_set()); assert!(!arg.is_required_set());
assert_eq!(arg.get_help().map(|s| s.to_string()), None); assert_eq!(arg.get_help().map(|s| s.to_string()), None);
let arg = clap::arg!(foo: -b <NUM> "How to use it"); let arg = clap::arg!(foo: -b <NUM> "How to use it");
@ -215,7 +215,7 @@ mod arg {
assert_eq!(arg.get_short(), Some('b')); assert_eq!(arg.get_short(), Some('b'));
assert!(matches!(arg.get_action(), clap::ArgAction::Set)); assert!(matches!(arg.get_action(), clap::ArgAction::Set));
assert_eq!(arg.get_num_args(), None); assert_eq!(arg.get_num_args(), None);
assert!(arg.is_required_set()); assert!(!arg.is_required_set());
assert_eq!( assert_eq!(
arg.get_help().map(|s| s.to_string()), arg.get_help().map(|s| s.to_string()),
Some("How to use it".to_owned()) Some("How to use it".to_owned())