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

Refactor reference resolution into Go code #401

Merged

Conversation

RedbackThomson
Copy link
Contributor

Description of changes:
Refactors the resolveReferenceFor<Field> Go template code into direct Go code. This way we can be more intelligent about nested field references and support unit testing its output.

Breaking change:
The previous Go template produced valid, but ultimately faulty, code for references within lists of structs. These are not supported (see aws-controllers-k8s/community#1291). As such, this update produces a panic when it detects those types of references.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@ack-prow ack-prow bot requested review from jljaco and vijtrip2 February 4, 2023 01:31
@ack-prow ack-prow bot added the approved label Feb 4, 2023
@jljaco
Copy link
Contributor

jljaco commented Feb 6, 2023

/cc A-Hilaly

@jljaco jljaco requested a review from a-hilaly February 6, 2023 22:33
Copy link
Member

@a-hilaly a-hilaly left a comment

Choose a reason for hiding this comment

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

Great one! Thank you for investing time in this. It's super useful, and makes references testable...
Left a few comments and suggestions bellow

@@ -16,7 +16,7 @@ require (
github.com/pkg/errors v0.9.1
github.com/spf13/cobra v1.2.1
github.com/stretchr/testify v1.7.1
golang.org/x/mod v0.4.2
golang.org/x/mod v0.6.0
Copy link
Member

Choose a reason for hiding this comment

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

Was this upgrade required for this patch? same for the upgrade below

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I honestly can't tell you where this came from. Go modules are a mystery to me

pkg/generate/code/resource_reference.go Outdated Show resolved Hide resolved
pkg/generate/code/resource_reference.go Outdated Show resolved Hide resolved
pkg/generate/code/resource_reference.go Outdated Show resolved Hide resolved
` if ko.Spec.Logging != nil {
if ko.Spec.Logging.LoggingEnabled != nil {
refVal := ""
if ko.Spec.Logging.LoggingEnabled.TargetBucketRef != nil && ko.Spec.Logging.LoggingEnabled.TargetBucketRef.From != nil {
Copy link
Member

Choose a reason for hiding this comment

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

thoughts: The more i see those, the more i think that we can refactor a little bit our code generator to make nil checks generic. Thinking a recursive wrapper function that can be called everywhere

    out += wrapNilCheck(fieldPath, generateCode(params....))

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That would only really work for structs. As soon as we get into lists and maps then things get iffy. I initially started to do that but it didn't extend cleanly.

pkg/generate/code/resource_reference.go Outdated Show resolved Hide resolved
pkg/generate/code/resource_reference.go Outdated Show resolved Hide resolved
pkg/generate/code/resource_reference.go Show resolved Hide resolved
pkg/generate/code/resource_reference.go Outdated Show resolved Hide resolved
pkg/generate/code/resource_reference.go Outdated Show resolved Hide resolved
pkg/generate/code/resource_reference.go Outdated Show resolved Hide resolved
pkg/generate/code/resource_reference.go Outdated Show resolved Hide resolved
pkg/generate/code/resource_reference_test.go Outdated Show resolved Hide resolved
pkg/generate/code/resource_reference.go Outdated Show resolved Hide resolved
pkg/generate/code/resource_reference.go Outdated Show resolved Hide resolved

func resolveSingleReference(field *model.Field, sourceVarName string, targetVarName string, shouldAppendTarget bool, indentLevel int) string {
out := ""
indent := strings.Repeat("\t", indentLevel)
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you just use https://pkg.go.dev/go/format#Source to deal with all of the formatting of the end result instead of bothering will all of these indentations?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

++ Absolutely would love to do this programmatically. If we can do this as a full refactor for all methods in the code-generator.

pkg/generate/code/resource_reference_test.go Show resolved Hide resolved
pkg/generate/code/resource_reference_test.go Show resolved Hide resolved
pkg/generate/code/resource_reference_test.go Show resolved Hide resolved
pkg/generate/code/resource_reference_test.go Show resolved Hide resolved
@RedbackThomson RedbackThomson requested review from jljaco, jaypipes and a-hilaly and removed request for jaypipes and vijtrip2 February 9, 2023 00:16
Copy link
Collaborator

@jaypipes jaypipes left a comment

Choose a reason for hiding this comment

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

I think you left one hard-coded string value in the code-generating function :) See comment inline..

outPrefix += fmt.Sprintf("%s\t\treturn fmt.Errorf(\"provided resource reference is nil or empty: \\%q\\\")\n", indent, field.ReferenceFieldPath())
outPrefix += fmt.Sprintf("%s\t}\n", indent)

outPrefix += fmt.Sprintf("%s\tif err := getReferencedResourceState_VPCLink(ctx, apiReader, obj, *arr.Name, namespace); err != nil {\n", indent)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
outPrefix += fmt.Sprintf("%s\tif err := getReferencedResourceState_VPCLink(ctx, apiReader, obj, *arr.Name, namespace); err != nil {\n", indent)
outPrefix += fmt.Sprintf("%s\tif err := getReferencedResourceState_%s(ctx, apiReader, obj, *arr.Name, namespace); err != nil {\n", indent, r.Names.Camel)

if arr == nil || arr.Name == nil || *arr.Name == "" {
return fmt.Errorf("provided resource reference is nil or empty: \"SecurityGroupRefs"\")
}
if err := getReferencedResourceState_VPCLink(ctx, apiReader, obj, *arr.Name, namespace); err != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

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

:) This test worked because it matched the hard-coded VPCLink you left in the generated code!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

lmao oops

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Don't you love test driven development

Copy link
Member

@a-hilaly a-hilaly left a comment

Choose a reason for hiding this comment

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

Neat! Good stuff 👌

outPrefix += fmt.Sprintf("%s\t}\n", indent)
outPrefix += fmt.Sprintf("%s\t%s = append(%s, obj.%s)\n", indent, targetVarName, targetVarName, field.FieldConfig.References.Path)
outPrefix += fmt.Sprintf("%s}\n", indent)
case ("map"):
Copy link
Member

Choose a reason for hiding this comment

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

Didn't know parenthesis here are possible

@ack-prow
Copy link

ack-prow bot commented Feb 9, 2023

@RedbackThomson: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ecr-controller-test dde4df3 link false /test ecr-controller-test
dynamodb-controller-test dde4df3 link false /test dynamodb-controller-test
s3-controller-test dde4df3 link false /test s3-controller-test

Full PR test history. Your PR dashboard.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here.

@a-hilaly
Copy link
Member

a-hilaly commented Feb 9, 2023

/lgtm

@ack-prow ack-prow bot added the lgtm Indicates that a PR is ready to be merged. label Feb 9, 2023
@ack-prow
Copy link

ack-prow bot commented Feb 9, 2023

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: A-Hilaly, RedbackThomson

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:
  • OWNERS [A-Hilaly,RedbackThomson]

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@ack-prow ack-prow bot merged commit 8dc09b7 into aws-controllers-k8s:main Feb 9, 2023
a-hilaly added a commit to a-hilaly/ack-code-generator that referenced this pull request Feb 9, 2023
a-hilaly added a commit that referenced this pull request Feb 16, 2023
Continuation of #401

Refactors the resolveReferenceFor<Field> Go template code into direct Go code. This way we can be more intelligent about nested field references and support unit testing its output.

Breaking change:
The previous Go template produced valid, but ultimately faulty, code for references within lists of structs. These are not supported (see aws-controllers-k8s/community#1291). As such, this update produces a panic when it detects those types of references.

Co-authored-by: Amine <hilalyamine@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved lgtm Indicates that a PR is ready to be merged.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants