Forbid multiple_occurrences for positional args

This commit is contained in:
Pavan Kumar Sunkara 2021-06-16 08:27:04 +01:00
parent 3f94d17c71
commit e5e20b389e
5 changed files with 32 additions and 31 deletions

View file

@ -29,12 +29,21 @@ pub(crate) fn assert_arg(arg: &Arg) {
if arg.index.is_some() {
assert!(
arg.short.is_none() && arg.long.is_none(),
!arg.has_switch(),
"Argument '{}' is a positional argument and can't have short or long name versions",
arg.name
);
}
// Positionals should not have multiple_occurrences
if arg.is_positional() {
assert!(
!arg.is_set(ArgSettings::MultipleOccurrences),
"Argument '{}' is a positional argument and can't be set as multiple occurrences",
arg.name
);
}
if arg.is_set(ArgSettings::Required) {
assert!(
arg.default_vals.is_empty(),

View file

@ -73,6 +73,7 @@ impl<'help> UsageParser<'help> {
// We had a positional and need to set mult vals too
arg.settings.set(ArgSettings::TakesValue);
arg.settings.set(ArgSettings::MultipleValues);
arg.settings.unset(ArgSettings::MultipleOccurrences);
}
debug!("UsageParser::parse: vals...{:?}", arg.val_names);
arg
@ -1181,9 +1182,7 @@ mod test {
let a = Arg::from("[pos]... 'some help info'");
assert_eq!(a.name, "pos");
assert_eq!(a.about.unwrap(), "some help info");
assert!(
a.is_set(ArgSettings::MultipleValues) && a.is_set(ArgSettings::MultipleOccurrences)
);
assert!(a.is_set(ArgSettings::MultipleValues));
assert!(!a.is_set(ArgSettings::Required));
assert!(a.val_names.is_empty());
assert!(a.num_vals.is_none());
@ -1194,9 +1193,7 @@ mod test {
let a = Arg::from("[pos]... 'some help\' info'");
assert_eq!(a.name, "pos");
assert_eq!(a.about.unwrap(), "some help' info");
assert!(
a.is_set(ArgSettings::MultipleValues) && a.is_set(ArgSettings::MultipleOccurrences)
);
assert!(a.is_set(ArgSettings::MultipleValues));
assert!(!a.is_set(ArgSettings::Required));
assert!(a.val_names.is_empty());
assert!(a.num_vals.is_none());
@ -1207,9 +1204,7 @@ mod test {
let a = Arg::from("[pos]... 'some \'help\' info'");
assert_eq!(a.name, "pos");
assert_eq!(a.about.unwrap(), "some 'help' info");
assert!(
a.is_set(ArgSettings::MultipleValues) && a.is_set(ArgSettings::MultipleOccurrences)
);
assert!(a.is_set(ArgSettings::MultipleValues));
assert!(!a.is_set(ArgSettings::Required));
assert!(a.val_names.is_empty());
assert!(a.num_vals.is_none());
@ -1223,9 +1218,7 @@ mod test {
);
assert_eq!(a.name, "pos");
assert_eq!(a.about.unwrap(), "some help\ninfo");
assert!(
a.is_set(ArgSettings::MultipleValues) && a.is_set(ArgSettings::MultipleOccurrences)
);
assert!(a.is_set(ArgSettings::MultipleValues));
assert!(!a.is_set(ArgSettings::Required));
assert!(a.val_names.is_empty());
assert!(a.num_vals.is_none());
@ -1239,9 +1232,7 @@ mod test {
);
assert_eq!(a.name, "pos");
assert_eq!(a.about.unwrap(), "some help' stuff\ninfo");
assert!(
a.is_set(ArgSettings::MultipleValues) && a.is_set(ArgSettings::MultipleOccurrences)
);
assert!(a.is_set(ArgSettings::MultipleValues));
assert!(!a.is_set(ArgSettings::Required));
assert!(a.val_names.is_empty());
assert!(a.num_vals.is_none());
@ -1252,9 +1243,7 @@ mod test {
let a = Arg::from("<pos>... 'some help info'");
assert_eq!(a.name, "pos");
assert_eq!(a.about.unwrap(), "some help info");
assert!(
a.is_set(ArgSettings::MultipleValues) && a.is_set(ArgSettings::MultipleOccurrences)
);
assert!(a.is_set(ArgSettings::MultipleValues));
assert!(a.is_set(ArgSettings::Required));
assert!(a.val_names.is_empty());
assert!(a.num_vals.is_none());
@ -1276,9 +1265,7 @@ mod test {
fn pos_mult() {
let a = Arg::from("[pos]...");
assert_eq!(a.name, "pos");
assert!(
a.is_set(ArgSettings::MultipleValues) && a.is_set(ArgSettings::MultipleOccurrences)
);
assert!(a.is_set(ArgSettings::MultipleValues));
assert!(!a.is_set(ArgSettings::Required));
assert!(a.val_names.is_empty());
assert!(a.num_vals.is_none());
@ -1289,9 +1276,7 @@ mod test {
let a = Arg::from("<pos>... @a 'some help info'");
assert_eq!(a.name, "pos");
assert_eq!(a.about.unwrap(), "some help info");
assert!(
a.is_set(ArgSettings::MultipleValues) && a.is_set(ArgSettings::MultipleOccurrences)
);
assert!(a.is_set(ArgSettings::MultipleValues));
assert!(a.is_set(ArgSettings::Required));
assert!(a.val_names.is_empty());
assert!(a.num_vals.is_none());

View file

@ -114,8 +114,7 @@ fn grouped_value_positional_arg() {
Arg::new("pos")
.about("multiple positionals")
.takes_value(true)
.multiple_values(true)
.multiple_occurrences(true),
.multiple_values(true),
)
.get_matches_from(vec![
"myprog", "val1", "val2", "val3", "val4", "val5", "val6",
@ -135,8 +134,7 @@ fn grouped_value_multiple_positional_arg() {
Arg::new("pos2")
.about("multiple positionals")
.takes_value(true)
.multiple_values(true)
.multiple_occurrences(true),
.multiple_values(true),
)
.get_matches_from(vec![
"myprog", "val1", "val2", "val3", "val4", "val5", "val6",
@ -157,7 +155,6 @@ fn grouped_value_multiple_positional_arg_last_multiple() {
.about("multiple positionals")
.takes_value(true)
.multiple_values(true)
.multiple_occurrences(true)
.last(true),
)
.get_matches_from(vec![

View file

@ -760,7 +760,6 @@ fn args_with_last_usage() {
.about("Any arguments you wish to pass to the being profiled.")
.setting(ArgSettings::TakesValue)
.setting(ArgSettings::MultipleValues)
.setting(ArgSettings::MultipleOccurrences)
.setting(ArgSettings::Last)
.value_name("ARGS"),
);

View file

@ -296,3 +296,14 @@ fn positional_arg_with_short() {
.arg(Arg::new("arg").index(1).short('a'))
.try_get_matches();
}
#[cfg(debug_assertions)]
#[test]
#[should_panic = "Argument 'arg' is a positional argument and can't be set as multiple occurrences"]
fn positional_arg_with_multiple_occurrences() {
use clap::{App, Arg};
let _ = App::new("test")
.arg(Arg::new("arg").multiple_occurrences(true))
.try_get_matches();
}