Skip to content

Commit

Permalink
Merge pull request #5908 from epage/present
Browse files Browse the repository at this point in the history
fix(parser): Dont report missing flags as present
  • Loading branch information
epage authored Feb 11, 2025
2 parents 190a3f2 + 24fd0a7 commit 50a2b16
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 3 deletions.
9 changes: 7 additions & 2 deletions clap_builder/src/parser/matches/arg_matches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,10 @@ impl ArgMatches {
}
}

/// Check if any args were present on the command line
/// Check if any [`Arg`][crate::Arg]s were present on the command line
///
/// See [`ArgMatches::subcommand_name()`] or [`ArgMatches::subcommand()`] to check if a
/// subcommand was present on the command line.
///
/// # Examples
///
Expand All @@ -575,7 +578,9 @@ impl ArgMatches {
/// .unwrap();
/// assert!(! m.args_present());
pub fn args_present(&self) -> bool {
!self.args.is_empty()
self.args
.values()
.any(|v| v.source().map(|s| s.is_explicit()).unwrap_or(false))
}

/// Report where argument value came from
Expand Down
4 changes: 4 additions & 0 deletions clap_builder/src/util/flat_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ impl<K: PartialEq + Eq, V> FlatMap<K, V> {
self.keys.iter()
}

pub(crate) fn values(&self) -> std::slice::Iter<'_, V> {
self.values.iter()
}

pub(crate) fn iter(&self) -> Iter<'_, K, V> {
Iter {
keys: self.keys.iter(),
Expand Down
34 changes: 33 additions & 1 deletion tests/builder/arg_matches.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use clap::{arg, value_parser, Command};
#[cfg(debug_assertions)]
use clap::{Arg, ArgAction};

#[test]
Expand Down Expand Up @@ -83,3 +82,36 @@ fn arg_matches_subcommand_matches_wrong_sub() {
assert!(m.subcommand_matches("speed").is_some());
m.subcommand_matches("seed");
}

#[test]
fn args_present_positional() {
let c = Command::new("test").arg(Arg::new("positional"));

let m = c.clone().try_get_matches_from(["test"]).unwrap();
assert!(!m.args_present());

let m = c.clone().try_get_matches_from(["test", "value"]).unwrap();
assert!(m.args_present());
}

#[test]
fn args_present_flag() {
let c = Command::new("test").arg(Arg::new("flag").long("flag").action(ArgAction::SetTrue));

let m = c.clone().try_get_matches_from(["test"]).unwrap();
assert!(!m.args_present());

let m = c.clone().try_get_matches_from(["test", "--flag"]).unwrap();
assert!(m.args_present());
}

#[test]
fn args_present_subcommand() {
let c = Command::new("test").subcommand(Command::new("sub"));

let m = c.clone().try_get_matches_from(["test"]).unwrap();
assert!(!m.args_present());

let m = c.clone().try_get_matches_from(["test", "sub"]).unwrap();
assert!(!m.args_present());
}

0 comments on commit 50a2b16

Please sign in to comment.