From c9eef442134de634e988436cd59da41519dc5285 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 12 Sep 2022 16:59:57 -0500 Subject: [PATCH] fix: Make `arg!(--flag )` 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 )`, outside of other context, should be optional. This is how the help would display it. Fixes #4206 --- CHANGELOG.md | 1 + clap_bench/benches/02_simple.rs | 6 +- clap_bench/benches/03_complex.rs | 12 ++-- clap_mangen/examples/man.rs | 1 - examples/cargo-example.rs | 1 - examples/escaped-positional.rs | 6 +- examples/find.md | 2 +- examples/git.rs | 2 +- examples/tutorial_builder/02_app_settings.rs | 4 +- examples/tutorial_builder/02_apps.rs | 4 +- examples/tutorial_builder/02_crate.rs | 4 +- examples/tutorial_builder/04_03_relations.rs | 4 +- examples/tutorial_builder/04_04_custom.rs | 9 +-- src/builder/arg_group.rs | 4 +- src/builder/command.rs | 4 +- src/macros.rs | 8 ++- src/parser/matches/arg_matches.rs | 12 ++-- tests/builder/app_settings.rs | 43 ++++++----- tests/builder/arg_matches.rs | 31 ++------ tests/builder/conflicts.rs | 37 ++-------- tests/builder/default_vals.rs | 75 +++++++------------- tests/builder/global_args.rs | 4 +- tests/builder/groups.rs | 12 ++-- tests/builder/help.rs | 34 +++++---- tests/builder/hidden_args.rs | 8 +-- tests/builder/opts.rs | 20 ++++-- tests/builder/posix_compatible.rs | 50 ++++--------- tests/builder/require.rs | 22 +++--- tests/builder/subcommands.rs | 14 ++-- tests/builder/utils.rs | 32 +++------ tests/macros.rs | 12 ++-- 31 files changed, 177 insertions(+), 301 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2dc89ae905e..7f8ef7725f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 )` 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) diff --git a/clap_bench/benches/02_simple.rs b/clap_bench/benches/02_simple.rs index 667d02f873c..2b448ea95fa 100644 --- a/clap_bench/benches/02_simple.rs +++ b/clap_bench/benches/02_simple.rs @@ -8,7 +8,7 @@ macro_rules! create_app { .about("tests clap library") .author("Kevin K. ") .arg(arg!(-f --flag "tests flags")) - .arg(arg!(-o --option "tests options").required(false)) + .arg(arg!(-o --option "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 "something"))) + b.iter(|| Command::new("claptests").arg(arg!(-s --some "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 "something"); + let arg = arg!(-s --some "something").required(true); Command::new("claptests").arg(&arg) }) }); diff --git a/clap_bench/benches/03_complex.rs b/clap_bench/benches/03_complex.rs index 2408d194497..dc708e61d04 100644 --- a/clap_bench/benches/03_complex.rs +++ b/clap_bench/benches/03_complex.rs @@ -10,7 +10,7 @@ macro_rules! create_app { .version("0.1") .about("tests clap library") .author("Kevin K. ") - .arg(arg!(-o --option ... "tests options").required(false)) + .arg(arg!(-o --option ... "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" "tests long options with exclusions") - .required(false) .conflicts_with("option") .requires("positional2"), arg!([positional2] "tests positionals with exclusions"), arg!(-O --Option "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 "Tests multiple values not mult occs").required(false).value_names(["one", "two"]), + arg!(--multvals "Tests multiple values not mult occs").value_names(["one", "two"]), arg!( --multvalsmo "Tests multiple values, not mult occs" ).required(false).value_names(["one", "two"]), - arg!(--minvals2 ... "Tests 2 min vals").num_args(2..).required(false), - arg!(--maxvals3 ... "Tests 3 max vals").num_args(1..=3).required(false), + arg!(--minvals2 ... "Tests 2 min vals").num_args(2..), + arg!(--maxvals3 ... "Tests 3 max vals").num_args(1..=3), ]) .subcommand( Command::new("subcmd") .about("tests subcommands") .version("0.1") .author("Kevin K. ") - .arg(arg!(-o --option ... "tests options").required(false)) + .arg(arg!(-o --option ... "tests options")) .arg(arg!([scpositional] "tests positionals")) ) }}; diff --git a/clap_mangen/examples/man.rs b/clap_mangen/examples/man.rs index 3af6fae97c7..1995b936506 100644 --- a/clap_mangen/examples/man.rs +++ b/clap_mangen/examples/man.rs @@ -19,7 +19,6 @@ And a few newlines.", .arg( arg!(-c --config "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"), ) diff --git a/examples/cargo-example.rs b/examples/cargo-example.rs index d9a909f4f0b..b0861a630cd 100644 --- a/examples/cargo-example.rs +++ b/examples/cargo-example.rs @@ -5,7 +5,6 @@ fn main() { .subcommand( clap::command!("example").arg( clap::arg!(--"manifest-path" ) - .required(false) .value_parser(clap::value_parser!(std::path::PathBuf)), ), ); diff --git a/examples/escaped-positional.rs b/examples/escaped-positional.rs index 8c5ffae4b67..d107e47db4b 100644 --- a/examples/escaped-positional.rs +++ b/examples/escaped-positional.rs @@ -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 ) - .required(false) - .value_parser(value_parser!(String)), - ) + .arg(arg!(pea: -p ).value_parser(value_parser!(String))) .arg( // Indicates that `slop` is only accessible after `--`. arg!(slop: [SLOP]) diff --git a/examples/find.md b/examples/find.md index fb9323989cf..6388d4724b6 100644 --- a/examples/find.md +++ b/examples/find.md @@ -4,7 +4,7 @@ $ find --help A simple to use, efficient, and full-featured Command Line Argument Parser -Usage: find[EXE] [OPTIONS] --name +Usage: find[EXE] [OPTIONS] Options: -h, --help Print help information diff --git a/examples/git.rs b/examples/git.rs index abf104f6153..acdd88b8caa 100644 --- a/examples/git.rs +++ b/examples/git.rs @@ -45,7 +45,7 @@ fn cli() -> Command { } fn push_args() -> Vec { - vec![arg!(-m --message ).required(false)] + vec![arg!(-m --message )] } fn main() { diff --git a/examples/tutorial_builder/02_app_settings.rs b/examples/tutorial_builder/02_app_settings.rs index 8d64b4dc3f9..4e30ec9a523 100644 --- a/examples/tutorial_builder/02_app_settings.rs +++ b/examples/tutorial_builder/02_app_settings.rs @@ -3,8 +3,8 @@ use clap::{arg, command, ArgAction}; fn main() { let matches = command!() // requires `cargo` feature .next_line_help(true) - .arg(arg!(--two ).action(ArgAction::Set)) - .arg(arg!(--one ).action(ArgAction::Set)) + .arg(arg!(--two ).required(true).action(ArgAction::Set)) + .arg(arg!(--one ).required(true).action(ArgAction::Set)) .get_matches(); println!( diff --git a/examples/tutorial_builder/02_apps.rs b/examples/tutorial_builder/02_apps.rs index db9da18f902..7d98e6cfe4c 100644 --- a/examples/tutorial_builder/02_apps.rs +++ b/examples/tutorial_builder/02_apps.rs @@ -5,8 +5,8 @@ fn main() { .version("1.0") .author("Kevin K. ") .about("Does awesome things") - .arg(arg!(--two )) - .arg(arg!(--one )) + .arg(arg!(--two ).required(true)) + .arg(arg!(--one ).required(true)) .get_matches(); println!( diff --git a/examples/tutorial_builder/02_crate.rs b/examples/tutorial_builder/02_crate.rs index 8a1722fd338..ad6bb4713bc 100644 --- a/examples/tutorial_builder/02_crate.rs +++ b/examples/tutorial_builder/02_crate.rs @@ -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 )) - .arg(arg!(--one )) + .arg(arg!(--two ).required(true)) + .arg(arg!(--one ).required(true)) .get_matches(); println!( diff --git a/examples/tutorial_builder/04_03_relations.rs b/examples/tutorial_builder/04_03_relations.rs index 9028e11b926..9d2d3d8d915 100644 --- a/examples/tutorial_builder/04_03_relations.rs +++ b/examples/tutorial_builder/04_03_relations.rs @@ -6,7 +6,7 @@ fn main() { // Create application like normal let matches = command!() // requires `cargo` feature // Add the version arguments - .arg(arg!(--"set-ver" "set version manually").required(false)) + .arg(arg!(--"set-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" "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 ) - .required(false) .value_parser(value_parser!(PathBuf)) .requires("input"), ) diff --git a/examples/tutorial_builder/04_04_custom.rs b/examples/tutorial_builder/04_04_custom.rs index 9028ac86823..ebbae67dc0f 100644 --- a/examples/tutorial_builder/04_04_custom.rs +++ b/examples/tutorial_builder/04_04_custom.rs @@ -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" "set version manually").required(false)) + .arg(arg!(--"set-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" "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 ) - .required(false) - .value_parser(value_parser!(PathBuf)), - ); + .arg(arg!(config: -c ).value_parser(value_parser!(PathBuf))); let matches = cmd.get_matches_mut(); // Let's assume the old version 1.2.3 diff --git a/src/builder/arg_group.rs b/src/builder/arg_group.rs index 32dbc97e8a8..9f97f24e57b 100644 --- a/src/builder/arg_group.rs +++ b/src/builder/arg_group.rs @@ -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" "set the version manually").required(false)) +/// .arg(arg!(--"set-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" "set the version manually").required(false)) +/// .arg(arg!(--"set-ver" "set the version manually")) /// .arg(arg!(--major "auto increase major")) /// .arg(arg!(--minor "auto increase minor")) /// .arg(arg!(--patch "auto increase patch")) diff --git a/src/builder/command.rs b/src/builder/command.rs index 564354715ee..36c92a3e983 100644 --- a/src/builder/command.rs +++ b/src/builder/command.rs @@ -923,8 +923,8 @@ impl Command { /// # use clap::{Command, arg}; /// let cmd = Command::new("cmd") /// .ignore_errors(true) - /// .arg(arg!(-c --config "Sets a custom config file").required(false)) - /// .arg(arg!(-x --stuff "Sets a custom stuff file").required(false)) + /// .arg(arg!(-c --config "Sets a custom config file")) + /// .arg(arg!(-x --stuff "Sets a custom stuff file")) /// .arg(arg!(f: -f "Flag")); /// /// let r = cmd.try_get_matches_from(vec!["cmd", "-c", "file", "-f", "-x"]); diff --git a/src/macros.rs b/src/macros.rs index 1ada8f95a9b..3bc04647e3c 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -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() == "" { diff --git a/src/parser/matches/arg_matches.rs b/src/parser/matches/arg_matches.rs index 1622f8f7273..d9664add155 100644 --- a/src/parser/matches/arg_matches.rs +++ b/src/parser/matches/arg_matches.rs @@ -376,11 +376,9 @@ impl ArgMatches { /// /// let m = Command::new("myprog") /// .arg(arg!(--color ) - /// .value_parser(["auto", "always", "never"]) - /// .required(false)) + /// .value_parser(["auto", "always", "never"])) /// .arg(arg!(--config ) - /// .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 ) -/// .value_parser(["auto", "always", "never"]) -/// .required(false)) +/// .value_parser(["auto", "always", "never"])) /// .arg(arg!(--config ) -/// .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() diff --git a/tests/builder/app_settings.rs b/tests/builder/app_settings.rs index 6b4ba9a8cfd..a3125373518 100644 --- a/tests/builder/app_settings.rs +++ b/tests/builder/app_settings.rs @@ -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 ).required(false).default_value("-")) + .arg(arg!(--input ).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 "some option") - .required(false) - .value_parser(["one", "two"]), + arg!(-o --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 "some opt").required(false), - arg!([arg] ... "some arg"), - ]) + .args(&[arg!(f: -f "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" ).allow_hyphen_values(true)) + .arg( + arg!(--"some-argument" ) + .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 "some option").action(ArgAction::Set)) + .arg( + arg!(--opt "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 "some option") - .required(false) - .action(ArgAction::Set), - ) + .arg(arg!(--opt "some option").action(ArgAction::Set)) .arg( arg!(--other "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 "some option") - .required(false) .overrides_with("other") .action(ArgAction::Set), ) - .arg( - arg!(--other "some other option") - .required(false) - .action(ArgAction::Set), - ) + .arg(arg!(--other "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 "some option").action(ArgAction::Set)) + .arg( + arg!(--opt "some option") + .required(true) + .action(ArgAction::Set), + ) .try_get_matches_from(vec!["", "--opt=some,other", "--opt=one,two"]) .unwrap(); assert!(m.contains_id("opt")); diff --git a/tests/builder/arg_matches.rs b/tests/builder/arg_matches.rs index 036d8966679..9e28661da59 100644 --- a/tests/builder/arg_matches.rs +++ b/tests/builder/arg_matches.rs @@ -5,16 +5,8 @@ use clap::{Arg, ArgAction}; #[test] fn ids() { let m = Command::new("test") - .arg( - arg!(--color ) - .value_parser(["auto", "always", "never"]) - .required(false), - ) - .arg( - arg!(--config ) - .value_parser(value_parser!(std::path::PathBuf)) - .required(false), - ) + .arg(arg!(--color ).value_parser(["auto", "always", "never"])) + .arg(arg!(--config ).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 ) - .value_parser(["auto", "always", "never"]) - .required(false), - ) - .arg( - arg!(--config ) - .value_parser(value_parser!(std::path::PathBuf)) - .required(false), - ) + .arg(arg!(--color ).value_parser(["auto", "always", "never"])) + .arg(arg!(--config ).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 ) - .value_parser(["auto", "always", "never"]) - .required(false), - ) + .arg(arg!(--color ).value_parser(["auto", "always", "never"])) .arg( arg!(--config ) .value_parser(value_parser!(std::path::PathBuf)) - .required(false) .overrides_with("color"), ) .try_get_matches_from(["test", "--config=config.toml", "--color=auto"]) diff --git a/tests/builder/conflicts.rs b/tests/builder/conflicts.rs index 50ed63e880a..fc919a5fc82 100644 --- a/tests/builder/conflicts.rs +++ b/tests/builder/conflicts.rs @@ -49,12 +49,8 @@ fn exclusive_flag() { #[test] fn exclusive_option() { let result = Command::new("flag_conflict") - .arg( - arg!(-f --flag "some flag") - .required(false) - .exclusive(true), - ) - .arg(arg!(-o --other "some flag").required(false)) + .arg(arg!(-f --flag "some flag").exclusive(true)) + .arg(arg!(-o --other "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 "some flag") - .required(false) - .exclusive(true), - ) + .arg(arg!(-f --flag "some flag").exclusive(true)) .arg( arg!(-o --other "some flag") .required(false) @@ -83,15 +75,10 @@ fn default_doesnt_activate_exclusive() { let result = Command::new("flag_conflict") .arg( arg!(-f --flag "some flag") - .required(false) .exclusive(true) .default_value("val2"), ) - .arg( - arg!(-o --other "some flag") - .required(false) - .default_value("val1"), - ) + .arg(arg!(-o --other "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 "some arg") - .required(false) - .group("gr"), - ) + .arg(clap::arg!(--some "some arg").group("gr")) .arg( clap::arg!(--other "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 "some opt") - .required(false) - .default_value("default"), - ) + .arg(arg!(-o --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 "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!( diff --git a/tests/builder/default_vals.rs b/tests/builder/default_vals.rs index 05fc34c3851..f2c7769a922 100644 --- a/tests/builder/default_vals.rs +++ b/tests/builder/default_vals.rs @@ -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 "some opt") - .required(false) - .default_value("default"), - ) + .arg(arg!(o: -o "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 "some opt") - .required(false) - .default_value("default"), - ) + .arg(arg!(o: -o "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 "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 "some arg") - .required(false) - .default_value("default"), - ) + .arg(arg!(--opt "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 "some opt") - .required(false) - .default_value(expected), - ) + .arg(arg!(o: -o "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 "some arg") - .required(false) - .default_value(default), - ) + .arg(arg!(--opt "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 "some arg").required(false)) + .arg(arg!(--opt "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 "some arg").required(false)) + .arg(arg!(--opt "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 "some arg").required(false)) + .arg(arg!(--opt "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 "some arg").required(false)) + .arg(arg!(--opt "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 "some arg").required(false)) + .arg(arg!(--opt "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 "some arg").required(false)) + .arg(arg!(--opt "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 "some arg").required(false)) + .arg(arg!(--opt "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 "some arg").required(false)) + .arg(arg!(--opt "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 "some arg").required(false)) + .arg(arg!(--opt "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 "some arg").required(false)) + .arg(arg!(--opt "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 "some arg").required(false)) + .arg(arg!(--opt "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 "some arg").required(false)) + .arg(arg!(--opt "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 "some arg").required(false)) + .arg(arg!(--opt "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 "some arg").required(false)) + .arg(arg!(--opt "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 "some arg").required(false)) + .arg(arg!(--opt "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 "some arg").required(false)) + .arg(arg!(--opt "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 "some arg").required(false)) + .arg(arg!(--opt "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 "some arg").required(false)) + .arg(arg!(--opt "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 "some arg").required(false)) + .arg(arg!(--opt "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 "some arg").required(false)) + .arg(arg!(--opt "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 "some arg").required(false)) + .arg(arg!(--opt "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 "some arg").required(false)) + .arg(arg!(--opt "some arg")) .arg(arg!(--flag "some arg")) .arg( arg!([arg] "some arg") diff --git a/tests/builder/global_args.rs b/tests/builder/global_args.rs index aece1dfd37c..7542b8e1a79 100644 --- a/tests/builder/global_args.rs +++ b/tests/builder/global_args.rs @@ -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" ).required(false).global(true)) + .arg(arg!(--"global-str" ).global(true)) .subcommand( Command::new("test") .arg(arg!(--"sub-flag").global(true)) - .arg(arg!(--"sub-str" ).required(false).global(true)) + .arg(arg!(--"sub-str" ).global(true)) .subcommand(Command::new("test")), ) .try_get_matches_from(&[ diff --git a/tests/builder/groups.rs b/tests/builder/groups.rs index 93281ca7712..c5c6aba3306 100644 --- a/tests/builder/groups.rs +++ b/tests/builder/groups.rs @@ -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 "another option").required(false)) + .arg(arg!(-n --hostname "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 "another option").required(false)) + .arg(arg!(-n --hostname "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 "another option").required(false)) + .arg(arg!(-n --hostname "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 "some option").num_args(1..)) - .arg(arg!(-n --hostname "another option").required(false)) + .arg(arg!(-n --hostname "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 )) - .arg(arg!(--bar )) + .arg(arg!(--foo ).required(true)) + .arg(arg!(--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()); diff --git a/tests/builder/help.rs b/tests/builder/help.rs index 961eedc5433..53e89571d38 100644 --- a/tests/builder/help.rs +++ b/tests/builder/help.rs @@ -1063,7 +1063,7 @@ Options: let cmd = Command::new("prog") .version("1.0") .subcommand_negates_reqs(true) - .arg(arg!(-o --opt "tests options")) + .arg(arg!(-o --opt "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 "tests options").required(false)) + .arg(arg!(-o --opt "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 "tests options").required(false)) + .arg(arg!(-o --opt "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 "tests options").required(false)) + .arg(arg!(-o --opt "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" "Change which song is played for birthdays") + .required(true) .help_heading(Some("OVERRIDE SPECIAL")), ) + .arg(arg!(--style