Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(help): Show when a flag 'ArgAction::Count's #4003

Merged
merged 2 commits into from Jul 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -52,6 +52,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- *(assert)* Ensure no self-`overrides_with` now that Actions replace it
- *(assert)* Ensure subcommand names are not duplicated
- *(help)* Use `Command::display_name` in the help title rather than `Command::bin_name`
- *(help)* Show when a flag is `ArgAction::Count` by adding an `...`
- *(version)* Use `Command::display_name` rather than `Command::bin_name`
- *(parser)* Assert on unknown args when using external subcommands (#3703)
- *(parser)* Always fill in `""` argument for external subcommands (#3263)
Expand Down
2 changes: 1 addition & 1 deletion examples/tutorial_builder/01_quick.md
Expand Up @@ -11,7 +11,7 @@ ARGS:

OPTIONS:
-c, --config <FILE> Sets a custom config file
-d, --debug Turn debugging information on
-d, --debug... Turn debugging information on
-h, --help Print help information
-V, --version Print version information

Expand Down
6 changes: 3 additions & 3 deletions examples/tutorial_builder/03_01_flag_count.md
Expand Up @@ -7,9 +7,9 @@ USAGE:
03_01_flag_count[EXE] [OPTIONS]

OPTIONS:
-v, --verbose
-h, --help Print help information
-V, --version Print version information
-v, --verbose...
-h, --help Print help information
-V, --version Print version information

$ 03_01_flag_count
verbose: 0
Expand Down
2 changes: 1 addition & 1 deletion examples/tutorial_derive/01_quick.md
Expand Up @@ -11,7 +11,7 @@ ARGS:

OPTIONS:
-c, --config <FILE> Sets a custom config file
-d, --debug Turn debugging information on
-d, --debug... Turn debugging information on
-h, --help Print help information
-V, --version Print version information

Expand Down
6 changes: 3 additions & 3 deletions examples/tutorial_derive/03_01_flag_count.md
Expand Up @@ -7,9 +7,9 @@ USAGE:
03_01_flag_count[EXE] [OPTIONS]

OPTIONS:
-v, --verbose
-h, --help Print help information
-V, --version Print version information
-v, --verbose...
-h, --help Print help information
-V, --version Print version information

$ 03_01_flag_count
verbose: 0
Expand Down
25 changes: 16 additions & 9 deletions src/builder/arg.rs
Expand Up @@ -4448,6 +4448,8 @@ impl<'help> Display for Arg<'help> {
if self.is_takes_value_set() || self.is_positional() {
let arg_val = render_arg_val(self);
f.write_str(&arg_val)?;
} else if matches!(*self.get_action(), ArgAction::Count) {
f.write_str("...")?;
}
if need_closing_bracket {
f.write_str("]")?;
Expand Down Expand Up @@ -4566,14 +4568,8 @@ pub(crate) fn render_arg_val(arg: &Arg) -> String {
}
extra_values |= val_names.len() < num_vals.max_values();
}
if arg.is_positional() {
if matches!(*arg.get_action(), ArgAction::Append) {
extra_values = true;
}
} else {
if matches!(*arg.get_action(), ArgAction::Count) {
extra_values = true;
}
if arg.is_positional() && matches!(*arg.get_action(), ArgAction::Append) {
extra_values = true;
}

if extra_values {
Expand All @@ -4590,18 +4586,29 @@ mod test {
use super::ArgAction;

#[test]
fn flag_display() {
fn flag_display_long() {
let mut f = Arg::new("flg").long("flag").action(ArgAction::SetTrue);
f._build();

assert_eq!(f.to_string(), "--flag");
}

#[test]
fn flag_display_short() {
let mut f2 = Arg::new("flg").short('f').action(ArgAction::SetTrue);
f2._build();

assert_eq!(f2.to_string(), "-f");
}

#[test]
fn flag_display_count() {
let mut f2 = Arg::new("flg").long("flag").action(ArgAction::Count);
f2._build();

assert_eq!(f2.to_string(), "--flag...");
}

#[test]
fn flag_display_single_alias() {
let mut f = Arg::new("flg")
Expand Down
4 changes: 3 additions & 1 deletion src/output/help.rs
Expand Up @@ -8,6 +8,7 @@ use std::usize;
// Internal
use crate::builder::{render_arg_val, Arg, Command};
use crate::output::{fmt::Colorizer, Usage};
use crate::ArgAction;
use crate::PossibleValue;

// Third party
Expand Down Expand Up @@ -316,8 +317,9 @@ impl<'help, 'cmd, 'writer> Help<'help, 'cmd, 'writer> {
if arg.is_takes_value_set() || arg.is_positional() {
let arg_val = render_arg_val(arg);
self.good(arg_val)?;
} else if matches!(*arg.get_action(), ArgAction::Count) {
self.good("...")?;
}

if need_closing_bracket {
self.none("]")?;
}
Expand Down
68 changes: 42 additions & 26 deletions tests/builder/conflicts.rs
Expand Up @@ -2,32 +2,6 @@ use super::utils;

use clap::{arg, error::ErrorKind, Arg, ArgAction, ArgGroup, Command};

static CONFLICT_ERR: &str = "error: The argument '--flag' cannot be used with '-F'

USAGE:
clap-test --flag --long-option-2 <option2> <positional> <positional2>

For more information try --help
";

static CONFLICT_ERR_REV: &str = "error: The argument '-F' cannot be used with '--flag'

USAGE:
clap-test -F --long-option-2 <option2> <positional> <positional2>

For more information try --help
";

static CONFLICT_ERR_THREE: &str = "error: The argument '--one' cannot be used with:
--two
--three

USAGE:
three_conflicting_arguments --one

For more information try --help
";

#[test]
fn flag_conflict() {
let result = Command::new("flag_conflict")
Expand Down Expand Up @@ -316,6 +290,14 @@ fn get_arg_conflicts_with_group() {

#[test]
fn conflict_output() {
static CONFLICT_ERR: &str = "error: The argument '--flag...' cannot be used with '-F'

USAGE:
clap-test --flag... --long-option-2 <option2> <positional> <positional2>

For more information try --help
";

utils::assert_output(
utils::complex_app(),
"clap-test val1 fa --flag --long-option-2 val2 -F",
Expand All @@ -326,6 +308,14 @@ fn conflict_output() {

#[test]
fn conflict_output_rev() {
static CONFLICT_ERR_REV: &str = "error: The argument '-F' cannot be used with '--flag...'

USAGE:
clap-test -F --long-option-2 <option2> <positional> <positional2>

For more information try --help
";

utils::assert_output(
utils::complex_app(),
"clap-test val1 fa -F --long-option-2 val2 --flag",
Expand All @@ -336,6 +326,14 @@ fn conflict_output_rev() {

#[test]
fn conflict_output_with_required() {
static CONFLICT_ERR: &str = "error: The argument '--flag...' cannot be used with '-F'

USAGE:
clap-test --flag... --long-option-2 <option2> <positional> <positional2>

For more information try --help
";

utils::assert_output(
utils::complex_app(),
"clap-test val1 --flag --long-option-2 val2 -F",
Expand All @@ -346,6 +344,14 @@ fn conflict_output_with_required() {

#[test]
fn conflict_output_rev_with_required() {
static CONFLICT_ERR_REV: &str = "error: The argument '-F' cannot be used with '--flag...'

USAGE:
clap-test -F --long-option-2 <option2> <positional> <positional2>

For more information try --help
";

utils::assert_output(
utils::complex_app(),
"clap-test val1 -F --long-option-2 val2 --flag",
Expand All @@ -356,6 +362,16 @@ fn conflict_output_rev_with_required() {

#[test]
fn conflict_output_three_conflicting() {
static CONFLICT_ERR_THREE: &str = "error: The argument '--one' cannot be used with:
--two
--three

USAGE:
three_conflicting_arguments --one

For more information try --help
";

let cmd = Command::new("three_conflicting_arguments")
.arg(
Arg::new("one")
Expand Down
4 changes: 2 additions & 2 deletions tests/builder/help.rs
Expand Up @@ -219,7 +219,7 @@ ARGS:

OPTIONS:
-o, --option <opt>... tests options
-f, --flag tests flags
-f, --flag... tests flags
-F tests flags with exclusions
--long-option-2 <option2> tests long options with exclusions
-O, --option3 <option3> specific vals [possible values: fast, slow]
Expand Down Expand Up @@ -550,7 +550,7 @@ ARGS:

OPTIONS:
-o, --option <scoption>... tests options
-f, --flag tests flags
-f, --flag... tests flags
-s, --subcmdarg <subcmdarg> tests other args
-h, --help Print help information
-V, --version Print version information
Expand Down
4 changes: 2 additions & 2 deletions tests/builder/template_help.rs
Expand Up @@ -34,7 +34,7 @@ USAGE:

OPTIONS:
-c, --config <FILE> Sets a custom config file
-d Turn debugging information on
-d... Turn debugging information on
-h, --help Print help information
-V, --version Print version information
ARGS:
Expand All @@ -56,7 +56,7 @@ ARGS:

OPTIONS:
-c, --config <FILE> Sets a custom config file
-d Turn debugging information on
-d... Turn debugging information on
-h, --help Print help information
-V, --version Print version information

Expand Down