-
Notifications
You must be signed in to change notification settings - Fork 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
fix(core): prevent the error when the condition is split into groups of 10 and 1 in Fn.conditionOr()
#25708
Conversation
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 pull request linter has failed. See the aws-cdk-automation comment below for failure reasons. If you believe this pull request should receive an exemption, please comment and provide a justification.
A comment requesting an exemption should contain the text Exemption Request
. Additionally, if clarification is needed add Clarification Request
to a comment.
Exemption Request I add test case in packages/aws-cdk-lib/core/test/condition.test.ts |
@@ -334,6 +334,10 @@ export class Fn { | |||
if (conditions.length === 1) { | |||
return conditions[0] as ICfnRuleConditionExpression; | |||
} | |||
// prevent the error "Fn::Or object requires a list of at least 2" when the condition is split into groups of 10 and 1 | |||
if (conditions.length % 10 === 1) { | |||
return Fn.conditionOr(..._inGroupsOf(conditions, 9).map(group => new FnOr(...group))); |
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 think this can break when conditions.length % 90 == 1
:)
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.
Yes, but would it be necessary to consider conditions for numbers larger than 91 or 181...?
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 guess yes, unless we are totally sure that there is no user to use such configuration.
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 agree that if we can't be sure, I should respond.
But in this case, I don't have a simple solution to solve this 91 or 181 or more problem...
And I'd prefer not to add more complex patch and test(should check the case of 91 and doesn't use snapshot for condition now) for specific funky code of 91 or 181 or more conditions.
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 see. I feel the solution @MalikAtalla-AWS proposed is also simple without any edge cases, but let's wait for comments from the maintainers.
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.
Lets go with @MalikAtalla-AWS's solution. Something like this might work
public static conditionOr(...conditions: ICfnConditionExpression[]): ICfnRuleConditionExpression {
if (conditions.length === 0) {
throw new Error('Fn.conditionOr() needs at least one argument');
}
if (conditions.length === 1) {
return conditions[0] as ICfnRuleConditionExpression;
}
// prevent the error "Fn::Or object requires a list of at least 2" when the condition is split into groups of 10 and 1
if (conditions.length > 10) {
return Fn.conditionOr(..._inGroupsOf(conditions, 10).map(group => Fn.conditionOr(...group));
}
return Fn.conditionOr(..._inGroupsOf(conditions, 10).map(group => new FnOr(...group)));
}
{ | ||
'Fn::Or': [ | ||
{ 'Fn::Equals': ['j', '10'] }, | ||
{ 'Fn::Equals': ['k', '11'] }, |
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 is totally a nice-to-have, but in terms of the simplicity of the resulting CFN snippet, I think it would be preferable to simply drop the last wrapping Fn::Or
, like this
'Fn::Or': [
{
'Fn::Or': [
{ 'Fn::Equals': ['a', '1'] },
{ 'Fn::Equals': ['b', '2'] },
{ 'Fn::Equals': ['c', '3'] },
{ 'Fn::Equals': ['d', '4'] },
{ 'Fn::Equals': ['e', '5'] },
{ 'Fn::Equals': ['f', '6'] },
{ 'Fn::Equals': ['g', '7'] },
{ 'Fn::Equals': ['h', '8'] },
{ 'Fn::Equals': ['i', '9'] },
{ 'Fn::Equals': ['j', '10'] }
],
},
{
'Fn::Equals': ['k', '11']
},
]
Fn.conditionOr()
@@ -334,6 +334,10 @@ export class Fn { | |||
if (conditions.length === 1) { | |||
return conditions[0] as ICfnRuleConditionExpression; | |||
} | |||
// prevent the error "Fn::Or object requires a list of at least 2" when the condition is split into groups of 10 and 1 | |||
if (conditions.length % 10 === 1) { | |||
return Fn.conditionOr(..._inGroupsOf(conditions, 9).map(group => new FnOr(...group))); |
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.
Lets go with @MalikAtalla-AWS's solution. Something like this might work
public static conditionOr(...conditions: ICfnConditionExpression[]): ICfnRuleConditionExpression {
if (conditions.length === 0) {
throw new Error('Fn.conditionOr() needs at least one argument');
}
if (conditions.length === 1) {
return conditions[0] as ICfnRuleConditionExpression;
}
// prevent the error "Fn::Or object requires a list of at least 2" when the condition is split into groups of 10 and 1
if (conditions.length > 10) {
return Fn.conditionOr(..._inGroupsOf(conditions, 10).map(group => Fn.conditionOr(...group));
}
return Fn.conditionOr(..._inGroupsOf(conditions, 10).map(group => new FnOr(...group)));
}
✅ Updated pull request passes all PRLinter validations. Dismissing previous PRLinter review.
@@ -334,6 +334,10 @@ export class Fn { | |||
if (conditions.length === 1) { | |||
return conditions[0] as ICfnRuleConditionExpression; | |||
} | |||
// prevent the error "Fn::Or object requires a list of at least 2" when the condition is split into groups of 10 and 1 |
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.
Just a matter of preference, but this seems more readable:
public static conditionOr(...conditions: ICfnConditionExpression[]): ICfnRuleConditionExpression {
if (conditions.length === 0) {
throw new Error('Fn.conditionOr() needs at least one argument');
}
if (conditions.length === 1) {
return conditions[0] as ICfnRuleConditionExpression;
}
if (conditions.length <= 10) {
return new FnOr(...conditions);
}
return Fn.conditionOr(..._inGroupsOf(conditions, 10).map(group => Fn.conditionOr(...group)));
}
The three base cases are stated explicitly, falling back to the recursive case at the end.
Pull request has been modified.
Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
…of 10 and 1 in `Fn.conditionAnd()` (#25999) Closes #25696 (comment) Same solution as #25708 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
…of 10 and 1 in `Fn.conditionAnd()` (aws#25999) Closes aws#25696 (comment) Same solution as aws#25708 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
…of 10 and 1 in `Fn.conditionAnd()` (aws#25999) Closes aws#25696 (comment) Same solution as aws#25708 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
…of 10 and 1 in `Fn.conditionAnd()` (aws#25999) Closes aws#25696 (comment) Same solution as aws#25708 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
Closes #25696
reproduce code: #25696 (comment)
approach: #25696 (comment)
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license