-
Notifications
You must be signed in to change notification settings - Fork 115
Fix option precedence over positional arguments #197
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
Conversation
|
Since args = ["--foo", "--foo", "3", "--bar", "5"];
ConsoleApp.Run(args, ([Argument] string path, int foo, int bar) =>
{
var obj = new { path, foo, bar };
Console.WriteLine($"{obj}");
});I think it's not bad to process things with simple rules (arguments bind with highest priority) rather than running complex interpretations. |
|
In your example, returning an error is the logical move because It does show: Argument 'foo' failed to parse, provided value: --fooThis is correct behavior as the second And this PR addresses the fact that i.e. if I pass For the sake of example, imagine the following example with "rsync", to which the real parameters are similar to this: args = ["--dry-run", "destination"];
ConsoleApp.Run(args, ([Argument] string source, [Argument] string destination, bool dryRun) =>
{
Console.WriteLine(new { source, destination, dryRun });
});If you are not familiar, "rsync" syncronizes files between 2 locations. In which case:
Also,
This PR doesn't add complexity to the interpretation, mainly just re-orders the processing of options to be before arguments, it also shouldn't really affect perf at all, and even if it will, the amount will probably will be insignificant in real world and a necessary price to pay to avoid examples like I provided above. |
|
Thanks for the detailed explanation.
|
|
Thanks for the follow-up!
ConsoleApp.Run(["-5", "--dry-run"], ([Argument] int count, bool dryRun) => …)Without the guard, I did change the guard to only emit when there are positional parameters to bind, and I added another test case
If you’d like anything else adjusted, just let me know. |
|
Thank you, I think it's very well thought out! |
|
I've released v5.6.2. |
Bug
Before these changes, the generated code would incorrectly bind anything to required postional arguments (parameters decorated with
Argumentattribute) - this includes options.For example:
Would print:
Which is invalid, and should fail because "path" is missing.
Fix
Emitter.EmitRunso named options are handled before positional[Argument]parameters:argumentPositioncounter that advances only when a non-option token is consumed, keeping positional slots aligned with the number of positional values actually provided.-x/--name(exclude negative numbers) and run the existing switch to parse it; when a match occurs, setoptionMatchedandcontinueso the token never reaches positional binding.RunTest.cswith four regression tests that cover the original single-argument case, multiple positional arguments, an[Argument]with a default value, and a command that mixes[Argument]with aparamsarray, demonstrating the new parser behavior across common patterns.Tests
All 104 generator tests (including the 4 new ones) pass.