Skip to content

Commit f03b88a

Browse files
committed
fix(Required Args): fixes a bug where required args are not correctly accounted for
Closes #343
1 parent 31692c4 commit f03b88a

File tree

1 file changed

+12
-44
lines changed

1 file changed

+12
-44
lines changed

src/app/mod.rs

+12-44
Original file line numberDiff line numberDiff line change
@@ -1669,27 +1669,6 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar> {
16691669
};
16701670
let arg_slice: &str = arg_cow.borrow();
16711671

1672-
// we need to know if we're parsing a new argument, or the value of previous
1673-
// argument,
1674-
// perhaps one with multiple values such as --option val1 val2. We determine
1675-
// when to
1676-
// stop parsing multiple values by finding a '-'
1677-
// let new_arg = if arg_slice.starts_with("-") {
1678-
// // If we come to a single `-` it's a value, not a new argument...this happens
1679-
// // when
1680-
// // one wants to use the Unix standard of '-' to mean 'stdin'
1681-
// arg_slice.len() > 1
1682-
// } else {
1683-
// true
1684-
// };
1685-
1686-
// pos_only is determined later, and set true when a user uses the Unix
1687-
// standard of
1688-
// '--' to mean only positionals follow
1689-
// If the user passed `--` we don't check for subcommands, because the argument
1690-
// they
1691-
// may be trying to pass might match a subcommand name
1692-
16931672
let starts_new_arg = if arg_slice.starts_with("-") {
16941673
!(arg_slice.len() == 1)
16951674
} else {
@@ -1766,10 +1745,13 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar> {
17661745
}
17671746
}
17681747

1748+
let mut reqs_validated = false;
17691749
if let Some(a) = needs_val_of {
17701750
if let Some(o) = self.opts.iter().filter(|o| &o.name == &a).next() {
1771-
if (o.settings.is_set(&ArgSettings::Multiple) && self.required.is_empty()) ||
1772-
!o.settings.is_set(&ArgSettings::Multiple){
1751+
try!(self.validate_required(matcher));
1752+
reqs_validated = true;
1753+
if (o.settings.is_set(&ArgSettings::Multiple) && reqs_validated) ||
1754+
!o.settings.is_set(&ArgSettings::Multiple) {
17731755
let should_err = match matcher.values_of(o.name) {
17741756
Some(ref v) => v.is_empty(),
17751757
None => true,
@@ -1781,6 +1763,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar> {
17811763
));
17821764
}
17831765
} else {
1766+
debugln!("Required: {:#?}", self.required);
17841767
return Err(error_builder::MissingRequiredArgument(
17851768
&*self.get_required_from(&self.required, Some(matcher))
17861769
.iter()
@@ -1799,18 +1782,13 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar> {
17991782
}
18001783
}
18011784

1802-
if let Err(e) = self.validate_blacklist(matcher) {
1803-
return Err(e);
1804-
}
1805-
1806-
if let Err(e) = self.validate_num_args(matcher) {
1807-
return Err(e);
1808-
}
1809-
1785+
try!(self.validate_blacklist(matcher));
1786+
try!(self.validate_num_args(matcher));
18101787
matcher.usage(try!(self.create_usage(&[])));
18111788

1812-
if !(self.settings.is_set(&AppSettings::SubcommandsNegateReqs) && subcmd_name.is_some()) {
1813-
try!(self.validate_required(&matcher));
1789+
if !(self.settings.is_set(&AppSettings::SubcommandsNegateReqs) && subcmd_name.is_some()) &&
1790+
!reqs_validated {
1791+
try!(self.validate_required(matcher));
18141792
}
18151793
if let Some(sc_name) = subcmd_name {
18161794
use std::fmt::Write;
@@ -2517,7 +2495,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar> {
25172495
if arg.is_set(ArgSettings::Multiple) {
25182496
if (vals as u8) < num {
25192497
return Ok(Some(arg.name()));
2520-
}
2498+
}
25212499
} else {
25222500
if (vals as u8 % num) != 0 {
25232501
return Ok(Some(arg.name()));
@@ -2555,16 +2533,6 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar> {
25552533

25562534
fn validate_arg<A>(&self, arg: &A, matcher: &mut ArgMatcher<'ar>) -> ClapResult<()>
25572535
where A: AnyArg<'ar> + Display {
2558-
// May not be needed since we can't get here without being an Arg of some type
2559-
//
2560-
// if arg.has_switch() && (!self.flags.iter().any(|f| f.name == arg.name()) &&
2561-
// !self.opts.iter().any(|f| f.name == arg.name())) {
2562-
// return Err(error_builder::InvalidArgument(
2563-
// &*format!("{}", arg),
2564-
// None,
2565-
// &*try!(self.create_current_usage(matcher))));
2566-
// }
2567-
25682536
// Ensure this arg isn't on the mutually excludes list
25692537
if self.blacklist.contains(&arg.name()) {
25702538
matcher.remove(arg.name());

0 commit comments

Comments
 (0)