Skip to content

Commit

Permalink
fix(parser): Deprecate multiple_occurrences
Browse files Browse the repository at this point in the history
Fixes #3772
  • Loading branch information
epage committed Jun 8, 2022
1 parent b78a0e6 commit 934dfe5
Show file tree
Hide file tree
Showing 27 changed files with 260 additions and 698 deletions.
15 changes: 7 additions & 8 deletions 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"];
Expand Down Expand Up @@ -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(
Expand All @@ -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")
Expand Down Expand Up @@ -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),
Expand All @@ -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"]),
)
Expand All @@ -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),
)
Expand All @@ -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),
)
Expand All @@ -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")),
Expand Down
8 changes: 4 additions & 4 deletions 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;

Expand Down Expand Up @@ -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),
)
}

Expand All @@ -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")
Expand All @@ -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")
Expand Down
29 changes: 12 additions & 17 deletions clap_bench/benches/05_ripgrep.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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"),
)
Expand All @@ -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"),
)
Expand All @@ -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.
Expand Down Expand Up @@ -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"))
Expand All @@ -427,7 +422,7 @@ where
.arg(
flag("ignore-file")
.value_name("FILE")
.multiple_occurrences(true),
.action(ArgAction::Append),
)
.arg(flag("follow").short('L'))
.arg(
Expand Down Expand Up @@ -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),
)
}

Expand Down
3 changes: 1 addition & 2 deletions clap_bench/benches/06_rustup.rs
Expand Up @@ -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(
Expand Down
3 changes: 3 additions & 0 deletions clap_complete/src/shells/zsh.rs
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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() {
Expand Down
6 changes: 3 additions & 3 deletions clap_complete/tests/common.rs
Expand Up @@ -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),
),
)
}
Expand All @@ -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')
Expand Down Expand Up @@ -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"))
Expand Down
2 changes: 2 additions & 0 deletions clap_complete_fig/src/fig.rs
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
6 changes: 3 additions & 3 deletions clap_complete_fig/tests/common.rs
Expand Up @@ -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),
),
)
}
Expand All @@ -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')
Expand Down Expand Up @@ -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"))
Expand Down
1 change: 1 addition & 0 deletions clap_complete_fig/tests/snapshots/special_commands.fig.js
Expand Up @@ -49,6 +49,7 @@ const completion: Fig.Spec = {
],
args: {
name: "path",
isVariadic: true,
isOptional: true,
},
},
Expand Down
2 changes: 1 addition & 1 deletion examples/escaped-positional.rs
Expand Up @@ -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)),
)
Expand Down
2 changes: 1 addition & 1 deletion examples/typed-derive.rs
Expand Up @@ -22,7 +22,7 @@ struct Args {
sleep: Option<humantime::Duration>,

/// Hand-written parser for tuples
#[clap(short = 'D', value_parser = parse_key_val::<String, i32>, multiple_occurrences(true))]
#[clap(short = 'D', value_parser = parse_key_val::<String, i32>)]
defines: Vec<(String, i32)>,
}

Expand Down
50 changes: 4 additions & 46 deletions src/builder/arg.rs
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
}
Expand Down

0 comments on commit 934dfe5

Please sign in to comment.