Skip to content

Commit

Permalink
fix(parser): Ensure globals override env vars
Browse files Browse the repository at this point in the history
This fixes a bug introduced in 4a694f3
when we were trying to move away from presence checks via occurrences.
I switched it to the common type of presence check but really what we
want is a highest-precedence check.

Fixes #3872
  • Loading branch information
epage committed Jun 28, 2022
1 parent f082eb6 commit 72d206e
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 3 deletions.
4 changes: 1 addition & 3 deletions src/parser/arg_matcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,7 @@ impl ArgMatcher {
// a default value of `other` myprog would have an existing MatchedArg for
// `--global-arg` where the value is `other`
let to_update = if let Some(parent_ma) = vals_map.get(global_arg) {
if parent_ma.check_explicit(ArgPredicate::IsPresent)
&& !ma.check_explicit(ArgPredicate::IsPresent)
{
if parent_ma.source() > ma.source() {
parent_ma
} else {
ma
Expand Down
37 changes: 37 additions & 0 deletions tests/builder/global_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,40 @@ fn global_overrides_default() {
.unwrap();
assert_eq!(m.get_one::<String>("name").unwrap().as_str(), "from_arg");
}

#[test]
#[cfg(feature = "env")]
fn global_overrides_env() {
std::env::set_var("GLOBAL_OVERRIDES_ENV", "from_env");

let cmd = Command::new("test")
.arg(
Arg::new("name")
.long("name")
.global(true)
.takes_value(true)
.env("GLOBAL_OVERRIDES_ENV"),
)
.subcommand(Command::new("sub"));

let m = cmd.clone().try_get_matches_from(["test"]).unwrap();
assert_eq!(m.get_one::<String>("name").unwrap().as_str(), "from_env");

let m = cmd
.clone()
.try_get_matches_from(["test", "--name", "from_arg"])
.unwrap();
assert_eq!(m.get_one::<String>("name").unwrap().as_str(), "from_arg");

let m = cmd
.clone()
.try_get_matches_from(["test", "--name", "from_arg", "sub"])
.unwrap();
assert_eq!(m.get_one::<String>("name").unwrap().as_str(), "from_arg");

let m = cmd
.clone()
.try_get_matches_from(["test", "sub", "--name", "from_arg"])
.unwrap();
assert_eq!(m.get_one::<String>("name").unwrap().as_str(), "from_arg");
}

0 comments on commit 72d206e

Please sign in to comment.