Skip to content

Commit f406d99

Browse files
authored
Merge pull request #3879 from epage/env
fix(parser): Ensure globals override env vars
2 parents 9962393 + 72d206e commit f406d99

File tree

2 files changed

+75
-3
lines changed

2 files changed

+75
-3
lines changed

src/parser/arg_matcher.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,7 @@ impl ArgMatcher {
7474
// a default value of `other` myprog would have an existing MatchedArg for
7575
// `--global-arg` where the value is `other`
7676
let to_update = if let Some(parent_ma) = vals_map.get(global_arg) {
77-
if parent_ma.check_explicit(ArgPredicate::IsPresent)
78-
&& !ma.check_explicit(ArgPredicate::IsPresent)
79-
{
77+
if parent_ma.source() > ma.source() {
8078
parent_ma
8179
} else {
8280
ma

tests/builder/global_args.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,77 @@ fn deeply_nested_discovery() {
126126
let m = m.subcommand_matches("c").unwrap();
127127
assert!(*m.get_one::<bool>("long-c").expect("defaulted by clap"));
128128
}
129+
130+
#[test]
131+
fn global_overrides_default() {
132+
let cmd = Command::new("test")
133+
.arg(
134+
Arg::new("name")
135+
.long("name")
136+
.global(true)
137+
.takes_value(true)
138+
.default_value("from_default"),
139+
)
140+
.subcommand(Command::new("sub"));
141+
142+
let m = cmd.clone().try_get_matches_from(["test"]).unwrap();
143+
assert_eq!(
144+
m.get_one::<String>("name").unwrap().as_str(),
145+
"from_default"
146+
);
147+
148+
let m = cmd
149+
.clone()
150+
.try_get_matches_from(["test", "--name", "from_arg"])
151+
.unwrap();
152+
assert_eq!(m.get_one::<String>("name").unwrap().as_str(), "from_arg");
153+
154+
let m = cmd
155+
.clone()
156+
.try_get_matches_from(["test", "--name", "from_arg", "sub"])
157+
.unwrap();
158+
assert_eq!(m.get_one::<String>("name").unwrap().as_str(), "from_arg");
159+
160+
let m = cmd
161+
.clone()
162+
.try_get_matches_from(["test", "sub", "--name", "from_arg"])
163+
.unwrap();
164+
assert_eq!(m.get_one::<String>("name").unwrap().as_str(), "from_arg");
165+
}
166+
167+
#[test]
168+
#[cfg(feature = "env")]
169+
fn global_overrides_env() {
170+
std::env::set_var("GLOBAL_OVERRIDES_ENV", "from_env");
171+
172+
let cmd = Command::new("test")
173+
.arg(
174+
Arg::new("name")
175+
.long("name")
176+
.global(true)
177+
.takes_value(true)
178+
.env("GLOBAL_OVERRIDES_ENV"),
179+
)
180+
.subcommand(Command::new("sub"));
181+
182+
let m = cmd.clone().try_get_matches_from(["test"]).unwrap();
183+
assert_eq!(m.get_one::<String>("name").unwrap().as_str(), "from_env");
184+
185+
let m = cmd
186+
.clone()
187+
.try_get_matches_from(["test", "--name", "from_arg"])
188+
.unwrap();
189+
assert_eq!(m.get_one::<String>("name").unwrap().as_str(), "from_arg");
190+
191+
let m = cmd
192+
.clone()
193+
.try_get_matches_from(["test", "--name", "from_arg", "sub"])
194+
.unwrap();
195+
assert_eq!(m.get_one::<String>("name").unwrap().as_str(), "from_arg");
196+
197+
let m = cmd
198+
.clone()
199+
.try_get_matches_from(["test", "sub", "--name", "from_arg"])
200+
.unwrap();
201+
assert_eq!(m.get_one::<String>("name").unwrap().as_str(), "from_arg");
202+
}

0 commit comments

Comments
 (0)