-
Notifications
You must be signed in to change notification settings - Fork 0
Optional option-argument parsing is incorrect #241
Comments
Comment by epage Would the summary be that we for optional values, we should be encouraging |
Comment by mkayaalp 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 |
Comment by mkayaalp This could be a separate issue, but the synopsis for optional option-argument should be:
or
|
Comment by epage Sorry, I mean to recommend |
Comment by epage (too many generic names,. keep referring to the wrong one. #3026 talks about cleaning this up) |
Comment by mkayaalp
Yes. That works for long, but it also requires it for short: |
Comment by epage Yeah, I was worried it didn't do the right thing in that case. |
Comment by epage I tried to summarize this at the bottom of your "Parsing" section. Mind double checking it? |
Comment by epage 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? |
Comment by mkayaalp
That's correct. Although I don't know if I would say |
Comment by mkayaalp
I would say
But
Allowing a space is the parser being lenient. Same thing with |
Comment by epage
While GNU is saying one thing, we still have to deal with user expectations. As a user, I never use |
Comment by mkayaalp
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. |
Comment by mkayaalp
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 |
Comment by mkayaalp
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: |
Issue by mkayaalp
Monday Nov 15, 2021 at 19:57 GMT
Originally opened as clap-rs/clap#3030
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: