-
Notifications
You must be signed in to change notification settings - Fork 5k
Add ability to parse command line switches without a value #43481
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
Tagging subscribers to this area: @maryamariyan |
...aries/Microsoft.Extensions.Configuration.CommandLine/src/CommandLineConfigurationProvider.cs
Outdated
Show resolved
Hide resolved
...aries/Microsoft.Extensions.Configuration.CommandLine/src/CommandLineConfigurationProvider.cs
Outdated
Show resolved
Hide resolved
...aries/Microsoft.Extensions.Configuration.CommandLine/src/CommandLineConfigurationProvider.cs
Outdated
Show resolved
Hide resolved
Thanks @am11 and @campersau for the review and @jdmallen for your PR. @HaoK would you consider this enhancement worth the behavior change it introduces? |
The change in behavior doesn't seem that unreasonable, but maybe its worth doing with a opt-in flag on the commandline source |
@HaoK do you think this is really breaking? I guess this would only apply to boolean flags, so this is just extending functionality other than breaking, right? |
I didn't look at the implementation, I guess if its narrow in scope only to bool switches, its not really breaking |
Yeah, that would be my expectation... to me this feature should only apply to boolean switches. |
If there's anything else you'd like me to change, please let me know and I'd be happy to do so. :) I'll also understand if you pass on it. This should only change it so that switch keys lacking values are no longer ignored. |
/azp run runtime |
Azure Pipelines successfully started running 1 pipeline(s). |
@jdmallen test logs show the failure below:
|
@maryamariyan If I'm reading the test results correctly, when compared to the test itself, it appears the string "true" is being appended to the second argument |
Also add 2 new tests for single args
Also, I rebased off master and pushed. |
IMO, confining |
@am11 I agree with what you said, and generally prefer how POSIX handles options. However, in order to support both styles, I think by adding my value-less switch feature, this library can no longer be OS-agnostic. I'm playing around with this as a static field in
I'm using it to only check for the Are there any other libraries you can think of that vary in function depending on the OS so I can see how to properly do this? I feel like I'm close, but I want to make sure I'm adhering to how it's supposed to be done. I'm also considering going buck-wild with this and supporting the full POSIX standard for options when the environment is not Windows. Adding the feature to have valueless flags as command line switches is only a piece of the pie, as you noted ( |
The automatic binding of uneven number of user-specified arguments that works interchangeably with Windows-styles (cmd This library ( Side note on command-line-api: it currently does not support stdin (which, in case of POSIX shell style, is represented by single hyphen |
Just checking in to say this PR isn't dead. Been working OT on lots of 1/1 deliverables at work-- should have more time for this either around Christmastime or in January. I appreciate all the feedback I've received so far! |
...aries/Microsoft.Extensions.Configuration.CommandLine/src/CommandLineConfigurationProvider.cs
Outdated
Show resolved
Hide resolved
...aries/Microsoft.Extensions.Configuration.CommandLine/src/CommandLineConfigurationProvider.cs
Outdated
Show resolved
Hide resolved
|
||
int separator = currentArg.IndexOf('='); | ||
// Process the last previousArg after exiting loop | ||
if (TryProcessArgs(previousArg, null, out (string key, string value) lastPair)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't this be calling TryProcessArgs
with the last arg twice? previousArg
will be pointing to enumerator.Current
which is the same as currentArg
if it entered the while loop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variable previousArg
gets assigned the value of currentArg
at the end of the last loop in the while
block. When it reaches the point where it processes the last argument (outside the while loop), previousArg
and currentArg
are indeed the same value, but that value has not yet been passed as the previousArg
to the TryProcessArgs
method. It only goes through it once.
...aries/Microsoft.Extensions.Configuration.CommandLine/src/CommandLineConfigurationProvider.cs
Outdated
Show resolved
Hide resolved
|| currentArg.StartsWith("/") | ||
|| currentArg.Contains("=")) | ||
{ | ||
value = "true"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what would happen if the value expected for the key is not a boolean? Do we have validation for that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I understand the question. The value
here gets assigned "true"
if the next command line argument found is another key. For example:
./program.exe -Key1 --Key2 someValue /Key3 Key4=42
would generate the dictionary { {"Key1", "true"}, {"Key2", "someValue"}, {"Key3", "true"}, {"Key1", "42"} }
.
The absence of a switch without a value can be interpreted as a falsy value for that switch. For example, if my program is looking for a value for Key1 in IConfiguration
to determine whether or not to enable a feature, and I removed "Key1" from the execution arguments, I would simply not enable that feature if it were missing, much like a switch on a typical *nix program.
Without a given value, true
is the best guess. However, I could assign it pretty much any string value I want. I just picked "true" since it seemed the most intuitive. Consumers of this library can still bind the configuration to a POCO, much like appsettings.json configuration, and {"Key1", "true"}
in the IConfiguration
would be successfully parsed and assigned to something like public bool Key1 { get; set; }
.
While I'm also inclined to doing the So imagine I want to say, It concerns me that we could potentially break people that might pass down a value that starts with |
Friendly ping @jdmallen, have you had a chance to look at the comments @maryamariyan and I left? |
Hi there! Yes, I've had a chance to look over the comments, and thanks for reviewing. I finally cut out time this weekend to dig in and apply the requested changes and ask/answer questions as they arise. I know you folks are probably eager to wrap up active development on 6.0 and I don't want to get in the way of that! |
Thank you @jdmallen. Take your time, we just want to make sure PRs don't go dead and try to keep a sane number of open PRs, only PRs which are active. I'll be waiting for your changes to review them 😄 |
That is a bit of a conundrum, and relative URIs were not something I thought of as a possible situation. I did already add a check for multiple |
@safern & @maryamariyan: Pushed a bunch of changes. Hopefully they resolve the errors in the HostTests and on the Linux environment tests. Please lemme know what you think about my responses above. |
I think I need to fix the tests, since they are still OS-agnostic and the code no longer is. |
Oh, also, I tried to make this field |
@jdmallen were you still planning to fix tests before having reviewers take another look? |
Could it be that you are getting the diagnostic error for the net461 build? So probably you need to make it a const for net461 and a readonly field for non net461? |
Closing the PR since there has not been any activity nor author response. Feel free to re-open if you want to keep working on this and have any updates. |
This is in response to issue #36024 where I was asked by @maryamariyan to submit a pull request based on my demonstration.
Applying this PR will:
CommandLineConfigurationProvider
to allow for individual switches to be evaluated as having the value"true"
, rather than be ignored altogether.As an example, one can currently provide key-value pairs currently in the following formats:
Once this PR is merged, the following will also set the configuration key
"help"
to the value"true"
, rather than be ignored completely:A potential breaking change is the necessity to bring inThis has been addressed; see below.System.Linq
inCommandLineConfigurationProvider
to easily transform anIEnumerable<string>
into astring[]
. However, this will likely never be needed, as the only type thatArgs
will ever be isstring[]
, andToArray
will only be called if the safe cast tostring[]
fails.I have tried my best to adhere to the original coding style of the files modified. Please let me know if anything needs adjusting and I will happily accommodate.
Please see the original issue comments (#36024) for more details.