Fix broken command line options#392
Conversation
|
@gregwinterstein FYI |
5a97975 to
9714c48
Compare
| EndProject | ||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ODataConnectedService_VS2022Plus", "src\ODataConnectedService_VS2022Plus\ODataConnectedService_VS2022Plus.csproj", "{15769DAB-F3B0-4E82-A125-CF55ACB04D07}" | ||
| EndProject | ||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.OData.Cli.Tests", "test\Microsoft.OData.Cli.Tests\Microsoft.OData.Cli.Tests.csproj", "{FE62623D-B8AF-49E2-AEB2-4EF50419777A}" |
There was a problem hiding this comment.
Changes to this solution file are due to reorganizing the solution through introduction of src and test solution folders and moving different projects to their logical solution folder
| string namespacePrefix = null; | ||
| if (!(generateOptions.NamespacePrefix != null && generateOptions.NamespacePrefix.All(char.IsWhiteSpace))) | ||
| { | ||
| namespacePrefix = string.IsNullOrEmpty(generateOptions.NamespacePrefix) ? configUserSettings?.NamespacePrefix : generateOptions.NamespacePrefix; |
There was a problem hiding this comment.
Why do we check string.IsNullOrEmpty if the wrapping if-block already checks that the string is null or all whitespace (which includes empty).
There was a problem hiding this comment.
Also, does this mean that with your changes that the namespacePrefix = generateOptions.NamespacePrefix condition does not get reached anymore?
There was a problem hiding this comment.
I have the same question for all the similar changes to the code blocks below.
There was a problem hiding this comment.
@habbes Like I explained offline, when either of namespace-prefix, excluded-operation-imports, excluded-bound-operations, and excluded-schema-types is explicitly specified from the command line as an empty string, that should interpreted as an indication that if there was a non-empty value specified previously undone, it should be undone. Otherwise, one would never be able to undo any namespace prefix, or excluded model elements from the config file.
As an illustration, consider a scenario, where on the first occasion I elected to have a namespace prefix "Client":
generate --metadata-uri http://tempuri.org --outputdir C:\tempdir --namespace-prefix Client
You end up with a config file with the following properties (among others):
{
"Endpoint": "http://tempuri.org",
"UseNamespacePrefix": true,
"NamespacePrefix": "Client"
}The logical way to unset the Client namespace prefix from the config file is as follows:
generate --metadata-uri http://tempuri.org --outputdir C:\tempdir --namespace-prefix "" --config-file C:\tempdir\ConnectedService.json
Where the empty string will be interpreted to mean I want to overwrite the value in the config file.
Same case with excluded model elements.
Consider a scenario, where on the first occasion I elected to exclude "ResetDataSource" operation import:
generate --metadata-uri http://tempuri.org --outputdir C:\tempdir --excluded-operation-imports ResetDataSource
You end up with a config file with the following properties (among others):
{
"Endpoint": "http://tempuri.org",
"ExcludedOperationImports": ["ResetDataSource"]
}The logical way to unset the ResetDataSource excluded operation import from the config file is as follows:
generate --metadata-uri http://tempuri.org --outputdir C:\tempdir --excluded-operation-imports "" --config-file C:\tempdir\ConnectedService.json
|
@gathogojr thanks for adding the tests. Do they run in the build pipeline as well? |
dbeb23e to
89c7b8f
Compare
@habbes This was a good catch. I updated the build pipeline to run the CLI tests |
1dd129a to
f1fdaa4
Compare
| string namespacePrefix = generateOptions.NamespacePrefix?.Trim(); | ||
| if (namespacePrefix == null) | ||
| { | ||
| namespacePrefix = configUserSettings?.NamespacePrefix; |
There was a problem hiding this comment.
Up there. you state that if namespace prefix is null then no namespace prefix should be applied. Why are we applying the namespace prefix here? or What does configUserSettings?.NamespacePrefix contain
There was a problem hiding this comment.
@ElizabethOkerio My statement is different - "if namespace prefix is empty ...".
The namespace prefix will be null if namespace-prefix is not included in the command - in which case it should be okay to apply whatever is in the config file, and will empty if it's included in the command with an empty string - in which case we shouldn't apply whatever might be in the config file (and we'll save the updated config file with empty namespace prefix).
There was a problem hiding this comment.
I think the reasoning here is that the namespacePrefix could either be set through command option or config file. If it's not set by the command option, we check the config file, if it's no set there either, it would be null. But also, I believe @gathogojr is making a clear distinction between empty and null. If the namespacePrefix is an empty string, then the user has explicitly set it to an empty value, which would remove the current prefix if it exists.
f1fdaa4 to
bf11e79
Compare
bf11e79 to
b743f65
Compare
This pull request fixes #390, fixes #391, fixes #384, and closes #389
This appears to have broken when introducing a feature that allows loading the command line options from a config file. Here's the pull request #363
It's a useful feature since it helps someone avoid having to specify the command line options all the time.
For the feature to work in a manner that makes logical sense, the value of a command line option that is explicitly specified should take precedence over the value loaded from the config file.
There was one challenge with this though...
Let's say the value for a particular option is
truein the config file, how would we differentiate betweenfalsethat is explicitly specified from the command line (such that it should take precedence over the config filetrueoption) if an unspecified option also defaults tofalse?This is the reason we changed the boolean options to be nullable such that their values would be null when not specified.
Users should still to be able to specify boolean options without an explicit true, e.g.,
--enable-trackingas opposed to--enable-tracking true. However, by making the options nullable, that capability broke. When a boolean option is not explicitly set totrueorfalse, it's defaulting tonull.The workaround currently is to explicitly specify
trueorfalse, e.g.,--enable-tracking trueor--enable-tracking false.I have since discovered that we could have achieved the objective without making the options nullable from the
GenerateCommandclass. We only need to make the property nullable from theGenerateOptions, i.e.:This resolves the issue. For example, with the above change, both
--enable-trackingand--enable-tracking trueinitialize theEnableTrackingproperty totrue, while unspecified options default tonull.From my investigation, I also discovered that other users of the System.CommandLine library had made a feature request for command line options to support three states - undefined|null/true/false: commandlineparser/commandline#316
That feature has already been implemented and upgrading the CLI project to the latest version of the System.CommandLine library (without making any change) would also solve the issue.
This pull request resolves the reported issue by removing the
?operator from the options inGenerateCommandclass. It also upgrades the System.CommandLine library to the latest version.Additional work
ServiceNamecommand line option to the CLI - This makes it possible to control the CSDL filename (Created as "Service NameCsdl.xml" by default)