-
Notifications
You must be signed in to change notification settings - Fork 480
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 #601 - better getopt compatibility for -- and --help handling #607
Conversation
This will let us parse -vvv and turn that into "Verbose=3".
Most tests pass; a couple of tests were either not needed, or were testing semantics that change with the new implementation (e.g., spaces in option values are allowed now).
Pattern matching is a particularly good fit here, as each case is data-driven and the flow is easy to read top-to-bottom.
The short and long option code can move into separate functions, which makes the big switch statement much easier to read. Also remove one TODO comment that's not relevant to the current feature.
Note that I wrote this PR on top of #594, because creating lists of input files with This means that if you merge this PR as-is, #594 will automatically be merged as well. |
It is better to minimize the change in the public API to avoid break change ( except it is necessary), can we remove |
Double dash (--) should end option sequences, but should have no effect on value sequences. These unit tests reflect that design.
I'll add tests for FlagCounter. The tests I just pushed are to test the scenarios that came up in discussion here: #610 (comment) |
I'm going to remove the FlagCounter feature from this PR: it's proving more difficult to implement than I had anticipated, and is going to require some fundamental reshuffling of how flag options are handled (a FlagCounter option needs to be treated more like a sequence than a flag throughout most of the code, up until the point where values are assigned). The required code changes to implement FlagCounter are making this PR drift out of its scope, so I'm going to pull them out of this PR and submit a separate PR for the FlagCounter feature once I get it working. |
Now things like -vvv for triple-verbose can be done in user code.
b8b9a97
to
1e791b5
Compare
Update: turns out I was almost there with my FlagCounter implementation yesterday, and I just needed a one-line change to get it all working. So I'm reverting my reversion of the feature, backing commit b8b9a97 out of this PR, and replacing it with commit 1e791b5 that implements FlagCounter properly and has a unit test to verify that it's working. @moh-hassan - With this commit, I believe I've addressed all the things you mentioned in your code review and it's ready to merge if you're satisfied. With the new FlagCounter implementation, though, you might want to do another code review. If so, I'll be happy to address any further changes you might want me to make. |
@rmunn I'm still in the code review for #607. |
@moh-hassan - I had missed that comment. I'm reading it now and will respond to it over there. This PR includes #594 so if you merge this one, #594 will automatically be merged as well. This one also contains a rewrite of #610 (with credit for the relevant commit still given to @robnasby), so merging #610 would cause some conflicts when you merge this one. If you decide that both #610 and this PR are worth taking, I'd suggest NOT merging #610 as-is, since this one replaces it. That way you'll have fewer merge conflicts to deal with. |
It's a best practice that every PR is one feature at a time per branch. This simplify maintenance and review, even if there is a minor confliction. |
I've responded to notes 2, 3 and 4 in the other thread. I'll summarize my comments here: Note 2, about AutoHelp=false: I believe this PR honors AutoHelp=false. If it doesn't, that's a bug and I'll fix it. Note 3, about Note 4, about allowing an "option" (by which I think you mean a string value starting with BTW, about this being a breaking change: I actually was expecting this to be a breaking change, since I had a big rewrite of the tokenizer. But I was amazed to discover that after I rewrote the tokenizer, all the unit tests still passed! So this isn't a breaking change, just a bugfix. It turns out that after this fix, the behavior of CommandLineParser is just as it was before, except that a couple of bugs ( So although I won't object if you decide that this PR needs a new major version number once it goes in, I do think that a major version number bump is not necessary here, because it's a bugfix that brings the behavior more in line with what it's intended to be. It's also not at all a breaking change from the point of view of the API, because the user-facing API has no changes except for a new OptionAttribute property (FlagCounter) being available. Having said that, I do think that more documentation is needed, and once I know you're planning to accept this PR I'll start working on editing the wiki to explain precisely how getopt, and now CLP, handles option values. Because I do think that the documentation is lacking in how it explains getopt's corner cases which CLP mimics, and it might be good to make sure they know what to expect. |
I'll jump temporary for using #607, for running sample programs already using v2.8. Case#1: class Options
{
// plugin name
[Option('n')]
public string Name { get; set; }
//plugin options
[Option('p')]
public IEnumerable<string> PluginArgs { get; set; }
} commandline: I pass -- so parser can consider all options after -- as a value.
In v2.8 in PR607, i get an error
I want to migrate the program to PR607 with zero change in the source code to avoid breaking change (if possible). |
That was always an incorrect way to use The right way to use a PluginArgs option like that would be to do one of two things:
Both do require a small modification to the user's code, so I guess we do have to consider this a breaking change even though it's really a bugfix. |
This changes the tokenizer to use the same logic as glibc's getopt, where the handling of one token will influence the handling of the next token. In particular, anything that follows an option expecting a value, even if it is something specially handled, will become the value of that option. So if
-s
is an option expecting a string value, thenmyprog -s --help
will NOT display the help screen, but will instead give-s
the value"--help"
, with no--
needed.To prove that this is how getopt behaves (and is expected to behave), run the following on any Linux machine:
gzip -S --help README.md
. The-S
option lets you pick a suffix different from.gz
, so if there's a README.md file in the current directory, this will create a gzipedREADME.md--help
file. This PR adjusts the behavior of CommandLineParser to mimic getopt's behavior exactly in this regard.