Skip to content
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 error cases of conditions and conditional parameters #5704

Merged
merged 4 commits into from
Dec 13, 2022

Conversation

JanKrivanek
Copy link
Member

@JanKrivanek JanKrivanek commented Nov 29, 2022

Problem

Fixes #5647
Fixes #5646
Some malformed expressions are evaluated as if without issues (e.g. 'Param = false')

Solution

  • Improves the error detection and reporting for malformed expressions evaluation
  • Improves error reporting of authoring issues for conditional parameters (malformed conditions or missing default parameters)
  • Removes the disabled parameters from the configured parameters (as if they were never defined on a template)

Case of missing default values

Missing default value on a parameter that is not required is always suspitious (and should likely be flaged by the template validation)
It is hard to guess what the sensible default should be in such case - even for boolean parameters (shown by unit case with inverted enabling parameter A_disabled). It's probably best bet to flag such a case via error. Current error seemes to be clear enough:

Failed to create template.
Details: Failed to evaluate condition IsEnabled on parameter A (condition text: A_enable, evaluation error: String 'A_enable' was not recognized as a valid Boolean.) - condition might be malformed or referenced parameters do not have default nor explicit values." to contain "xFailed to evaluate condition IsEnabled on parameter A

On a second thought - the condition within template are evaluated via different evaluator (CPP vs CPP2) and behaves as if default value was specified (thanks to default value of expression https://github.com/dotnet/templating/blob/main/src/Microsoft.TemplateEngine.Core/Expressions/Cpp/CppStyleEvaluatorDefinition.cs#L533 and default value when negating subexpression https://github.com/dotnet/templating/blob/main/src/Microsoft.TemplateEngine.Core/Expressions/Cpp/Scope.cs#L61).

So the question is if we want:
a) Consistency, but hide possible authoring issues.
b) Fail fast and clearly for authoring issues but lose consistency with instantiation.

Checks:

  • Added unit tests
  • Added #nullable enable to all the modified files ?

@JanKrivanek JanKrivanek requested a review from a team as a code owner November 29, 2022 20:42
@vlada-shubina
Copy link
Member

First thought on default values: imo defining default values for boolean is superfluous and will easily become authoring burden.

They should only be defined in case different from common meaning: defaultValue: false, defaultIfOptionWithoutValue: true.
We may discuss other types separately.

Copy link
Member

@vlada-shubina vlada-shubina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's discuss couple of points:

  • consider keeping to the generator scope to remove parameters or not. If so API changes are not required.
  • let's consider implicit default values for boolean instead and extract supporting default values for other types in a separate issue. Removing them will probably be a "breaking" change. A_disabled seems to be a unique scenario, and in this case likely defaultValue will be specified to true if desired.

Copy link
Member

@vlada-shubina vlada-shubina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{
string s when string.IsNullOrEmpty(s) => null,
string s when s.Equals("bool", StringComparison.OrdinalIgnoreCase) => false.ToString(),
string s when s.Equals("choice", StringComparison.OrdinalIgnoreCase) => string.Empty,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't it be null for choice?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

null for choice means that default value should be used.
If defualt would be null as well - it would be recognized as error: https://github.com/dotnet/templating/blob/main/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/ParameterConverter.cs#L147-L148

string.Empty is explicit unset - sounds as reasonable default

@@ -62,6 +62,11 @@ internal ParameterSymbol(string name, JObject jObject, string? defaultOverride)
DefaultIfOptionWithoutValue = "true";
}

if (DefaultValue == null && IsRequired != true)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is IsRequired needed here?
does it change any behavior?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IsRequired indicates that value needs to be specified. Dafult is not needed. So it can technically be removed here from the condition without any impact. I just wanted the code not to create impression that the Default is created and applied even for required parameters.

@JanKrivanek
Copy link
Member Author

Looks good, thank you!

Just wondering, it it makes sense to add the integration test(s) for cases we explicitly faced to have them as the reference.

Follow up: uncomment those tests in sdk https://github.com/dotnet/sdk/blob/66738868dfe1bb818a960d8bf501b0b6e4aa86f6/src/Tests/dotnet-new.Tests/DotnetNewInstantiateTests.Approval.cs#L688

https://github.com/dotnet/sdk/blob/66738868dfe1bb818a960d8bf501b0b6e4aa86f6/src/Tests/dotnet-new.Tests/DotnetNewInstantiateTests.Approval.cs#L737

Yes, Yes
It's the InstantiateAsync_ConditionalParametersRequiredOverwrittenByDisabled test added in this PR - with all possible variations of parameter values combinations (and their omission)

@JanKrivanek JanKrivanek merged commit b26cc3b into dotnet:main Dec 13, 2022
@JanKrivanek JanKrivanek deleted the conditional-params-fixing branch December 13, 2022 15:06
@JanKrivanek
Copy link
Member Author

/backport to release/7.0.2xx

@github-actions
Copy link
Contributor

Started backporting to release/7.0.2xx: https://github.com/dotnet/templating/actions/runs/3686669324

@github-actions
Copy link
Contributor

@JanKrivanek backporting to release/7.0.2xx failed, the patch most likely resulted in conflicts:

$ git am --3way --ignore-whitespace --keep-non-patch changes.patch

Applying: Fix error cases of conditions and conditional parameters
.git/rebase-apply/patch:186: trailing whitespace.
    
.git/rebase-apply/patch:187: trailing whitespace.
    
.git/rebase-apply/patch:199: trailing whitespace.
        
.git/rebase-apply/patch:201: trailing whitespace.
        
.git/rebase-apply/patch:203: trailing whitespace.
        
warning: squelched 33 whitespace errors
warning: 38 lines add whitespace errors.
Using index info to reconstruct a base tree...
M	src/Microsoft.TemplateEngine.Abstractions/PublicAPI.Unshipped.txt
M	src/Microsoft.TemplateEngine.Core/Expressions/Shared/SharedEvaluatorDefinition.cs
M	src/Microsoft.TemplateEngine.Core/PublicAPI.Shipped.txt
M	src/Microsoft.TemplateEngine.Edge/Template/TemplateCreator.cs
M	src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/RunnableProjectConfig.cs
Falling back to patching base and 3-way merge...
Auto-merging src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/RunnableProjectConfig.cs
Auto-merging src/Microsoft.TemplateEngine.Edge/Template/TemplateCreator.cs
Auto-merging src/Microsoft.TemplateEngine.Core/PublicAPI.Shipped.txt
CONFLICT (content): Merge conflict in src/Microsoft.TemplateEngine.Core/PublicAPI.Shipped.txt
Auto-merging src/Microsoft.TemplateEngine.Core/Expressions/Shared/SharedEvaluatorDefinition.cs
Auto-merging src/Microsoft.TemplateEngine.Abstractions/PublicAPI.Unshipped.txt
CONFLICT (content): Merge conflict in src/Microsoft.TemplateEngine.Abstractions/PublicAPI.Unshipped.txt
error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch=diff' to see the failed patch
Patch failed at 0001 Fix error cases of conditions and conditional parameters
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
Error: The process '/usr/bin/git' failed with exit code 128

Please backport manually!

@github-actions
Copy link
Contributor

@JanKrivanek an error occurred while backporting to release/7.0.2xx, please check the run log for details!

Error: git am failed, most likely due to a merge conflict.

JanKrivanek added a commit to JanKrivanek/templating that referenced this pull request Dec 14, 2022
* Fix error cases of conditions and conditional parameters

* Add default values assignment and tests

* Fix tests

* Fix PR suggestions
JanKrivanek added a commit to JanKrivanek/templating that referenced this pull request Dec 14, 2022
* Fix error cases of conditions and conditional parameters

* Add default values assignment and tests

* Fix tests

* Fix PR suggestions
JanKrivanek added a commit that referenced this pull request Jan 6, 2023
…] to release/7.0.2xx (#5765)

* Fix error cases of conditions and conditional parameters (#5704)

* Fix error cases of conditions and conditional parameters

* Add default values assignment and tests

* Fix tests

* Fix PR suggestions

* Fix contract

* Extend macros contract and improve coalesce macro (#5817)

* Improve coalesce macro

* Add test

* Add comments

* Fix contracts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants