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

requires_all does not display all missing requirements #1158

Closed
smcmurray opened this issue Feb 1, 2018 · 4 comments
Closed

requires_all does not display all missing requirements #1158

smcmurray opened this issue Feb 1, 2018 · 4 comments
Labels
C-bug Category: Updating dependencies
Milestone

Comments

@smcmurray
Copy link

smcmurray commented Feb 1, 2018

Rust Version

1.23

Affected Version of clap

2.29.2

Expected Behavior Summary

When an agument has a requires_all list, and that argument is present but multiple of its required arguments are missing, clap should print an error message that includes all missing required arguments.

Actual Behavior Summary

clap will print out just one of the missing arguments. The user has to repeat the command over and over, adding one missing argument at a time.

@smcmurray
Copy link
Author

To clarify, this is ArgGroup.requires_all

@smcmurray
Copy link
Author

I'm trying to set up a command line something like:
example --conf <FILE>...|<<ID> --x <X>... --y <Y> --z <Z>>

but I get:

  $ example -h
  example [OPTIONS] <ID> --conf <FILE>... --x <X>... --y <Y> --z <Z>

and

$ example test
error: The following required arguments were not provided:
    --conf <FILE>...
    --x <X>...
    --y <Y>
    --z <Z>

In this case, --conf is not required or missing. In fact, including it would cause a conflict.
I understand that 'example -h' will put [OPTIONS] in there even though there are no other options. I can live with that. But it needs to get the | right, and the grouping right.

Here's my code:

extern crate clap;
use clap::{Arg, App};

fn main(){
  let matches = App::new("example")
                        .version("1.0")
                        .about("clap example")
                        .arg(Arg::with_name("config")
                             .short("c")
                             .long("conf")
                             .value_name("FILE")
                             .help("Custom config file.")
                             .takes_value(true)
                             .multiple(true)
                             .required_unless("ID")
                             .conflicts_with("ID")
                        )
                        .arg(Arg::with_name("ID")
                             .index(1)
                             .help("ID")
                             .required_unless("config")
                             .conflicts_with("config")
                             .requires_all(&["x", "y", "z"])
                        )
                        .arg(Arg::with_name("x")
                             .short("x")
                             .long("x")
                             .value_name("X")
                             .help("x")
                             .multiple(true)
                             .takes_value(true)
                        )
                        .arg(Arg::with_name("y")
                             .short("y")
                             .long("y")
                             .value_name("Y")
                             .help("y")
                             .takes_value(true)
                        )
                        .arg(Arg::with_name("z")
                             .short("z")
                             .long("z")
                             .value_name("Z")
                             .help("z")
                             .takes_value(true)
                        )
                        .get_matches();
}

@kbknapp
Copy link
Member

kbknapp commented Feb 2, 2018

Apologies, I've confirmed this bug. I'm in a heated battle with getting v3 out the door (which will include this bug fix) but I might be able to squeeze the part of this bug fix that will at least remove --conf from the required list when id (or another of it's conflicts) is used. The deeper fix to fix all arg group related conflicts will have to wait until v3. This initial fix should be able to come out in 2.29.3 since I think it'll be easy enough to forward port to v3.

@kbknapp kbknapp added C-bug Category: Updating dependencies P2: need to have labels Feb 2, 2018
@kbknapp kbknapp added this to the 2.29.3 milestone Feb 2, 2018
kbknapp added a commit that referenced this issue Feb 5, 2018
…show up as required

Prior to this commit if one had two requirements which conflicted with each other, and an
error was generated due to a totally seperate argument, BOTH required but conflicting args
would show up in the help message as "missing but required"

This is now fixed and the *used* required arg shows up, but the conflicting required arg
has been dropped.

Closes #1158
kbknapp added a commit that referenced this issue Feb 5, 2018
…show up as required

Prior to this commit if one had two requirements which conflicted with each other, and an
error was generated due to a totally seperate argument, BOTH required but conflicting args
would show up in the help message as "missing but required"

This is now fixed and the *used* required arg shows up, but the conflicting required arg
has been dropped.

Closes #1158
@kbknapp kbknapp mentioned this issue Feb 5, 2018
@kbknapp
Copy link
Member

kbknapp commented Feb 5, 2018

This is fixed in #1164 however, the usage string isn't exactly what you want. So I would recommend using a custom usage string. The behaviour is correct though.

    let matches = App::new("example")
        .usage("example <--config [FILE] | -x [X] -y [Y] -z [Z]>")
        .arg(Arg::from_usage("-c, --config [FILE] 'Custom config file.'")
             .required_unless("ID")
             .conflicts_with("ID"))
        .arg(Arg::from_usage("[ID] 'ID'")
             .required_unless("config")
             .conflicts_with("config")
             .requires_all(&["x", "y", "z"]))
        .arg(Arg::from_usage("-x [X] 'X'"))
        .arg(Arg::from_usage("-y [Y] 'Y'"))
        .arg(Arg::from_usage("-z [Z] 'Z'"))
        .get_matches();

@kbknapp kbknapp closed this as completed in 0d470af Feb 5, 2018
@kbknapp kbknapp mentioned this issue Feb 5, 2018
87 tasks
kbknapp added a commit that referenced this issue Aug 1, 2018
Fixes requirements and conflicts on the v3 branch

Closes #1158
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: Updating dependencies
Projects
None yet
Development

No branches or pull requests

2 participants