crossplane / upjet

A code generation framework and runtime for Crossplane providers
Apache License 2.0
320 stars 90 forks source link

feat: add AddReference method to References #415

Open yordis opened 5 months ago

yordis commented 5 months ago

Description of your changes

@haarchri was helping at https://github.com/crossplane-contrib/provider-upjet-digitalocean/pull/41 (thank you), and during the code review, I noticed a oversee where he replaced the existing r.References as follow:

diff --git a/config/provider.go b/config/provider.go
index 83eada3..8e69d59 100644
--- a/config/provider.go
+++ b/config/provider.go
@@ -294,13 +294,9 @@ func GetProvider() *ujconfig.Provider {
            Type:          referenceType(pc, “project”, “v1alpha1", “Project”),
            TerraformName: “digitalocean_project”,
        }
-
-       r.References = map[string]ujconfig.Reference{
-           “forwarding_rule.certificate_name”: {
-               TerraformName: “digitalocean_certificate”,
-           },
+       r.References[“forwarding_rule.certificate_name”] = ujconfig.Reference{
+           TerraformName: “digitalocean_certificate”,
        }
-
    })
    pc.AddResourceConfigurator(“digitalocean_domain”, func(r *ujconfig.Resource) {
        r.ShortGroup = “dns”

I am glad that I saw the diff, but honestly, this is a straightforward thing to miss when they are so much code-generated files noise, or people tend to ignore those.

As @haarchri explained, "That's why I prefer this, for example, https://github.com/crossplane-contrib/provider-upjet-aws/blob/main/config/elbv2/config.go#L13," which is a really common scenario.

I never considered using the existing style. I didn't think much about it. He didn’t try to break things. Still, we ran into the issue. Since we are talking about "style" here, it is really difficult to be objective and define who is more proper.

So, the fix here is to expose an SDK API that avoids such a mistake.

I am not proposing adding getters and setters everywhere either, just reacting to the situation and figuring out how to mitigate the issues in the future; as I usually say, "let the code teach you what to do, not the other way around."

I have:

How has this code been tested

yordis commented 5 months ago

A few things from this,

  1. Should all documentation and code-generated code be updated to this?
  2. Should References be a private field instead of exposing it? You can still assign r.References. Ideally, Provider Authors shouldn't care about replacing the entire r.References, and in that case, we can add r.ReplaceReferences(references), but I am not sure when this would be necessary.