-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Support '--' in a command line argument as a correct switch indicator #5786
Support '--' in a command line argument as a correct switch indicator #5786
Conversation
Launching the 'dotnet build' command is possible with both '-' and '--' switches, while launching the 'dotnet msbuild' command is only possible with single-dash swith (for example: '-help' or '-h'). To keep both products consistent it is necessary to add the double-dash to the list of supported switch indicators. Changes provided in this commit implements the '--' switch indicator. With these changes it is now possible to call 'dotnet msbuild --<switch>' as well as 'dotnet msbuild -<switch>' and 'dotnet msbuild -<switch>', where <switch> is any of supported command line option name. Implementation is done by: - adding "--" as considered sequence when checking for correct command line argument's beginning, - considering the switch indicator's length (2 for '--', 1 for '-' and '\', 0 for none) when extracting the name of switch from unquoted command line argument
The minor corrections done to the GetLengthOfSwitchIndicator() method are: - Use .Length property to return the length of each indicator variant This way will avoid the hardcoded magic values - Improve the comment formatting - Remove additional spaces inside the parameters braces
Unit test covering the GetLengthOfSwitchIndicator checks whether for each available indicator (- or / or --) it's correct length is returned. Hardcoded values are used (instead of using .Length property) to check if returned value matches exactly the known length.
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.
This should work (and thank you!) but it affects a lot more switches than I'd expected from the bug report, meaning that in addition to permitting --help
to work, it also lets users use --
with any other switch. That doesn't bother me, but I know there was a relevant difference between -
and --
with early command shells (-
when followed by several characters meant treating each character as a separate flag, whereas --
treated it as a single flag), which means someone might want this change to only apply to help and not more broadly.
[Fact] | ||
public void GetLengthOfSwitchIndicatorTest() | ||
{ | ||
var commandLineSwitchWithSlash = "/Switch"; |
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.
It might be good to have a test validating that building with --help
works.
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.
+1
This might be overkill but: Consider a case for -help
, /help
, and --help
and verifying part of the output is expected. Potentially in the help
test just below this test.
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.
@benvillalobos Can you elaborate on:
verifying part of the output is expected
Thing is, that MSBuildApp.Execute()
method only returns the ExitType
.
How to get the string returned from command line execution?
Or perhaps checking whether each call (command with '--help', '-h, '/h') returns ExitType.Success
will be enough?
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.
Verifying that it succeeded would be enough for me. I think it's probably more complicated than it's worth to look at the output, but you might be able to capture it with a logger you can pass in alongside the --help switch.
src/MSBuild/XMake.cs
Outdated
{ | ||
if (unquotedSwitch.StartsWith("--", StringComparison.Ordinal)) | ||
{ | ||
return "--".Length; |
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'd probably just put 2, 1, and 0 here to avoid allocating strings unnecessarily.
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.
These strings are constants and so aren't allocated. This compiles to
ldstr "--"
call instance int32 [System.Private.CoreLib]System.String::get_Length()
However, it's probably worth avoiding that call/making the JIT constant-fold it, so I would also prefer the constants.
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.
Thanks! A couple of minor suggestions but this looks great. I definitely expected this behavior, not a restriction to just the help
switch.
src/MSBuild/XMake.cs
Outdated
{ | ||
if (unquotedSwitch.StartsWith("--", StringComparison.Ordinal)) | ||
{ | ||
return "--".Length; |
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.
These strings are constants and so aren't allocated. This compiles to
ldstr "--"
call instance int32 [System.Private.CoreLib]System.String::get_Length()
However, it's probably worth avoiding that call/making the JIT constant-fold it, so I would also prefer the constants.
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.
Great PR! I'd suggest having a test case to verify the output of -help
, --help
, and /help
are all the same, but I won't block on it.
Thanks for the review everyone! I will provide this PR with all the corrections today. |
The if statement in the switch indication's validation has been reduced from separate checking '--' and '-' beginnings, to only one '-' check. This is due to '-' beginning being a superset of '--' indicator, so additional check for separate '--' can be considered redundant and can be removed for optimize reasons. Co-authored-by: Rainer Sigwald <[email protected]>
To avoid using ldstr call and cover the review remark, each constant string.Length call has been replaced with constant value. Please see: dotnet#5786 (comment)
Unit test checking successfull call of Help command has been extended with the additional '--' switch indicator's case: "msbuild.exe --help" Also other cases has been added, so it's verified that additional indicator doesn't affect the already existing ones.
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.
Thanks for the test! Looks good to me, although it would be nice to refactor it into a Theory (see comments and delete the rest).
src/MSBuild.UnitTests/XMake_Tests.cs
Outdated
[Fact] | ||
public void Help() | ||
{ |
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.
[Fact] | |
public void Help() | |
{ | |
[Theory] | |
[InlineData("-?")] | |
[InlineData("-h")] | |
[InlineData("--help")] | |
[InlineData(@"/h")] | |
public void Help(string switch) | |
{ |
src/MSBuild.UnitTests/XMake_Tests.cs
Outdated
MSBuildApp.Execute( | ||
#if FEATURE_GET_COMMANDLINE | ||
@"c:\bin\msbuild.exe -? " | ||
#else | ||
new [] {@"c:\bin\msbuild.exe", "-?"} | ||
#endif | ||
).ShouldBe(MSBuildApp.ExitType.Success); |
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.
MSBuildApp.Execute( | |
#if FEATURE_GET_COMMANDLINE | |
@"c:\bin\msbuild.exe -? " | |
#else | |
new [] {@"c:\bin\msbuild.exe", "-?"} | |
#endif | |
).ShouldBe(MSBuildApp.ExitType.Success); | |
MSBuildApp.Execute( | |
#if FEATURE_GET_COMMANDLINE | |
@$"c:\bin\msbuild.exe {switch} " | |
#else | |
new [] {@"c:\bin\msbuild.exe", switch} | |
#endif | |
).ShouldBe(MSBuildApp.ExitType.Success); |
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.
Looks great, thanks!
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.
Looks awesome, thanks!
src/MSBuild.UnitTests/XMake_Tests.cs
Outdated
#else | ||
new [] {@"c:\bin\msbuild.exe", "-?"} | ||
new [] {@"c:\bin\msbuild.exe", $"{indicator}"} |
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.
Slight redundancy here:
new [] {@"c:\bin\msbuild.exe", $"{indicator}"} | |
new [] {@"c:\bin\msbuild.exe", indicator} |
dfbf090
to
3d1f45d
Compare
Thanks @BartoszKlonowski! |
This pull request fixes #5714:
It adds the support for double dash ('--') indicator used in command line arguments.
With these changes it is now possible to invoke MSBuild commands using the same '--' switch indicators as it is currently possible with dotnet call.
Changes done in this delivery are:
Even if '-' beginning would also be recognized when using '--', adding '--' keeps the implementation consistent
Without it '--' would still be unrecognized, as hardcoded 1 in
switchName = unquotedCommandLineArg.Substring(1, switchParameterIndicator - 1);
would still result in having the extracted name as "-name"
GetLengthOfSwitchIndicator()
method with unit testThis is to check whether each switch variation has correct length of it's indicator returned.
For more details about the implementation, please check the commit messages done for this pull request.
The example of how this implementation work (presented on version switch for short output) is presented below.
Unit test results are attached to this pull request, presenting only the Microsoft.Build.CommandLine, as only this layer should be affected.
Microsoft.Build.CommandLine.UnitTests_net472_x86_implementation - showing the results with PR changes
Microsoft.Build.CommandLine.UnitTests_net472_x86_original - showing the results on main branch
CommandLine_UnitTest_Results.zip