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(parser): Ban long flags with literals #2619

Merged
merged 11 commits into from
Aug 1, 2021

Conversation

rami3l
Copy link
Contributor

@rami3l rami3l commented Jul 24, 2021

Closes #1543.

The objective of this PR is to ban use of literals with long flags (long args without TakesValue), eg. --flag=literal, in order to avoid the current confusion that --flag=false is considered as true.

Ideally, --flag=literal could be re-enabled for certain values of literal, but the choice of such values is left for further discussion (in #1649 for CLI flags, and #2539 for environment variables).

Unresolved Questions

  • How should this interact with multiple occurrences?

@epage
Copy link
Member

epage commented Jul 25, 2021

How should this interact with multiple occurrences?

I wish overrides-self was a default :). It'd especially make sense in this case but people can still relatively easily opt-in, if they know how.

@epage
Copy link
Member

epage commented Jul 25, 2021

Looking over #1649, it doesn't look like there was consensus on moving forward with this. It also looked like it was possible to implement this by users in clap today.

I'm particularly concerned about

  • User confusion with an argument that can only be used as --arg=value and not also -avalue or --arg value
  • The needed special casing of the parser for this
  • If we did support this as a --arg value, it'd then need to be opt-in with a flag because conditional number of values can have surprising results.

@rami3l
Copy link
Contributor Author

rami3l commented Jul 25, 2021

@epage As a clap user I truly think that the pseudo-flag pattern solution proposed in #1649 (comment) is acceptable. However, the problem that I really want to solve here is that --flag=false is considered as true, as good library should always minimize its possibility to be misused. Also, I think users need to know how to get the exact behavior that they expect.

I have an idea: to avoid possible argues about true/false against yes/no and 1/0, maybe we can do this in another way by banning --flag=something altogether, and think of a way to guide our users towards the pseudo-flag pattern, also to give our users more control?

How will this decision affect the usage of clap?

@epage
Copy link
Member

epage commented Jul 26, 2021

However, the problem that I really want to solve here is that --flag=false is considered as true

... I didn't want to believe this but I threw in a test real quick

    assert_eq!(
        Opt { alice: true },
        Opt::parse_from(&["test", "--alice=false"])
    );

imo thats bad and seems like a bug in the parser. If there is a val, we shouldn't ignore it but should error if we are processing a flag.

@rami3l
Copy link
Contributor Author

rami3l commented Jul 26, 2021

@pksunkara After some consideration, at this point I'm leaning towards modifying my original code to ban --flag=something altogether. Is this desirable?

@epage What's worse, the same problem exists with env flags, see #2539.

@rami3l rami3l changed the title fix(parser): Accept long flags with Boolean literals fix(parser): Ban long flags with Boolean literals Jul 28, 2021
@rami3l
Copy link
Contributor Author

rami3l commented Jul 28, 2021

@epage @pksunkara So I have just banned all usage of flags with a literal, giving a too_many_values error.

The rest of this problem is to somehow make users of this crate more aware of the pseudo-flag approach. Any advice?

If this gets accepted, I will then make another PR on env variables.

@rami3l rami3l marked this pull request as ready for review July 28, 2021 15:59
@epage
Copy link
Member

epage commented Jul 28, 2021

The rest of this problem is to somehow make users of this crate more aware of the pseudo-flag approach. Any advice?

imo we should have a place to document common arg patterns. Unsure if examples/ is the best place or the website.

src/parse/parser.rs Outdated Show resolved Hide resolved
@epage
Copy link
Member

epage commented Jul 30, 2021

Could you update your PR to say its resolving #1543 rather than #1649
(turns out we did have an open issue for this)

@rami3l
Copy link
Contributor Author

rami3l commented Jul 30, 2021

@epage @ldm0 I updated the description mentioning both issues: it shouldn't be necessary to make a choice between them. Also, I modified one of the existing examples hoping to make more users aware of the pseudo-flag pattern.

@epage
Copy link
Member

epage commented Jul 30, 2021

I updated the description mentioning both issues: there should be no need to make a choice between them

I take it you are proposing we close #1649 out by rejecting the proposed idea and instead document how to use existing clap APIs?

As I said earlier, I hadn't seen consensus on it. No idea what clap's decision making process is like to say whether documenting is a way of closing #1649 or to just unblock people until a decision is made. This is why I was assuming #1649 was going to be taken out of this PR.

One thing gained by decoupling the decision over #1649 from this PR is it means it doesn't have to be bogged down before merging useful improvements.

@rami3l
Copy link
Contributor Author

rami3l commented Jul 30, 2021

@epage Thanks for clarifying. Sorry, clearly I wasn't very well thought out, since it turns out that soon we might be discussing the very same problem over again with env variables...

@ldm0 ldm0 requested a review from pksunkara July 31, 2021 08:31
@rami3l rami3l changed the title fix(parser): Ban long flags with Boolean literals fix(parser): Ban long flags with literals Jul 31, 2021
examples/05_flag_args.rs Outdated Show resolved Hide resolved
examples/05_flag_args.rs Outdated Show resolved Hide resolved
src/build/app/mod.rs Outdated Show resolved Hide resolved
tests/flags.rs Outdated Show resolved Hide resolved
tests/flags.rs Outdated Show resolved Hide resolved
tests/flags.rs Outdated Show resolved Hide resolved
Copy link
Member

@pksunkara pksunkara left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example file still has changes.

tests/flags.rs Outdated Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Arguments with takes_value(false) still accept "compact"-style arguments
4 participants