Repository: clap-rs/clap (language: rust)

Issue:
Set required(false) by default for all arguments
### Discussed in https://github.com/clap-rs/clap/discussions/4203

<div type='discussions-op-text'>

<sup>Originally posted by **fritzrehde** September 11, 2022</sup>
I am trying to simplify my argument parsing in clap.
I want to do something like this: 
```
			arg!(-i --interval <SECS> "Seconds to wait between updates, 0 only executes once")
				.required(false)
				.default_value(DEFAULT_INTERVAL)
				.value_parser(value_parser!(f64)),
```
However, most of my arguments are not required (and have a default value), but I don't want to write required(false) every time. Is there an easy way to set required(false) as default for all arguments?</div>


Discussion / hints:

Fix patch:
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 <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)
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. <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)
         })
     });
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. <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 
 "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 <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"))
             )
     }};
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 <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"),
         )
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" <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 <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])
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 <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<clap::Arg> {
-    vec![arg!(-m --message <MESSAGE>).required(false)]
+    vec![arg!(-m --message <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 <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!(
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. <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!(
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 <VALUE>))
-        .arg(arg!(--one <VALUE>))
+        .arg(arg!(--two <VALUE>).required(true))
+        .arg(arg!(--one <VALUE>).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" <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"),
         )
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" <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
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" <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"))
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 <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"]);
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 <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()


Test patch:
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 <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"));
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 <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"])
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 <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!(
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 <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")
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" <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(&[
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 <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());
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 <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);
 
diff --git a/tests/builder/hidden_args.rs b/tests/builder/hidden_args.rs
index fbe5f4b4c3c..8f634321d32 100644
--- a/tests/builder/hidden_args.rs
+++ b/tests/builder/hidden_args.rs
@@ -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);
 }
diff --git a/tests/builder/opts.rs b/tests/builder/opts.rs
index f5312c2dc6f..c47bbe2c320 100644
--- a/tests/builder/opts.rs
+++ b/tests/builder/opts.rs
@@ -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();
 
diff --git a/tests/builder/posix_compatible.rs b/tests/builder/posix_compatible.rs
index dcfc92ef7a9..c6e202aa8a8 100644
--- a/tests/builder/posix_compatible.rs
+++ b/tests/builder/posix_compatible.rs
@@ -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")
diff --git a/tests/builder/require.rs b/tests/builder/require.rs
index 97195aca44a..7e85df1b7d8 100644
--- a/tests/builder/require.rs
+++ b/tests/builder/require.rs
@@ -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]
diff --git a/tests/builder/subcommands.rs b/tests/builder/subcommands.rs
index 2e41c021cf2..937a2475421 100644
--- a/tests/builder/subcommands.rs
+++ b/tests/builder/subcommands.rs
@@ -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"]);
 
diff --git a/tests/builder/utils.rs b/tests/builder/utils.rs
index 3430e7164e9..f76efbec26c 100644
--- a/tests/builder/utils.rs
+++ b/tests/builder/utils.rs
@@ -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")),
         )
 }
diff --git a/tests/macros.rs b/tests/macros.rs
index e768884d916..7d56570f835 100644
--- a/tests/macros.rs
+++ b/tests/macros.rs
@@ -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())