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

Arguments with default values conflict even if not used #1071

Closed
kornelski opened this issue Oct 19, 2017 · 10 comments
Closed

Arguments with default values conflict even if not used #1071

kornelski opened this issue Oct 19, 2017 · 10 comments
Labels
A-parsing Area: Parser's logic and needs it changed somehow. C-bug Category: Updating dependencies

Comments

@kornelski
Copy link
Contributor

Expected Behavior Summary

I expect conflicts to happen only when conflicting arguments are explicitly present on the command line.

Actual Behavior Summary

It's enough for an argument to have a default_value configured to cause a conflict.

Sample Code or Link to Sample Code

extern crate clap;
use clap::*;

fn main() {
  App::new("prog")
    .arg(Arg::with_name("default")
        .takes_value(true)
        .default_value("default"))
    .arg(Arg::with_name("exclusive")
        .long("exclusive")
        .conflicts_with("default"))
    .get_matches_from(vec![
        "prog", "--exclusive"
    ]);
}

I'd expect all of prog --exclusive, prog --default and prog (no args, meaning the default is used) to be allowed.

@kbknapp
Copy link
Member

kbknapp commented Oct 24, 2017

Default values are provided regardless of whether or not an argument was used, so it's as if the arguments are always used.

Perhaps what your looking for is conditional default values?

What you're wanting can be accomplished in user code pretty easily as well.

extern crate clap;
use clap::*;

fn main() {
  let matches = App::new("prog")
    .arg(Arg::with_name("default")
        .takes_value(true))
        //.default_value("default"))
    .arg(Arg::with_name("exclusive")
        .long("exclusive")
        .conflicts_with("default"))
    .get_matches_from(vec![
        "prog", "--exclusive"
    ]);

   let default = matches.value_of("default").unwrap_or("default_value");
}

@kbknapp
Copy link
Member

kbknapp commented Oct 24, 2017

Technically speaking it's possible for clap to know if it was a default value or not that was used and simply ignore conflicts if so...but I'd need to hear more arguments for it.

@kornelski
Copy link
Contributor Author

I'm using .default_value() in order to have this value printed in the help screen. I could put that info in my help text and handle defaults myself, but that's a workaround.

I presume from implementation perspective the current behavior is more straightforward, but from user perspective I don't see any argument in favor of it, since a set of flags configured in a way that never works is of no use.

@kbknapp
Copy link
Member

kbknapp commented Oct 24, 2017

[...] I don't see any argument in favor of it, since a set of flags configured in a way that never works is of no use.

I understand that, but I'm more wondering if there is a better way to solve this issue than adding additional logic in clap.

(Note: I'm not insulting your intelligence here because I know you're quite familiar with this project, but just to make sure we're on the same page 😄) In clap speak:

  • A default value is an argument that is always used, only the user is allowed to manually override the value.
  • A conflict says, if this particular argument is used, throw and error.

I understand that in your case, the conflict should only arise if the user overrides that default value, however that's now how clap is structured at the moment as those two statements are incompatible.

What I meant by "arguments for it" is I haven't had anyone yet talk to me about wanting to conflict with a arg which provides a default value so I'm unsure how common the case is. Are you modeling after a well known CLI that provides some precedence? It's required to add this feature, I'm just curious 😉 I don't know the specifics of the CLI you're designing so it's hard for me to make any suggestions.

@kornelski
Copy link
Contributor Author

My specific case is a CLI that can either be used by specifying arguments individually, or by specifying a JSON file that specifies all of them.

So I have a bunch of options, and a --json option that conflicts with everything else.

@kbknapp
Copy link
Member

kbknapp commented Oct 24, 2017

Makes sense to me. I think this is fairly easily classified as a bug the more I play with it. Thanks for taking the time to file this and hash it out with me 😉

@kbknapp kbknapp added A-parsing Area: Parser's logic and needs it changed somehow. D: easy C-bug Category: Updating dependencies and removed T: RFC / question labels Oct 24, 2017
@kornelski
Copy link
Contributor Author

Thank you! :)

@kbknapp kbknapp mentioned this issue Nov 13, 2017
87 tasks
@0ndorio
Copy link
Contributor

0ndorio commented Dec 9, 2019

@kornelski / @kbknapp
Seems like the issue is still present :/ Any chance to resurrect it?

This playground contains a slightly modified version of the test case introduced in f7a6955. The main difference to the original is that I moved the conflicts_with option to the the same argument, which also uses the default option. This should result in the same behavior but instead results in an error as soon as -f or --flag is passed.

Known Workaround: Split default and conflicts_with between the two arguments.

@Dylan-DPC-zz
Copy link

@0ndorio can you test if the issue persists on master branch? If yes then I recommend creating a new issue for visibility

@0ndorio
Copy link
Contributor

0ndorio commented Dec 9, 2019

This is issue is still present on the latest state of the master branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-parsing Area: Parser's logic and needs it changed somehow. C-bug Category: Updating dependencies
Projects
None yet
Development

No branches or pull requests

4 participants