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
Optional option-argument parsing is incorrect #3030
Comments
Would the summary be that we for optional values, we should be encouraging |
That changes the parsing for let opt = App::new("clap-test")
.arg(Arg::new("foo")
.short('f')
.long("foo")
.takes_value(true)
.value_name("FOO")
.min_values(0)
.max_values(1)
.multiple_values(false)
.use_delimiter(true)
.require_delimiter(true))
.arg(Arg::new("input")
.takes_value(true)
.value_name("INPUT")
.required(true)).get_matches(); The POSIX guideline says:
So, Solaris guideline says:
I don't know if the lack of space between option and quote in |
This could be a separate issue, but the synopsis for optional option-argument should be:
or
|
Sorry, I mean to recommend |
(too many generic names,. keep referring to the wrong one. #3026 talks about cleaning this up) |
Yes. That works for long, but it also requires it for short: |
Yeah, I was worried it didn't do the right thing in that case. |
I tried to summarize this at the bottom of your "Parsing" section. Mind double checking it? |
Random observations: 1 atm the color flag in my CLIs is 2 For the most part, users are constructing the optional-optional value, we are just providing the building blocks. In following that pattern, we'd need to be able to allow users to specify the policy in a way that isn't confusing. So how do we communicate this? One thought is to have an enum listing out delimited ( My main concern about this is the overall complexity, not just in code but in API design and user code. Is there a simpler way? |
That's correct. Although I don't know if I would say |
I would say
But
Allowing a space is the parser being lenient. Same thing with |
While GNU is saying one thing, we still have to deal with user expectations. As a user, I never use |
We could say "short" option follows the POSIX guidelines, and "long" option follows the GNU guidelines. Then have a custom option escape hatch that changes the prefix, separator, delimiter, with allow/disallow/require flags for each. |
I agree, I am not saying we make the parser strict (although, it would be a really good addition to As a user, I am expecting But I would prefer to show |
Well, we do have a short/long/operand distinction. If we had simpler building blocks, short/long options could be "non-positional optional operands with labels" and short and long could only differ in their label length and prefix ( Going the other way, maybe we need another distinction for optional option-arguments: |
Many users are used to GNU and Unix-like systems their expectation is that flags will behave the way GNU and POSIX describes. Users aren’t dumb. They can understand CLI conventions so long as they are somewhat consistent between applications. It’s when every application has their own idea of how arguments should be parsed is when we get into trouble. (And I’m sorry to say but clap is contributing to that problem). |
Could you clarify which problem clap is contributing to? If its allowing a space between a flag and a value, the cat is out of the bag on that one and its not just clap. If its for something else, please clarify, |
clap is definitely not the only offender, but it does contribute to the problem. The reason I have irrational hatred of clap are:
And yes, I’m aware cat is out of the bag and I’ll have to continue dealing with my irrational hatred but perhaps some of clap parsing may be made saner. |
I regret to inform you, it likely isn't. Looking at the high level options for making the ecosystem "saner":
For allowing individual apps to be "saner", we'll need a strong case for why or where being more permissive is a problem due to the aforementioned challenges with configurability. Design work on this would also need to come from the wider community as this is not one of our stated focus areas. I'm most sympathetic to cases like uutils where they are trying to match behavior but even then I would need to understand why being more lax is a problem so long as all of the strict cases work. |
I have proposed a solution in PR #5489 where
|
Please complete the following tasks
Rust Version
rustc 1.56.0 (09c42c458 2021-10-18)
Clap Version
master
Minimal reproducible code
Steps to reproduce the bug with the above code
or
Actual Behaviour
Expected Behaviour
Additional Context
There needs to be some special handling of options with optional arguments.
Optional option-arguments are bad
First of all, users really need to be discouraged (if we ever add some lint-like feature, e.g.
#[clap(enable-warnings)
).POSIX says:
Solaris says:
Parsing
I know some people have a preference for
-f OptArg
over-fOptArg
, but if the option-argument is optional, then only the latter is correct. If there is a space, it means the optional argument is not there.From POSIX.1-2017 - Ch. 12: Utility Conventions:
Same thing with the long option, which is a GNU extension.
From GNU C Library Reference Manual - Ch. 25.1.1: Program Argument Syntax Conventions:
See this SO question about how
getopt
handles this:getopt
does not parse optional arguments to parameters.In clap terms, these are saying we should only allow
--long
--long=value
-s
-svalue
In contrast, clap supports
--long
--long=value
--long value
-s
-s value
-s=value
-svalue
requires_equals(true)
--long
--long=value
-s
-s=value
Debug Output
The text was updated successfully, but these errors were encountered: