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)
- `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`
- `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)* 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)

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -36,7 +36,7 @@ use crate::util::Id;
/// ```rust
/// # use clap::{Command, arg, ArgGroup, error::ErrorKind};
/// 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!(--minor "auto increase minor"))
/// .arg(arg!(--patch "auto increase patch"))
@ -54,7 +54,7 @@ use crate::util::Id;
/// ```rust
/// # use clap::{Command, arg, ArgGroup, Id};
/// 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!(--minor "auto increase minor"))
/// .arg(arg!(--patch "auto increase patch"))

View file

@ -923,8 +923,8 @@ impl Command {
/// # use clap::{Command, arg};
/// let cmd = Command::new("cmd")
/// .ignore_errors(true)
/// .arg(arg!(-c --config <FILE> "Sets a custom config file").required(false))
/// .arg(arg!(-x --stuff <FILE> "Sets a custom stuff file").required(false))
/// .arg(arg!(-c --config <FILE> "Sets a custom config file"))
/// .arg(arg!(-x --stuff <FILE> "Sets a custom stuff file"))
/// .arg(arg!(f: -f "Flag"));
///
/// 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;
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 };
if arg.get_id() == "" {
@ -322,7 +324,9 @@ macro_rules! arg_impl {
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 };
if arg.get_id() == "" {

View file

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

View file

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

View file

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

View file

@ -49,12 +49,8 @@ fn exclusive_flag() {
#[test]
fn exclusive_option() {
let result = Command::new("flag_conflict")
.arg(
arg!(-f --flag <VALUE> "some flag")
.required(false)
.exclusive(true),
)
.arg(arg!(-o --other <VALUE> "some flag").required(false))
.arg(arg!(-f --flag <VALUE> "some flag").exclusive(true))
.arg(arg!(-o --other <VALUE> "some flag"))
.try_get_matches_from(vec!["myprog", "-o=val1", "-f=val2"]);
assert!(result.is_err());
let err = result.err().unwrap();
@ -64,11 +60,7 @@ fn exclusive_option() {
#[test]
fn not_exclusive_with_defaults() {
let result = Command::new("flag_conflict")
.arg(
arg!(-f --flag <VALUE> "some flag")
.required(false)
.exclusive(true),
)
.arg(arg!(-f --flag <VALUE> "some flag").exclusive(true))
.arg(
arg!(-o --other <VALUE> "some flag")
.required(false)
@ -83,15 +75,10 @@ fn default_doesnt_activate_exclusive() {
let result = Command::new("flag_conflict")
.arg(
arg!(-f --flag <VALUE> "some flag")
.required(false)
.exclusive(true)
.default_value("val2"),
)
.arg(
arg!(-o --other <VALUE> "some flag")
.required(false)
.default_value("val1"),
)
.arg(arg!(-o --other <VALUE> "some flag").default_value("val1"))
.try_get_matches_from(vec!["myprog"]);
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")
.arg(clap::arg!(-f --flag "some flag").conflicts_with("gr"))
.group(clap::ArgGroup::new("gr").multiple(true))
.arg(
clap::arg!(--some <name> "some arg")
.required(false)
.group("gr"),
)
.arg(clap::arg!(--some <name> "some arg").group("gr"))
.arg(
clap::arg!(--other <secs> "other arg")
.required(false)
.default_value("1000")
.group("gr"),
);
@ -480,11 +462,7 @@ fn conflicts_with_invalid_arg() {
#[test]
fn conflict_with_unused_default() {
let result = Command::new("conflict")
.arg(
arg!(-o --opt <opt> "some opt")
.required(false)
.default_value("default"),
)
.arg(arg!(-o --opt <opt> "some opt").default_value("default"))
.arg(
arg!(-f --flag "some flag")
.conflicts_with("opt")
@ -508,7 +486,6 @@ fn conflicts_with_alongside_default() {
.arg(
arg!(-o --opt <opt> "some opt")
.default_value("default")
.required(false)
.conflicts_with("flag"),
)
.arg(arg!(-f --flag "some flag").action(ArgAction::SetTrue))
@ -644,7 +621,7 @@ fn subcommand_conflict_negates_required() {
let cmd = Command::new("test")
.args_conflicts_with_subcommands(true)
.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"]);
assert!(

View file

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

View file

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

View file

@ -1063,7 +1063,7 @@ Options:
let cmd = Command::new("prog")
.version("1.0")
.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"))
.subcommand(Command::new("test"));
utils::assert_output(cmd, "prog --help", SC_NEGATES_REQS, false);
@ -1084,7 +1084,7 @@ Options:
let cmd = Command::new("prog")
.version("1.0")
.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));
utils::assert_output(cmd, "prog --help", HIDDEN_ARGS, false);
}
@ -1113,7 +1113,7 @@ Options:
.version("1.0")
.args_conflicts_with_subcommands(true)
.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"))
.subcommand(Command::new("test"));
utils::assert_output(cmd, "prog --help", ARGS_NEGATE_SC, false);
@ -1137,7 +1137,7 @@ Options:
let cmd = Command::new("prog")
.version("1.0")
.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"))
.subcommand(Command::new("test").hide(true));
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"))
.arg(
arg!(-b --"birthday-song" <song> "Change which song is played for birthdays")
.required(true)
.help_heading(Some("OVERRIDE SPECIAL")),
)
.arg(arg!(--style <style> "Choose musical style to play the song").help_heading(None))
.arg(
arg!(--style <style> "Choose musical style to play the song")
.required(false)
.help_heading(None),
arg!(
-v --"birthday-song-volume" <volume> "Change the volume of the birthday song"
)
.required(true),
)
.arg(arg!(
-v --"birthday-song-volume" <volume> "Change the volume of the birthday song"
))
.next_help_heading(None)
.arg(
Arg::new("server-addr")
@ -1688,11 +1688,15 @@ fn custom_help_headers_hide_args() {
.next_help_heading(Some("SPECIAL"))
.arg(
arg!(-b --song <song> "Change which song is played for birthdays")
.required(true)
.help_heading(Some("OVERRIDE SPECIAL")),
)
.arg(arg!(
-v --"song-volume" <volume> "Change the volume of the birthday song"
))
.arg(
arg!(
-v --"song-volume" <volume> "Change the volume of the birthday song"
)
.required(true),
)
.next_help_heading(None)
.arg(
Arg::new("server-addr")
@ -2225,7 +2229,7 @@ fn only_custom_heading_opts_no_args() {
.disable_help_flag(true)
.arg(arg!(--help).action(ArgAction::Help).hide(true))
.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);
}
@ -2589,7 +2593,7 @@ Arguments:
#[test]
fn help_without_short() {
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))
.disable_help_flag(true);

View file

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

View file

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

View file

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

View file

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

View file

@ -183,9 +183,8 @@ Usage: dym [COMMAND]
For more information try --help
";
let cmd = Command::new("dym").subcommand(
Command::new("subcmd").arg(arg!(-s --subcmdarg <subcmdarg> "tests").required(false)),
);
let cmd = Command::new("dym")
.subcommand(Command::new("subcmd").arg(arg!(-s --subcmdarg <subcmdarg> "tests")));
utils::assert_output(cmd, "dym --subcmarg subcmd", EXPECTED, true);
}
@ -203,9 +202,8 @@ Usage: dym [COMMAND]
For more information try --help
";
let cmd = Command::new("dym").subcommand(
Command::new("subcmd").arg(arg!(-s --subcmdarg <subcmdarg> "tests").required(false)),
);
let cmd = Command::new("dym")
.subcommand(Command::new("subcmd").arg(arg!(-s --subcmdarg <subcmdarg> "tests")));
utils::assert_output(cmd, "dym --subcmarg foo", EXPECTED, true);
}
@ -260,7 +258,7 @@ fn replace() {
#[test]
fn issue_1031_args_with_same_name() {
let res = Command::new("prog")
.arg(arg!(--"ui-path" <PATH>))
.arg(arg!(--"ui-path" <PATH>).required(true))
.subcommand(Command::new("signer"))
.try_get_matches_from(vec!["prog", "--ui-path", "signer"]);
@ -275,7 +273,7 @@ fn issue_1031_args_with_same_name() {
#[test]
fn issue_1031_args_with_same_name_no_more_vals() {
let res = Command::new("prog")
.arg(arg!(--"ui-path" <PATH>))
.arg(arg!(--"ui-path" <PATH>).required(true))
.subcommand(Command::new("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")
.action(ArgAction::SetTrue),
arg!(--"long-option-2" <option2> "tests long options with exclusions")
.required(false)
.conflicts_with("option")
.requires("positional2"),
arg!([positional2] "tests positionals with exclusions"),
arg!(-O --option3 <option3> "specific vals")
.required(false)
.value_parser(opt3_vals),
arg!(-O --option3 <option3> "specific vals").value_parser(opt3_vals),
arg!([positional3] ... "tests specific values").value_parser(pos3_vals),
arg!(--multvals <val> "Tests multiple values, not mult occs")
.value_names(["one", "two"])
.required(false),
.value_names(["one", "two"]),
arg!(--multvalsmo <val> ... "Tests multiple values, and mult occs")
.value_names(["one", "two"])
.required(false),
arg!(--minvals2 <minvals> "Tests 2 min vals")
.required(false)
.num_args(2..),
arg!(--maxvals3 <maxvals> "Tests 3 max vals")
.required(false)
.num_args(1..=3),
.value_names(["one", "two"]),
arg!(--minvals2 <minvals> "Tests 2 min vals").num_args(2..),
arg!(--maxvals3 <maxvals> "Tests 3 max vals").num_args(1..=3),
arg!(--optvaleq <optval> "Tests optional value, require = sign")
.required(false)
.num_args(0..=1)
.require_equals(true),
arg!(--optvalnoeq <optval> "Tests optional value")
.required(false)
.num_args(0..=1),
arg!(--optvalnoeq <optval> "Tests optional value").num_args(0..=1),
])
.subcommand(
Command::new("subcmd")
@ -106,12 +94,8 @@ pub fn complex_app() -> Command {
.version("0.1")
.author("Kevin K. <kbknapp@gmail.com>")
.help_template(FULL_TEMPLATE)
.arg(
arg!(-o --option <scoption> "tests options")
.required(false)
.num_args(1..),
)
.arg(arg!(-s --subcmdarg <subcmdarg> "tests other args").required(false))
.arg(arg!(-o --option <scoption> "tests options").num_args(1..))
.arg(arg!(-s --subcmdarg <subcmdarg> "tests other args"))
.arg(arg!([scpositional] "tests positionals")),
)
}

View file

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