From 934dfe565ef238ce399ceba4e1e95da75535b121 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 7 Jun 2022 13:48:48 -0500 Subject: [PATCH] fix(parser): Deprecate multiple_occurrences Fixes #3772 --- clap_bench/benches/03_complex.rs | 15 +- clap_bench/benches/04_new_help.rs | 8 +- clap_bench/benches/05_ripgrep.rs | 29 +- clap_bench/benches/06_rustup.rs | 3 +- clap_complete/src/shells/zsh.rs | 3 + clap_complete/tests/common.rs | 6 +- clap_complete_fig/src/fig.rs | 2 + clap_complete_fig/tests/common.rs | 6 +- .../tests/snapshots/special_commands.fig.js | 1 + examples/escaped-positional.rs | 2 +- examples/typed-derive.rs | 2 +- src/builder/arg.rs | 50 +--- src/builder/debug_asserts.rs | 7 +- src/macros.rs | 44 ++- src/parser/arg_matcher.rs | 1 + src/parser/validator.rs | 2 + tests/builder/grouped_values.rs | 38 +-- tests/builder/help.rs | 14 +- tests/builder/indices.rs | 81 ++---- tests/builder/multiple_occurrences.rs | 257 +++-------------- tests/builder/multiple_values.rs | 273 ++---------------- tests/builder/posix_compatible.rs | 4 +- tests/builder/possible_values.rs | 6 +- tests/builder/propagate_globals.rs | 22 +- tests/builder/utils.rs | 2 +- tests/derive/options.rs | 10 +- tests/macros.rs | 70 ++++- 27 files changed, 260 insertions(+), 698 deletions(-) diff --git a/clap_bench/benches/03_complex.rs b/clap_bench/benches/03_complex.rs index b4e76020f732..6292472fd745 100644 --- a/clap_bench/benches/03_complex.rs +++ b/clap_bench/benches/03_complex.rs @@ -1,4 +1,4 @@ -use clap::{arg, Arg, Command}; +use clap::{arg, Arg, ArgAction, Command}; use criterion::{criterion_group, criterion_main, Criterion}; static OPT3_VALS: [&str; 2] = ["fast", "slow"]; @@ -59,7 +59,7 @@ pub fn build_from_builder(c: &mut Criterion) { .long("option") .takes_value(true) .multiple_values(true) - .multiple_occurrences(true), + .action(ArgAction::Append), ) .arg(Arg::new("positional").help("tests positionals").index(1)) .arg( @@ -68,7 +68,7 @@ pub fn build_from_builder(c: &mut Criterion) { .help("tests flags") .long("flag") .global(true) - .multiple_occurrences(true), + .action(ArgAction::Append), ) .arg( Arg::new("flag2") @@ -102,7 +102,6 @@ pub fn build_from_builder(c: &mut Criterion) { Arg::new("positional3") .takes_value(true) .multiple_values(true) - .multiple_occurrences(true) .help("tests positionals with specific values") .index(4) .value_parser(POS3_VALS), @@ -118,7 +117,7 @@ pub fn build_from_builder(c: &mut Criterion) { .long("multvalsmo") .takes_value(true) .multiple_values(true) - .multiple_occurrences(true) + .action(ArgAction::Append) .help("Tests multiple values, not mult occs") .value_names(&["one", "two"]), ) @@ -127,7 +126,7 @@ pub fn build_from_builder(c: &mut Criterion) { .long("minvals2") .takes_value(true) .multiple_values(true) - .multiple_occurrences(true) + .action(ArgAction::Append) .help("Tests 2 min vals") .min_values(2), ) @@ -136,7 +135,7 @@ pub fn build_from_builder(c: &mut Criterion) { .long("maxvals3") .takes_value(true) .multiple_values(true) - .multiple_occurrences(true) + .action(ArgAction::Append) .help("Tests 3 max vals") .max_values(3), ) @@ -151,7 +150,7 @@ pub fn build_from_builder(c: &mut Criterion) { .long("option") .takes_value(true) .multiple_values(true) - .multiple_occurrences(true) + .action(ArgAction::Append) .help("tests options"), ) .arg(Arg::new("scpositional").index(1).help("tests positionals")), diff --git a/clap_bench/benches/04_new_help.rs b/clap_bench/benches/04_new_help.rs index 83b14fb70681..7de9dd48727e 100644 --- a/clap_bench/benches/04_new_help.rs +++ b/clap_bench/benches/04_new_help.rs @@ -1,5 +1,5 @@ use clap::Command; -use clap::{arg, Arg}; +use clap::{arg, Arg, ArgAction}; use criterion::{criterion_group, criterion_main, Criterion}; use std::io::Cursor; @@ -95,7 +95,7 @@ fn app_example5<'c>() -> Command<'c> { .help("turns up the awesome") .short('a') .long("awesome") - .multiple_occurrences(true), + .action(ArgAction::Count), ) } @@ -120,7 +120,7 @@ fn app_example7<'c>() -> Command<'c> { .help("the input file to use") .takes_value(true) .multiple_values(true) - .multiple_occurrences(true) + .action(ArgAction::Append) .required(true) .short('i') .long("input") @@ -138,7 +138,7 @@ fn app_example8<'c>() -> Command<'c> { .help("the input file to use") .takes_value(true) .multiple_values(true) - .multiple_occurrences(true) + .action(ArgAction::Append) .required(true) .short('i') .long("input") diff --git a/clap_bench/benches/05_ripgrep.rs b/clap_bench/benches/05_ripgrep.rs index 6ed8448d3391..10ab52c52459 100644 --- a/clap_bench/benches/05_ripgrep.rs +++ b/clap_bench/benches/05_ripgrep.rs @@ -3,7 +3,7 @@ // // CLI used is adapted from ripgrep 48a8a3a691220f9e5b2b08f4051abe8655ea7e8a -use clap::{value_parser, Arg, Command}; +use clap::{value_parser, Arg, ArgAction, Command}; use criterion::{criterion_group, criterion_main, Criterion}; use std::collections::HashMap; use std::io::Cursor; @@ -323,17 +323,12 @@ where "type-list", "version", ])) - .arg( - arg("path") - .takes_value(true) - .multiple_values(true) - .multiple_occurrences(true), - ) + .arg(arg("path").takes_value(true).multiple_values(true)) .arg( flag("regexp") .short('e') .allow_hyphen_values(true) - .multiple_occurrences(true) + .action(ArgAction::Append) .takes_value(true) .value_name("pattern"), ) @@ -357,14 +352,14 @@ where .arg( flag("colors") .value_name("SPEC") - .multiple_occurrences(true) + .action(ArgAction::Append) .takes_value(true), ) .arg(flag("fixed-strings").short('F')) .arg( flag("glob") .short('g') - .multiple_occurrences(true) + .action(ArgAction::Append) .takes_value(true) .value_name("GLOB"), ) @@ -375,18 +370,18 @@ where .arg( flag("type") .short('t') - .multiple_occurrences(true) + .action(ArgAction::Append) .takes_value(true) .value_name("TYPE"), ) .arg( flag("type-not") .short('T') - .multiple_occurrences(true) + .action(ArgAction::Append) .takes_value(true) .value_name("TYPE"), ) - .arg(flag("unrestricted").short('u').multiple_occurrences(true)) + .arg(flag("unrestricted").short('u').action(ArgAction::Append)) .arg(flag("invert-match").short('v')) .arg(flag("word-regexp").short('w')) // Third, set up less common flags. @@ -415,7 +410,7 @@ where flag("file") .short('f') .value_name("FILE") - .multiple_occurrences(true), + .action(ArgAction::Append), ) .arg(flag("files-with-matches").short('l')) .arg(flag("files-without-match")) @@ -427,7 +422,7 @@ where .arg( flag("ignore-file") .value_name("FILE") - .multiple_occurrences(true), + .action(ArgAction::Append), ) .arg(flag("follow").short('L')) .arg( @@ -464,12 +459,12 @@ where .arg( flag("type-add") .value_name("TYPE") - .multiple_occurrences(true), + .action(ArgAction::Append), ) .arg( flag("type-clear") .value_name("TYPE") - .multiple_occurrences(true), + .action(ArgAction::Append), ) } diff --git a/clap_bench/benches/06_rustup.rs b/clap_bench/benches/06_rustup.rs index 8d9c406e40df..ddc9fb321679 100644 --- a/clap_bench/benches/06_rustup.rs +++ b/clap_bench/benches/06_rustup.rs @@ -218,8 +218,7 @@ fn build_cli() -> Command<'static> { Arg::new("command") .required(true) .takes_value(true) - .multiple_values(true) - .multiple_occurrences(true), + .multiple_values(true), ), ) .subcommand( diff --git a/clap_complete/src/shells/zsh.rs b/clap_complete/src/shells/zsh.rs index 2563ad9329bf..0ff4703202b5 100644 --- a/clap_complete/src/shells/zsh.rs +++ b/clap_complete/src/shells/zsh.rs @@ -451,6 +451,7 @@ fn write_opts_of(p: &Command, p_global: Option<&Command>) -> String { let help = o.get_help().map_or(String::new(), escape_help); let conflicts = arg_conflicts(p, o, p_global); + #[allow(deprecated)] let multiple = if o.is_multiple_occurrences_set() { "*" } else { @@ -554,6 +555,7 @@ fn write_flags_of(p: &Command, p_global: Option<&Command>) -> String { let help = f.get_help().map_or(String::new(), escape_help); let conflicts = arg_conflicts(p, &f, p_global); + #[allow(deprecated)] let multiple = if f.is_multiple_occurrences_set() { "*" } else { @@ -632,6 +634,7 @@ fn write_positionals_of(p: &Command) -> String { for arg in p.get_positionals() { debug!("write_positionals_of:iter: arg={}", arg.get_id()); + #[allow(deprecated)] let cardinality = if arg.is_multiple_values_set() || arg.is_multiple_occurrences_set() { "*:" } else if !arg.is_required_set() { diff --git a/clap_complete/tests/common.rs b/clap_complete/tests/common.rs index 838ed381e523..f2200cbd8dd4 100644 --- a/clap_complete/tests/common.rs +++ b/clap_complete/tests/common.rs @@ -6,7 +6,7 @@ pub fn basic_command(name: &'static str) -> clap::Command<'static> { clap::Command::new("test").about("Subcommand").arg( clap::Arg::new("debug") .short('d') - .multiple_occurrences(true), + .action(clap::ArgAction::Count), ), ) } @@ -23,7 +23,7 @@ pub fn feature_sample_command(name: &'static str) -> clap::Command<'static> { ) .arg( clap::Arg::new("config") - .multiple_occurrences(true) + .action(clap::ArgAction::Count) .help("some config file") .short('c') .visible_short_alias('C') @@ -57,7 +57,7 @@ pub fn special_commands_command(name: &'static str) -> clap::Command<'static> { .arg( clap::Arg::new("path") .takes_value(true) - .multiple_occurrences(true), + .multiple_values(true), ), ) .subcommand(clap::Command::new("some-cmd-with-hyphens").alias("hyphen")) diff --git a/clap_complete_fig/src/fig.rs b/clap_complete_fig/src/fig.rs index f8e0d233a5af..ae6bff9ab3e5 100644 --- a/clap_complete_fig/src/fig.rs +++ b/clap_complete_fig/src/fig.rs @@ -216,6 +216,7 @@ fn gen_options(cmd: &Command, indent: usize) -> String { buffer.push_str(&format!("{:indent$}],\n", "", indent = indent + 4)); } + #[allow(deprecated)] if option.is_multiple_occurrences_set() { buffer.push_str(&format!( "{:indent$}isRepeatable: true,\n", @@ -303,6 +304,7 @@ fn gen_options(cmd: &Command, indent: usize) -> String { buffer.push_str(&format!("{:indent$}],\n", "", indent = indent + 4)); } + #[allow(deprecated)] if flag.is_multiple_occurrences_set() { buffer.push_str(&format!( "{:indent$}isRepeatable: true,\n", diff --git a/clap_complete_fig/tests/common.rs b/clap_complete_fig/tests/common.rs index 838ed381e523..f2200cbd8dd4 100644 --- a/clap_complete_fig/tests/common.rs +++ b/clap_complete_fig/tests/common.rs @@ -6,7 +6,7 @@ pub fn basic_command(name: &'static str) -> clap::Command<'static> { clap::Command::new("test").about("Subcommand").arg( clap::Arg::new("debug") .short('d') - .multiple_occurrences(true), + .action(clap::ArgAction::Count), ), ) } @@ -23,7 +23,7 @@ pub fn feature_sample_command(name: &'static str) -> clap::Command<'static> { ) .arg( clap::Arg::new("config") - .multiple_occurrences(true) + .action(clap::ArgAction::Count) .help("some config file") .short('c') .visible_short_alias('C') @@ -57,7 +57,7 @@ pub fn special_commands_command(name: &'static str) -> clap::Command<'static> { .arg( clap::Arg::new("path") .takes_value(true) - .multiple_occurrences(true), + .multiple_values(true), ), ) .subcommand(clap::Command::new("some-cmd-with-hyphens").alias("hyphen")) diff --git a/clap_complete_fig/tests/snapshots/special_commands.fig.js b/clap_complete_fig/tests/snapshots/special_commands.fig.js index 5a306ac1bbc3..1982cac0070b 100644 --- a/clap_complete_fig/tests/snapshots/special_commands.fig.js +++ b/clap_complete_fig/tests/snapshots/special_commands.fig.js @@ -49,6 +49,7 @@ const completion: Fig.Spec = { ], args: { name: "path", + isVariadic: true, isOptional: true, }, }, diff --git a/examples/escaped-positional.rs b/examples/escaped-positional.rs index 035c7b3e87cc..0043c735cad4 100644 --- a/examples/escaped-positional.rs +++ b/examples/escaped-positional.rs @@ -13,7 +13,7 @@ fn main() { .arg( // Indicates that `slop` is only accessible after `--`. arg!(slop: [SLOP]) - .multiple_occurrences(true) + .multiple_values(true) .last(true) .value_parser(value_parser!(String)), ) diff --git a/examples/typed-derive.rs b/examples/typed-derive.rs index b99370780df7..85c750f9c119 100644 --- a/examples/typed-derive.rs +++ b/examples/typed-derive.rs @@ -22,7 +22,7 @@ struct Args { sleep: Option, /// Hand-written parser for tuples - #[clap(short = 'D', value_parser = parse_key_val::, multiple_occurrences(true))] + #[clap(short = 'D', value_parser = parse_key_val::)] defines: Vec<(String, i32)>, } diff --git a/src/builder/arg.rs b/src/builder/arg.rs index eb8c8f937305..078acfef8f2b 100644 --- a/src/builder/arg.rs +++ b/src/builder/arg.rs @@ -776,53 +776,10 @@ impl<'help> Arg<'help> { } } - /// Specifies that the argument may appear more than once. - /// - /// For flags, this results in the number of occurrences of the flag being recorded. For - /// example `-ddd` or `-d -d -d` would count as three occurrences. For options or arguments - /// that take a value, this *does not* affect how many values they can accept. (i.e. only one - /// at a time is allowed) - /// - /// For example, `--opt val1 --opt val2` is allowed, but `--opt val1 val2` is not. - /// - /// # Examples - /// - /// An example with flags - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("verbose") - /// .multiple_occurrences(true) - /// .short('v')) - /// .get_matches_from(vec![ - /// "prog", "-v", "-v", "-v" // note, -vvv would have same result - /// ]); - /// - /// assert!(m.is_present("verbose")); - /// assert_eq!(m.occurrences_of("verbose"), 3); - /// ``` - /// - /// An example with options - /// - /// ```rust - /// # use clap::{Command, Arg}; - /// let m = Command::new("prog") - /// .arg(Arg::new("file") - /// .multiple_occurrences(true) - /// .takes_value(true) - /// .short('F')) - /// .get_matches_from(vec![ - /// "prog", "-F", "file1", "-F", "file2", "-F", "file3" - /// ]); - /// - /// assert!(m.is_present("file")); - /// assert_eq!(m.occurrences_of("file"), 3); - /// let files: Vec<_> = m.values_of("file").unwrap().collect(); - /// assert_eq!(files, ["file1", "file2", "file3"]); - /// ``` + /// Deprecated, replaced with [`Arg::action`] ([Issue #3772](https://github.com/clap-rs/clap/issues/3772)) #[inline] #[must_use] + #[deprecated(since = "3.2.0", note = "Replaced with `Arg::action` (Issue #3772)")] pub fn multiple_occurrences(self, yes: bool) -> Self { if yes { self.setting(ArgSettings::MultipleOccurrences) @@ -4477,7 +4434,8 @@ impl<'help> Arg<'help> { self.is_set(ArgSettings::MultipleValues) } - /// Report whether [`Arg::multiple_occurrences`] is set + /// [`Arg::multiple_occurrences`] is going away ([Issue #3772](https://github.com/clap-rs/clap/issues/3772)) + #[deprecated(since = "3.2.0", note = "`multiple_occurrences` away (Issue #3772)")] pub fn is_multiple_occurrences_set(&self) -> bool { self.is_set(ArgSettings::MultipleOccurrences) } diff --git a/src/builder/debug_asserts.rs b/src/builder/debug_asserts.rs index 78db63c5d250..91ab7dfe54cf 100644 --- a/src/builder/debug_asserts.rs +++ b/src/builder/debug_asserts.rs @@ -538,8 +538,11 @@ fn _verify_positionals(cmd: &Command) -> bool { let count = cmd .get_positionals() .filter(|p| { - p.is_multiple_occurrences_set() - || (p.is_multiple_values_set() && p.num_vals.is_none()) + #[allow(deprecated)] + { + p.is_multiple_occurrences_set() + || (p.is_multiple_values_set() && p.num_vals.is_none()) + } }) .count(); let ok = count <= 1 diff --git a/src/macros.rs b/src/macros.rs index f50b854959e6..0bbf6a14d467 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -425,7 +425,10 @@ macro_rules! arg_impl { @arg ({ debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values"); - debug_assert!(!$arg.is_multiple_occurrences_set(), "Flags should precede `...`"); + #[allow(deprecated)] + { + debug_assert!(!$arg.is_multiple_occurrences_set(), "Flags should precede `...`"); + } let mut arg = $arg; let long = $crate::arg_impl! { @string $long }; @@ -447,7 +450,10 @@ macro_rules! arg_impl { @arg ({ debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values"); - debug_assert!(!$arg.is_multiple_occurrences_set(), "Flags should precede `...`"); + #[allow(deprecated)] + { + debug_assert!(!$arg.is_multiple_occurrences_set(), "Flags should precede `...`"); + } let mut arg = $arg; let long = $crate::arg_impl! { @string $long }; @@ -470,7 +476,10 @@ macro_rules! arg_impl { ({ debug_assert_eq!($arg.get_long(), None, "Short flags should precede long flags"); debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values"); - debug_assert!(!$arg.is_multiple_occurrences_set(), "Flags should precede `...`"); + #[allow(deprecated)] + { + debug_assert!(!$arg.is_multiple_occurrences_set(), "Flags should precede `...`"); + } $arg.short($crate::arg_impl! { @char $short }) }) @@ -488,7 +497,10 @@ macro_rules! arg_impl { ({ debug_assert_eq!($arg.get_long(), None, "Short flags should precede long flags"); debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values"); - debug_assert!(!$arg.is_multiple_occurrences_set(), "Flags should precede `...`"); + #[allow(deprecated)] + { + debug_assert!(!$arg.is_multiple_occurrences_set(), "Flags should precede `...`"); + } $arg.short($crate::arg_impl! { @char $short }) }) @@ -504,7 +516,10 @@ macro_rules! arg_impl { $crate::arg_impl! { @arg ({ - debug_assert!(!$arg.is_multiple_occurrences_set(), "Values should precede `...`"); + #[allow(deprecated)] + { + debug_assert!(!$arg.is_multiple_occurrences_set(), "Values should precede `...`"); + } debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported"); let mut arg = $arg; @@ -530,7 +545,10 @@ macro_rules! arg_impl { $crate::arg_impl! { @arg ({ - debug_assert!(!$arg.is_multiple_occurrences_set(), "Values should precede `...`"); + #[allow(deprecated)] + { + debug_assert!(!$arg.is_multiple_occurrences_set(), "Values should precede `...`"); + } debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported"); let mut arg = $arg; @@ -556,7 +574,10 @@ macro_rules! arg_impl { $crate::arg_impl! { @arg ({ - debug_assert!(!$arg.is_multiple_occurrences_set(), "Values should precede `...`"); + #[allow(deprecated)] + { + debug_assert!(!$arg.is_multiple_occurrences_set(), "Values should precede `...`"); + } debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported"); let mut arg = $arg; @@ -586,7 +607,10 @@ macro_rules! arg_impl { $crate::arg_impl! { @arg ({ - debug_assert!(!$arg.is_multiple_occurrences_set(), "Values should precede `...`"); + #[allow(deprecated)] + { + debug_assert!(!$arg.is_multiple_occurrences_set(), "Values should precede `...`"); + } debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported"); let mut arg = $arg; @@ -615,9 +639,9 @@ macro_rules! arg_impl { ) => { $crate::arg_impl! { @arg - ({ + ({#[allow(deprecated)]{ $arg.multiple_occurrences(true) - }) + }}) $($tail)* } }; diff --git a/src/parser/arg_matcher.rs b/src/parser/arg_matcher.rs index 2c94484a0afa..8d15c5799f41 100644 --- a/src/parser/arg_matcher.rs +++ b/src/parser/arg_matcher.rs @@ -230,6 +230,7 @@ impl ArgMatcher { true } else if let Some(num) = o.num_vals { debug!("ArgMatcher::needs_more_vals: num_vals...{}", num); + #[allow(deprecated)] if o.is_multiple_occurrences_set() { (current_num % num) != 0 } else { diff --git a/src/parser/validator.rs b/src/parser/validator.rs index f075d1a71e3b..ebf2b234d4c0 100644 --- a/src/parser/validator.rs +++ b/src/parser/validator.rs @@ -375,6 +375,7 @@ impl<'help, 'cmd> Validator<'help, 'cmd> { if let Some(num) = a.num_vals { let total_num = ma.num_vals(); debug!("Validator::validate_arg_num_vals: num_vals set...{}", num); + #[allow(deprecated)] let should_err = if a.is_multiple_occurrences_set() { total_num % num != 0 } else { @@ -386,6 +387,7 @@ impl<'help, 'cmd> Validator<'help, 'cmd> { self.cmd, a.to_string(), num, + #[allow(deprecated)] if a.is_multiple_occurrences_set() { total_num % num } else { diff --git a/tests/builder/grouped_values.rs b/tests/builder/grouped_values.rs index 4b5706c8fe09..03d1b5355c5e 100644 --- a/tests/builder/grouped_values.rs +++ b/tests/builder/grouped_values.rs @@ -10,7 +10,7 @@ fn grouped_value_works() { .long("option") .takes_value(true) .multiple_values(true) - .multiple_occurrences(true), + .action(ArgAction::Append), ) .try_get_matches_from(&[ "cli", @@ -42,7 +42,7 @@ fn issue_1026() { .long("target") .takes_value(true) .multiple_values(true) - .multiple_occurrences(true), + .action(ArgAction::Append), ) .try_get_matches_from(&[ "backup", "-s", "server", "-u", "user", "--target", "target1", "file1", "file2", @@ -70,7 +70,7 @@ fn grouped_value_long_flag_delimiter() { .takes_value(true) .use_value_delimiter(true) .multiple_values(true) - .multiple_occurrences(true), + .action(ArgAction::Append), ) .try_get_matches_from(vec![ "myapp", @@ -100,7 +100,7 @@ fn grouped_value_short_flag_delimiter() { .takes_value(true) .use_value_delimiter(true) .multiple_values(true) - .multiple_occurrences(true), + .action(ArgAction::Append), ) .try_get_matches_from(vec!["myapp", "-o=foo", "-o=val1,val2,val3", "-o=bar"]) .unwrap(); @@ -183,53 +183,41 @@ fn grouped_interleaved_positional_values() { .short('f') .long("flag") .takes_value(true) - .multiple_occurrences(true), + .action(ArgAction::Append), ); let m = cmd .try_get_matches_from(["foo", "1", "2", "-f", "a", "3", "-f", "b", "4"]) .unwrap(); + let pos: Vec<_> = m.grouped_values_of("pos").unwrap().collect(); assert_eq!(pos, vec![vec!["1", "2", "3", "4"]]); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("pos"), 4); - } + let flag: Vec<_> = m.grouped_values_of("flag").unwrap().collect(); assert_eq!(flag, vec![vec!["a"], vec!["b"]]); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("flag"), 2); - } } #[test] fn grouped_interleaved_positional_occurrences() { let cmd = clap::Command::new("foo") - .arg(clap::Arg::new("pos").multiple_occurrences(true)) + .arg(clap::Arg::new("pos").multiple_values(true)) .arg( clap::Arg::new("flag") .short('f') .long("flag") .takes_value(true) - .multiple_occurrences(true), + .action(ArgAction::Append), ); let m = cmd .try_get_matches_from(["foo", "1", "2", "-f", "a", "3", "-f", "b", "4"]) .unwrap(); + let pos: Vec<_> = m.grouped_values_of("pos").unwrap().collect(); - assert_eq!(pos, vec![vec!["1"], vec!["2"], vec!["3"], vec!["4"]]); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("pos"), 4); - } + assert_eq!(pos, vec![vec!["1", "2", "3", "4"]]); + let flag: Vec<_> = m.grouped_values_of("flag").unwrap().collect(); assert_eq!(flag, vec![vec!["a"], vec!["b"]]); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("flag"), 2); - } } #[test] @@ -240,7 +228,7 @@ fn issue_1374() { .long("input") .overrides_with("input") .min_values(0) - .multiple_occurrences(true), + .action(ArgAction::Append), ); let matches = cmd .clone() diff --git a/tests/builder/help.rs b/tests/builder/help.rs index 05e57cb074f5..6aaec5afee0b 100644 --- a/tests/builder/help.rs +++ b/tests/builder/help.rs @@ -1,6 +1,6 @@ use super::utils; -use clap::{arg, error::ErrorKind, Arg, ArgGroup, Command, PossibleValue}; +use clap::{arg, error::ErrorKind, Arg, ArgAction, ArgGroup, Command, PossibleValue}; static REQUIRE_DELIM_HELP: &str = "test 1.3 Kevin K. @@ -672,7 +672,7 @@ fn help_multi_subcommand_error() { ) .required(false) .multiple_values(true) - .multiple_occurrences(true), + .action(ArgAction::Append), ), ), ); @@ -720,7 +720,7 @@ fn args_with_last_usage() { .help("Prints out more stuff.") .short('v') .long("verbose") - .multiple_occurrences(true), + .action(ArgAction::SetTrue), ) .arg( Arg::new("timeout") @@ -822,7 +822,7 @@ fn multi_level_sc_help() { ) .required(false) .multiple_values(true) - .multiple_occurrences(true), + .action(ArgAction::Append), ), ), ); @@ -2514,7 +2514,8 @@ fn positional_multiple_occurrences_is_dotted() { Arg::new("foo") .required(true) .takes_value(true) - .multiple_occurrences(true), + .multiple_values(true) + .action(ArgAction::Append), ); utils::assert_output( cmd, @@ -2538,7 +2539,8 @@ OPTIONS: .required(true) .takes_value(true) .value_name("BAR") - .multiple_occurrences(true), + .multiple_values(true) + .action(ArgAction::Append), ); utils::assert_output( cmd, diff --git a/tests/builder/indices.rs b/tests/builder/indices.rs index 403cf86f579e..c5f236fd07c6 100644 --- a/tests/builder/indices.rs +++ b/tests/builder/indices.rs @@ -1,4 +1,4 @@ -use clap::{Arg, Command}; +use clap::{Arg, ArgAction, Command}; #[test] fn indices_mult_opts() { @@ -8,7 +8,7 @@ fn indices_mult_opts() { .short('e') .takes_value(true) .multiple_values(true) - .multiple_occurrences(true), + .action(ArgAction::Append), ) .arg( Arg::new("include") @@ -37,7 +37,7 @@ fn index_mult_opts() { .short('e') .takes_value(true) .multiple_values(true) - .multiple_occurrences(true), + .action(ArgAction::Append), ) .arg( Arg::new("include") @@ -67,88 +67,64 @@ fn index_flag() { #[test] fn index_flags() { let m = Command::new("ind") - .arg(Arg::new("exclude").short('e').multiple_occurrences(true)) - .arg(Arg::new("include").short('i').multiple_occurrences(true)) + .arg(Arg::new("exclude").short('e').action(ArgAction::SetTrue)) + .arg(Arg::new("include").short('i').action(ArgAction::SetTrue)) .try_get_matches_from(vec!["ind", "-e", "-i", "-e", "-e", "-i"]) .unwrap(); - assert_eq!(m.index_of("exclude"), Some(1)); - assert_eq!(m.index_of("include"), Some(2)); + assert_eq!(m.index_of("exclude"), Some(4)); + assert_eq!(m.index_of("include"), Some(5)); } #[test] fn indices_mult_flags() { let m = Command::new("ind") - .arg(Arg::new("exclude").short('e').multiple_occurrences(true)) - .arg(Arg::new("include").short('i').multiple_occurrences(true)) + .arg(Arg::new("exclude").short('e').action(ArgAction::SetTrue)) + .arg(Arg::new("include").short('i').action(ArgAction::SetTrue)) .try_get_matches_from(vec!["ind", "-e", "-i", "-e", "-e", "-i"]) .unwrap(); - assert_eq!( - m.indices_of("exclude").unwrap().collect::>(), - &[1, 3, 4] - ); - assert_eq!( - m.indices_of("include").unwrap().collect::>(), - &[2, 5] - ); + assert_eq!(m.indices_of("exclude").unwrap().collect::>(), &[4]); + assert_eq!(m.indices_of("include").unwrap().collect::>(), &[5]); } #[test] fn indices_mult_flags_combined() { let m = Command::new("ind") - .arg(Arg::new("exclude").short('e').multiple_occurrences(true)) - .arg(Arg::new("include").short('i').multiple_occurrences(true)) + .arg(Arg::new("exclude").short('e').action(ArgAction::SetTrue)) + .arg(Arg::new("include").short('i').action(ArgAction::SetTrue)) .try_get_matches_from(vec!["ind", "-eieei"]) .unwrap(); - assert_eq!( - m.indices_of("exclude").unwrap().collect::>(), - &[1, 3, 4] - ); - assert_eq!( - m.indices_of("include").unwrap().collect::>(), - &[2, 5] - ); + assert_eq!(m.indices_of("exclude").unwrap().collect::>(), &[4]); + assert_eq!(m.indices_of("include").unwrap().collect::>(), &[5]); } #[test] fn indices_mult_flags_opt_combined() { let m = Command::new("ind") - .arg(Arg::new("exclude").short('e').multiple_occurrences(true)) - .arg(Arg::new("include").short('i').multiple_occurrences(true)) + .arg(Arg::new("exclude").short('e').action(ArgAction::SetTrue)) + .arg(Arg::new("include").short('i').action(ArgAction::SetTrue)) .arg(Arg::new("option").short('o').takes_value(true)) .try_get_matches_from(vec!["ind", "-eieeio", "val"]) .unwrap(); - assert_eq!( - m.indices_of("exclude").unwrap().collect::>(), - &[1, 3, 4] - ); - assert_eq!( - m.indices_of("include").unwrap().collect::>(), - &[2, 5] - ); + assert_eq!(m.indices_of("exclude").unwrap().collect::>(), &[4]); + assert_eq!(m.indices_of("include").unwrap().collect::>(), &[5]); assert_eq!(m.indices_of("option").unwrap().collect::>(), &[7]); } #[test] fn indices_mult_flags_opt_combined_eq() { let m = Command::new("ind") - .arg(Arg::new("exclude").short('e').multiple_occurrences(true)) - .arg(Arg::new("include").short('i').multiple_occurrences(true)) + .arg(Arg::new("exclude").short('e').action(ArgAction::SetTrue)) + .arg(Arg::new("include").short('i').action(ArgAction::SetTrue)) .arg(Arg::new("option").short('o').takes_value(true)) .try_get_matches_from(vec!["ind", "-eieeio=val"]) .unwrap(); - assert_eq!( - m.indices_of("exclude").unwrap().collect::>(), - &[1, 3, 4] - ); - assert_eq!( - m.indices_of("include").unwrap().collect::>(), - &[2, 5] - ); + assert_eq!(m.indices_of("exclude").unwrap().collect::>(), &[4]); + assert_eq!(m.indices_of("include").unwrap().collect::>(), &[5]); assert_eq!(m.indices_of("option").unwrap().collect::>(), &[7]); } @@ -187,16 +163,11 @@ fn indices_mult_opt_value_no_delim_eq() { #[test] fn indices_mult_opt_mult_flag() { let m = Command::new("myapp") - .arg( - Arg::new("option") - .short('o') - .takes_value(true) - .multiple_occurrences(true), - ) - .arg(Arg::new("flag").short('f').multiple_occurrences(true)) + .arg(Arg::new("option").short('o').action(ArgAction::Append)) + .arg(Arg::new("flag").short('f').action(ArgAction::SetTrue)) .try_get_matches_from(vec!["myapp", "-o", "val1", "-f", "-o", "val2", "-f"]) .unwrap(); assert_eq!(m.indices_of("option").unwrap().collect::>(), &[2, 5]); - assert_eq!(m.indices_of("flag").unwrap().collect::>(), &[3, 6]); + assert_eq!(m.indices_of("flag").unwrap().collect::>(), &[6]); } diff --git a/tests/builder/multiple_occurrences.rs b/tests/builder/multiple_occurrences.rs index fac64d0a983f..3159a8efd205 100644 --- a/tests/builder/multiple_occurrences.rs +++ b/tests/builder/multiple_occurrences.rs @@ -1,89 +1,44 @@ -use clap::{arg, error::ErrorKind, Arg, Command}; +use clap::{arg, Arg, ArgAction, Command}; #[test] fn multiple_occurrences_of_flags_long() { let m = Command::new("mo_flags_long") - .arg(arg!(--multflag "allowed multiple flag").multiple_occurrences(true)) - .arg(arg!(--flag "disallowed multiple flag")) + .arg(arg!(--multflag "allowed multiple flag").action(ArgAction::SetTrue)) + .arg(arg!(--flag "disallowed multiple flag").action(ArgAction::SetTrue)) .try_get_matches_from(vec!["", "--multflag", "--flag", "--multflag"]) .unwrap(); assert!(m.is_present("multflag")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("multflag"), 2); - } + assert_eq!(m.get_one::("multflag").copied(), Some(true)); assert!(m.is_present("flag")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("flag"), 1); - } + assert_eq!(m.get_one::("flag").copied(), Some(true)); } #[test] fn multiple_occurrences_of_flags_short() { let m = Command::new("mo_flags_short") - .arg(arg!(-m --multflag "allowed multiple flag").multiple_occurrences(true)) - .arg(arg!(-f --flag "disallowed multiple flag")) + .arg(arg!(-m --multflag "allowed multiple flag").action(ArgAction::SetTrue)) + .arg(arg!(-f --flag "disallowed multiple flag").action(ArgAction::SetTrue)) .try_get_matches_from(vec!["", "-m", "-f", "-m"]) .unwrap(); assert!(m.is_present("multflag")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("multflag"), 2); - } + assert_eq!(m.get_one::("multflag").copied(), Some(true)); assert!(m.is_present("flag")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("flag"), 1); - } -} - -#[test] -fn multiple_occurrences_of_flags_mixed() { - let m = Command::new("mo_flags_mixed") - .arg(arg!(-m --multflag1 "allowed multiple flag").multiple_occurrences(true)) - .arg(arg!(-n --multflag2 "another allowed multiple flag").multiple_occurrences(true)) - .arg(arg!(-f --flag "disallowed multiple flag")) - .try_get_matches_from(vec![ - "", - "-m", - "-f", - "-n", - "--multflag1", - "-m", - "--multflag2", - ]) - .unwrap(); - assert!(m.is_present("multflag1")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("multflag1"), 3); - } - assert!(m.is_present("multflag2")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("multflag2"), 2); - } - assert!(m.is_present("flag")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("flag"), 1); - } + assert_eq!(m.get_one::("flag").copied(), Some(true)); } #[test] fn multiple_occurrences_of_positional() { - let cmd = Command::new("test").arg(Arg::new("multi").multiple_occurrences(true)); + let cmd = Command::new("test").arg( + Arg::new("multi") + .multiple_values(true) + .action(ArgAction::Append), + ); let m = cmd .clone() .try_get_matches_from(&["test"]) .expect("zero occurrences work"); assert!(!m.is_present("multi")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("multi"), 0); - } assert!(m.get_many::("multi").is_none()); let m = cmd @@ -91,10 +46,6 @@ fn multiple_occurrences_of_positional() { .try_get_matches_from(&["test", "one"]) .expect("single occurrence work"); assert!(m.is_present("multi")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("multi"), 1); - } assert_eq!( m.get_many::("multi") .unwrap() @@ -108,10 +59,6 @@ fn multiple_occurrences_of_positional() { .try_get_matches_from(&["test", "one", "two", "three", "four"]) .expect("many occurrences work"); assert!(m.is_present("multi")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("multi"), 4); - } assert_eq!( m.get_many::("multi") .unwrap() @@ -128,14 +75,11 @@ fn multiple_occurrences_of_flags_large_quantity() { .chain(vec!["-m"; 1024].into_iter()) .collect(); let m = Command::new("mo_flags_large_qty") - .arg(arg!(-m --multflag "allowed multiple flag").multiple_occurrences(true)) + .arg(arg!(-m --multflag "allowed multiple flag").action(ArgAction::Count)) .try_get_matches_from(args) .unwrap(); assert!(m.is_present("multflag")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("multflag"), 1024); - } + assert_eq!(m.get_one::("multflag").copied(), Some(1024)); } #[cfg(feature = "env")] @@ -147,35 +91,28 @@ fn multiple_occurrences_of_before_env() { .short('v') .long("verbose") .takes_value(false) - .multiple_occurrences(true), + .action(ArgAction::Count), ); let m = cmd.clone().try_get_matches_from(vec![""]); assert!(m.is_ok(), "{}", m.unwrap_err()); - #[allow(deprecated)] - { - assert_eq!(m.unwrap().occurrences_of("verbose"), 0); - } + let m = m.unwrap(); + assert_eq!(m.get_one::("verbose").copied(), Some(0)); let m = cmd.clone().try_get_matches_from(vec!["", "-v"]); assert!(m.is_ok(), "{}", m.unwrap_err()); - #[allow(deprecated)] - { - assert_eq!(m.unwrap().occurrences_of("verbose"), 1); - } + let m = m.unwrap(); + assert_eq!(m.get_one::("verbose").copied(), Some(1)); let m = cmd.clone().try_get_matches_from(vec!["", "-vv"]); assert!(m.is_ok(), "{}", m.unwrap_err()); - #[allow(deprecated)] - { - assert_eq!(m.unwrap().occurrences_of("verbose"), 2); - } + let m = m.unwrap(); + assert_eq!(m.get_one::("verbose").copied(), Some(2)); + let m = cmd.clone().try_get_matches_from(vec!["", "-vvv"]); assert!(m.is_ok(), "{}", m.unwrap_err()); - #[allow(deprecated)] - { - assert_eq!(m.unwrap().occurrences_of("verbose"), 3); - } + let m = m.unwrap(); + assert_eq!(m.get_one::("verbose").copied(), Some(3)); } #[cfg(feature = "env")] @@ -186,149 +123,27 @@ fn multiple_occurrences_of_after_env() { .short('v') .long("verbose") .takes_value(false) - .multiple_occurrences(true) + .action(ArgAction::Count) .env("VERBOSE"), ); let m = cmd.clone().try_get_matches_from(vec![""]); assert!(m.is_ok(), "{}", m.unwrap_err()); - #[allow(deprecated)] - { - assert_eq!(m.unwrap().occurrences_of("verbose"), 0); - } + let m = m.unwrap(); + assert_eq!(m.get_one::("verbose").copied(), Some(0)); let m = cmd.clone().try_get_matches_from(vec!["", "-v"]); assert!(m.is_ok(), "{}", m.unwrap_err()); - #[allow(deprecated)] - { - assert_eq!(m.unwrap().occurrences_of("verbose"), 1); - } + let m = m.unwrap(); + assert_eq!(m.get_one::("verbose").copied(), Some(1)); let m = cmd.clone().try_get_matches_from(vec!["", "-vv"]); assert!(m.is_ok(), "{}", m.unwrap_err()); - #[allow(deprecated)] - { - assert_eq!(m.unwrap().occurrences_of("verbose"), 2); - } - let m = cmd.clone().try_get_matches_from(vec!["", "-vvv"]); - assert!(m.is_ok(), "{}", m.unwrap_err()); - #[allow(deprecated)] - { - assert_eq!(m.unwrap().occurrences_of("verbose"), 3); - } -} + let m = m.unwrap(); + assert_eq!(m.get_one::("verbose").copied(), Some(2)); -#[test] -#[allow(deprecated)] -fn max_occurrences_implies_multiple_occurrences() { - let cmd = Command::new("prog").arg( - Arg::new("verbose") - .short('v') - .long("verbose") - .max_occurrences(3), - ); - let m = cmd.try_get_matches_from(vec!["prog", "-vvv"]); - - assert!(m.is_ok(), "{}", m.unwrap_err()); - #[allow(deprecated)] - { - assert_eq!(m.unwrap().occurrences_of("verbose"), 3); - } - - // One max should not imply multiple occurrences - let cmd = Command::new("prog").arg( - Arg::new("verbose") - .short('v') - .long("verbose") - .max_occurrences(1), - ); - - let m = cmd.try_get_matches_from(vec!["prog", "-vvv"]); - - assert!(m.is_err()); - assert_eq!(m.unwrap_err().kind(), ErrorKind::UnexpectedMultipleUsage); -} - -#[test] -#[allow(deprecated)] -fn max_occurrences_try_inputs() { - let cmd = Command::new("prog").arg( - Arg::new("verbose") - .short('v') - .long("verbose") - .max_occurrences(3), - ); - let m = cmd.clone().try_get_matches_from(vec!["prog", "-v"]); - assert!(m.is_ok(), "{}", m.unwrap_err()); - #[allow(deprecated)] - { - assert_eq!(m.unwrap().occurrences_of("verbose"), 1); - } - - let m = cmd.clone().try_get_matches_from(vec!["prog", "-vv"]); - assert!(m.is_ok(), "{}", m.unwrap_err()); - #[allow(deprecated)] - { - assert_eq!(m.unwrap().occurrences_of("verbose"), 2); - } - - let m = cmd.clone().try_get_matches_from(vec!["prog", "-vvv"]); - assert!(m.is_ok(), "{}", m.unwrap_err()); - #[allow(deprecated)] - { - assert_eq!(m.unwrap().occurrences_of("verbose"), 3); - } - - let m = cmd.clone().try_get_matches_from(vec!["prog", "-vvvv"]); - assert!(m.is_err()); - assert_eq!(m.unwrap_err().kind(), ErrorKind::TooManyOccurrences); - - let m = cmd - .clone() - .try_get_matches_from(vec!["prog", "-v", "-v", "-v"]); - assert!(m.is_ok(), "{}", m.unwrap_err()); - #[allow(deprecated)] - { - assert_eq!(m.unwrap().occurrences_of("verbose"), 3); - } - - let m = cmd - .clone() - .try_get_matches_from(vec!["prog", "-v", "-vv", "-v"]); - assert!(m.is_err()); - assert_eq!(m.unwrap_err().kind(), ErrorKind::TooManyOccurrences); -} - -#[test] -#[allow(deprecated)] -fn max_occurrences_positional() { - let cmd = Command::new("prog").arg(Arg::new("verbose").max_occurrences(3)); - let m = cmd.clone().try_get_matches_from(vec!["prog", "v"]); - assert!(m.is_ok(), "{}", m.unwrap_err()); - #[allow(deprecated)] - { - assert_eq!(m.unwrap().occurrences_of("verbose"), 1); - } - - let m = cmd.clone().try_get_matches_from(vec!["prog", "v", "v"]); - assert!(m.is_ok(), "{}", m.unwrap_err()); - #[allow(deprecated)] - { - assert_eq!(m.unwrap().occurrences_of("verbose"), 2); - } - - let m = cmd - .clone() - .try_get_matches_from(vec!["prog", "v", "v", "v"]); + let m = cmd.clone().try_get_matches_from(vec!["", "-vvv"]); assert!(m.is_ok(), "{}", m.unwrap_err()); - #[allow(deprecated)] - { - assert_eq!(m.unwrap().occurrences_of("verbose"), 3); - } - - let m = cmd - .clone() - .try_get_matches_from(vec!["prog", "v", "v", "v", "v"]); - assert!(m.is_err()); - assert_eq!(m.unwrap_err().kind(), ErrorKind::TooManyOccurrences); + let m = m.unwrap(); + assert_eq!(m.get_one::("verbose").copied(), Some(3)); } diff --git a/tests/builder/multiple_values.rs b/tests/builder/multiple_values.rs index 84d2cd412daf..d4fe7d19e616 100644 --- a/tests/builder/multiple_values.rs +++ b/tests/builder/multiple_values.rs @@ -1,4 +1,4 @@ -use clap::{error::ErrorKind, Arg, Command}; +use clap::{error::ErrorKind, Arg, ArgAction, Command}; #[test] fn option_long() { @@ -9,7 +9,7 @@ fn option_long() { .help("multiple options") .takes_value(true) .multiple_values(true) - .multiple_occurrences(true), + .action(ArgAction::Append), ) .try_get_matches_from(vec![ "", "--option", "val1", "--option", "val2", "--option", "val3", @@ -19,10 +19,6 @@ fn option_long() { let m = m.unwrap(); assert!(m.is_present("option")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("option"), 3); - } assert_eq!( m.get_many::("option") .unwrap() @@ -41,7 +37,7 @@ fn option_short() { .help("multiple options") .takes_value(true) .multiple_values(true) - .multiple_occurrences(true), + .action(ArgAction::Append), ) .try_get_matches_from(vec!["", "-o", "val1", "-o", "val2", "-o", "val3"]); @@ -49,10 +45,6 @@ fn option_short() { let m = m.unwrap(); assert!(m.is_present("option")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("option"), 3); - } assert_eq!( m.get_many::("option") .unwrap() @@ -72,7 +64,7 @@ fn option_mixed() { .help("multiple options") .takes_value(true) .multiple_values(true) - .multiple_occurrences(true), + .action(ArgAction::Append), ) .try_get_matches_from(vec![ "", "-o", "val1", "--option", "val2", "--option", "val3", "-o", "val4", @@ -82,10 +74,6 @@ fn option_mixed() { let m = m.unwrap(); assert!(m.is_present("option")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("option"), 4); - } assert_eq!( m.get_many::("option") .unwrap() @@ -103,7 +91,7 @@ fn option_exact_exact() { .short('o') .help("multiple options") .number_of_values(3) - .multiple_occurrences(true), + .action(ArgAction::Append), ) .try_get_matches_from(vec!["", "-o", "val1", "-o", "val2", "-o", "val3"]); @@ -111,10 +99,6 @@ fn option_exact_exact() { let m = m.unwrap(); assert!(m.is_present("option")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("option"), 3); - } assert_eq!( m.get_many::("option") .unwrap() @@ -139,10 +123,6 @@ fn option_exact_exact_not_mult() { let m = m.unwrap(); assert!(m.is_present("option")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("option"), 1); - } assert_eq!( m.get_many::("option") .unwrap() @@ -160,7 +140,7 @@ fn option_exact_exact_mult() { .short('o') .help("multiple options") .number_of_values(3) - .multiple_occurrences(true), + .action(ArgAction::Append), ) .try_get_matches_from(vec![ "", "-o", "val1", "val2", "val3", "-o", "val4", "val5", "val6", @@ -170,10 +150,6 @@ fn option_exact_exact_mult() { let m = m.unwrap(); assert!(m.is_present("option")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("option"), 2); - } assert_eq!( m.get_many::("option") .unwrap() @@ -191,7 +167,7 @@ fn option_exact_less() { .short('o') .help("multiple options") .number_of_values(3) - .multiple_occurrences(true), + .action(ArgAction::Append), ) .try_get_matches_from(vec!["", "-o", "val1", "-o", "val2"]); @@ -207,7 +183,7 @@ fn option_exact_more() { .short('o') .help("multiple options") .number_of_values(3) - .multiple_occurrences(true), + .action(ArgAction::Append), ) .try_get_matches_from(vec![ "", "-o", "val1", "-o", "val2", "-o", "val3", "-o", "val4", @@ -225,7 +201,7 @@ fn option_min_exact() { .short('o') .help("multiple options") .min_values(3) - .multiple_occurrences(true), + .action(ArgAction::Append), ) .try_get_matches_from(vec!["", "-o", "val1", "-o", "val2", "-o", "val3"]); @@ -233,10 +209,6 @@ fn option_min_exact() { let m = m.unwrap(); assert!(m.is_present("option")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("option"), 3); - } assert_eq!( m.get_many::("option") .unwrap() @@ -254,7 +226,7 @@ fn option_min_less() { .short('o') .help("multiple options") .min_values(3) - .multiple_occurrences(true), + .action(ArgAction::Append), ) .try_get_matches_from(vec!["", "-o", "val1", "-o", "val2"]); @@ -271,7 +243,7 @@ fn option_short_min_more_mult_occurs() { .short('o') .help("multiple options") .min_values(3) - .multiple_occurrences(true), + .action(ArgAction::Append), ) .try_get_matches_from(vec![ "", "pos", "-o", "val1", "-o", "val2", "-o", "val3", "-o", "val4", @@ -282,10 +254,6 @@ fn option_short_min_more_mult_occurs() { assert!(m.is_present("option")); assert!(m.is_present("arg")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("option"), 4); - } assert_eq!( m.get_many::("option") .unwrap() @@ -313,10 +281,6 @@ fn option_short_min_more_single_occur() { assert!(m.is_present("option")); assert!(m.is_present("arg")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("option"), 1); - } assert_eq!( m.get_many::("option") .unwrap() @@ -335,7 +299,7 @@ fn option_max_exact() { .short('o') .help("multiple options") .max_values(3) - .multiple_occurrences(true), + .action(ArgAction::Append), ) .try_get_matches_from(vec!["", "-o", "val1", "-o", "val2", "-o", "val3"]); @@ -343,10 +307,6 @@ fn option_max_exact() { let m = m.unwrap(); assert!(m.is_present("option")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("option"), 3); - } assert_eq!( m.get_many::("option") .unwrap() @@ -364,7 +324,7 @@ fn option_max_less() { .short('o') .help("multiple options") .max_values(3) - .multiple_occurrences(true), + .action(ArgAction::Append), ) .try_get_matches_from(vec!["", "-o", "val1", "-o", "val2"]); @@ -372,10 +332,6 @@ fn option_max_less() { let m = m.unwrap(); assert!(m.is_present("option")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("option"), 2); - } assert_eq!( m.get_many::("option") .unwrap() @@ -393,7 +349,7 @@ fn option_max_more() { .short('o') .help("multiple options") .max_values(3) - .multiple_occurrences(true), + .action(ArgAction::Append), ) .try_get_matches_from(vec![ "", "-o", "val1", "-o", "val2", "-o", "val3", "-o", "val4", @@ -418,10 +374,6 @@ fn positional() { let m = m.unwrap(); assert!(m.is_present("pos")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("pos"), 3); - } assert_eq!( m.get_many::("pos") .unwrap() @@ -445,10 +397,6 @@ fn positional_exact_exact() { let m = m.unwrap(); assert!(m.is_present("pos")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("pos"), 3); - } assert_eq!( m.get_many::("pos") .unwrap() @@ -496,10 +444,6 @@ fn positional_min_exact() { let m = m.unwrap(); assert!(m.is_present("pos")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("pos"), 3); - } assert_eq!( m.get_many::("pos") .unwrap() @@ -529,10 +473,6 @@ fn positional_min_more() { let m = m.unwrap(); assert!(m.is_present("pos")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("pos"), 4); - } assert_eq!( m.get_many::("pos") .unwrap() @@ -552,10 +492,6 @@ fn positional_max_exact() { let m = m.unwrap(); assert!(m.is_present("pos")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("pos"), 3); - } assert_eq!( m.get_many::("pos") .unwrap() @@ -575,10 +511,6 @@ fn positional_max_less() { let m = m.unwrap(); assert!(m.is_present("pos")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("pos"), 2); - } assert_eq!( m.get_many::("pos") .unwrap() @@ -613,10 +545,6 @@ fn sep_long_equals() { let m = m.unwrap(); assert!(m.is_present("option")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("option"), 1); - } assert_eq!( m.get_many::("option") .unwrap() @@ -641,10 +569,6 @@ fn sep_long_space() { let m = m.unwrap(); assert!(m.is_present("option")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("option"), 1); - } assert_eq!( m.get_many::("option") .unwrap() @@ -669,10 +593,6 @@ fn sep_short_equals() { let m = m.unwrap(); assert!(m.is_present("option")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("option"), 1); - } assert_eq!( m.get_many::("option") .unwrap() @@ -697,10 +617,6 @@ fn sep_short_space() { let m = m.unwrap(); assert!(m.is_present("option")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("option"), 1); - } assert_eq!( m.get_many::("option") .unwrap() @@ -725,10 +641,6 @@ fn sep_short_no_space() { let m = m.unwrap(); assert!(m.is_present("option")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("option"), 1); - } assert_eq!( m.get_many::("option") .unwrap() @@ -752,10 +664,6 @@ fn sep_positional() { let m = m.unwrap(); assert!(m.is_present("option")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("option"), 1); - } assert_eq!( m.get_many::("option") .unwrap() @@ -780,10 +688,6 @@ fn different_sep() { let m = m.unwrap(); assert!(m.is_present("option")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("option"), 1); - } assert_eq!( m.get_many::("option") .unwrap() @@ -807,10 +711,6 @@ fn different_sep_positional() { let m = m.unwrap(); assert!(m.is_present("option")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("option"), 1); - } assert_eq!( m.get_many::("option") .unwrap() @@ -836,10 +736,6 @@ fn no_sep() { let m = m.unwrap(); assert!(m.is_present("option")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("option"), 1); - } assert_eq!( m.get_one::("option").map(|v| v.as_str()).unwrap(), "val1,val2,val3" @@ -861,10 +757,6 @@ fn no_sep_positional() { let m = m.unwrap(); assert!(m.is_present("option")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("option"), 1); - } assert_eq!( m.get_one::("option").map(|v| v.as_str()).unwrap(), "val1,val2,val3" @@ -893,10 +785,6 @@ fn req_delimiter_long() { let m = m.unwrap(); assert!(m.is_present("option")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("option"), 1); - } assert_eq!( m.get_many::("option") .unwrap() @@ -935,10 +823,6 @@ fn req_delimiter_long_with_equal() { let m = m.unwrap(); assert!(m.is_present("option")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("option"), 1); - } assert_eq!( m.get_many::("option") .unwrap() @@ -977,10 +861,6 @@ fn req_delimiter_short_with_space() { let m = m.unwrap(); assert!(m.is_present("option")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("option"), 1); - } assert_eq!( m.get_many::("option") .unwrap() @@ -1019,10 +899,6 @@ fn req_delimiter_short_with_no_space() { let m = m.unwrap(); assert!(m.is_present("option")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("option"), 1); - } assert_eq!( m.get_many::("option") .unwrap() @@ -1061,10 +937,6 @@ fn req_delimiter_short_with_equal() { let m = m.unwrap(); assert!(m.is_present("option")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("option"), 1); - } assert_eq!( m.get_many::("option") .unwrap() @@ -1089,7 +961,7 @@ fn req_delimiter_complex() { .long("option") .short('o') .multiple_values(true) - .multiple_occurrences(true) + .action(ArgAction::Append) .use_value_delimiter(true) .require_value_delimiter(true), ) @@ -1132,10 +1004,6 @@ fn req_delimiter_complex() { let m = m.unwrap(); assert!(m.is_present("option")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("option"), 10); - } assert_eq!( m.get_many::("option") .unwrap() @@ -1238,15 +1106,6 @@ fn low_index_positional() { let m = m.unwrap(); assert!(m.is_present("files")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("files"), 3); - } - assert!(m.is_present("target")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("target"), 1); - } assert_eq!( m.get_many::("files") .unwrap() @@ -1254,6 +1113,7 @@ fn low_index_positional() { .collect::>(), ["file1", "file2", "file3"] ); + assert!(m.is_present("target")); assert_eq!( m.get_one::("target").map(|v| v.as_str()).unwrap(), "target" @@ -1281,15 +1141,6 @@ fn low_index_positional_in_subcmd() { let sm = m.subcommand_matches("test").unwrap(); assert!(sm.is_present("files")); - #[allow(deprecated)] - { - assert_eq!(sm.occurrences_of("files"), 3); - } - assert!(sm.is_present("target")); - #[allow(deprecated)] - { - assert_eq!(sm.occurrences_of("target"), 1); - } assert_eq!( sm.get_many::("files") .unwrap() @@ -1297,6 +1148,7 @@ fn low_index_positional_in_subcmd() { .collect::>(), ["file1", "file2", "file3"] ); + assert!(sm.is_present("target")); assert_eq!( sm.get_one::("target").map(|v| v.as_str()).unwrap(), "target" @@ -1323,15 +1175,6 @@ fn low_index_positional_with_option() { let m = m.unwrap(); assert!(m.is_present("files")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("files"), 3); - } - assert!(m.is_present("target")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("target"), 1); - } assert_eq!( m.get_many::("files") .unwrap() @@ -1339,6 +1182,7 @@ fn low_index_positional_with_option() { .collect::>(), ["file1", "file2", "file3"] ); + assert!(m.is_present("target")); assert_eq!( m.get_one::("target").map(|v| v.as_str()).unwrap(), "target" @@ -1367,15 +1211,6 @@ fn low_index_positional_with_flag() { let m = m.unwrap(); assert!(m.is_present("files")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("files"), 3); - } - assert!(m.is_present("target")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("target"), 1); - } assert_eq!( m.get_many::("files") .unwrap() @@ -1383,6 +1218,7 @@ fn low_index_positional_with_flag() { .collect::>(), ["file1", "file2", "file3"] ); + assert!(m.is_present("target")); assert_eq!( m.get_one::("target").map(|v| v.as_str()).unwrap(), "target" @@ -1407,10 +1243,6 @@ fn multiple_value_terminator_option() { let m = m.unwrap(); assert!(m.is_present("other")); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("other"), 1); - } assert!(m.is_present("files")); assert_eq!( m.get_many::("files") @@ -1609,7 +1441,7 @@ fn values_per_occurrence_named() { Arg::new("pos") .long("pos") .number_of_values(2) - .multiple_occurrences(true), + .action(ArgAction::Append), ); let m = a.try_get_matches_from_mut(vec!["myprog", "--pos", "val1", "val2"]); @@ -1624,10 +1456,6 @@ fn values_per_occurrence_named() { .collect::>(), ["val1", "val2"] ); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("pos"), 1); - } let m = a.try_get_matches_from_mut(vec![ "myprog", "--pos", "val1", "val2", "--pos", "val3", "val4", @@ -1643,10 +1471,6 @@ fn values_per_occurrence_named() { .collect::>(), ["val1", "val2", "val3", "val4"] ); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("pos"), 2); - } } #[test] @@ -1654,7 +1478,7 @@ fn values_per_occurrence_positional() { let mut a = Command::new("test").arg( Arg::new("pos") .number_of_values(2) - .multiple_occurrences(true), + .action(ArgAction::Append), ); let m = a.try_get_matches_from_mut(vec!["myprog", "val1", "val2"]); @@ -1669,59 +1493,4 @@ fn values_per_occurrence_positional() { .collect::>(), ["val1", "val2"] ); - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("pos"), 2); - } - - let m = a.try_get_matches_from_mut(vec!["myprog", "val1", "val2", "val3", "val4"]); - let m = match m { - Ok(m) => m, - Err(err) => panic!("{}", err), - }; - assert_eq!( - m.get_many::("pos") - .unwrap() - .map(|v| v.as_str()) - .collect::>(), - ["val1", "val2", "val3", "val4"] - ); - //#[allow(deprecated)]{assert_eq!(m.occurrences_of("pos"), 2);} // Fails, we don't recognize this as two occurrences -} - -// Theoretically we could support this but we aren't tracking occurrence boundaries for positionals -#[test] -#[should_panic = "When using a positional argument with .multiple_values(true) that is *not the last* positional argument, the last positional argument (i.e. the one with the highest index) *must* have .required(true) or .last(true) set."] -fn positional_parser_advances() { - let m = Command::new("multiple_values") - .arg(Arg::new("pos1").number_of_values(2)) - .arg(Arg::new("pos2").number_of_values(2)) - .try_get_matches_from(vec!["myprog", "val1", "val2", "val3", "val4"]); - - assert!(m.is_ok(), "{}", m.unwrap_err()); - let m = m.unwrap(); - - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("pos1"), 1); - } - assert_eq!( - m.get_many::("pos1") - .unwrap() - .map(|v| v.as_str()) - .collect::>(), - ["val1", "val2"] - ); - - #[allow(deprecated)] - { - assert_eq!(m.occurrences_of("pos2"), 1); - } - assert_eq!( - m.get_many::("pos2") - .unwrap() - .map(|v| v.as_str()) - .collect::>(), - ["val3", "val4"] - ); } diff --git a/tests/builder/posix_compatible.rs b/tests/builder/posix_compatible.rs index db1c8f8940cc..159f2dce85ed 100644 --- a/tests/builder/posix_compatible.rs +++ b/tests/builder/posix_compatible.rs @@ -1,4 +1,4 @@ -use clap::{arg, error::ErrorKind, Arg, Command}; +use clap::{arg, error::ErrorKind, Arg, ArgAction, Command}; #[test] fn flag_overrides_itself() { @@ -454,7 +454,7 @@ fn issue_1374_overrides_self_with_multiple_values() { #[test] fn incremental_override() { let mut cmd = Command::new("test") - .arg(arg!(--name ).multiple_occurrences(true)) + .arg(arg!(--name ).action(ArgAction::Append)) .arg(arg!(--"no-name").overrides_with("name")); let m = cmd .try_get_matches_from_mut(&["test", "--name=ahmed", "--no-name", "--name=ali"]) diff --git a/tests/builder/possible_values.rs b/tests/builder/possible_values.rs index be04a98257d5..bb6c51f50b21 100644 --- a/tests/builder/possible_values.rs +++ b/tests/builder/possible_values.rs @@ -1,6 +1,6 @@ use super::utils; -use clap::{error::ErrorKind, Arg, Command, PossibleValue}; +use clap::{error::ErrorKind, Arg, ArgAction, Command, PossibleValue}; #[cfg(feature = "suggestions")] static PV_ERROR: &str = "error: \"slo\" isn't a valid value for '-O