@@ -36,6 +36,44 @@ import (
3636// constructed from the Read operation, is compared to the Resource we got from
3737// the Kubernetes API server's event bus. The code that is returned from this
3838// function is the code that compares those two Resources.
39+ //
40+ // The Go code we return depends on the Go type of the various fields for the
41+ // resource being compared.
42+ //
43+ // For *scalar* Go types, the output Go code looks like this:
44+ //
45+ // if ackcompare.HasNilDifference(a.ko.Spec.GrantFullControl, b.ko.Spec.GrantFullControl) {
46+ // delta.Add("Spec.GrantFullControl", a.ko.Spec.GrantFullControl, b.ko.Spec.GrantFullControl)
47+ // } else if a.ko.Spec.GrantFullControl != nil && b.ko.Spec.GrantFullControl != nil {
48+ // if *a.ko.Spec.GrantFullControl != *b.ko.Spec.GrantFullControl {
49+ // delta.Add("Spec.GrantFullControl", a.ko.Spec.GrantFullControl, b.ko.Spec.GrantFullControl)
50+ // }
51+ // }
52+ //
53+ // For *struct* Go types, the output Go code looks like this (note that it is a
54+ // simple recursive-descent output of all the struct's fields...):
55+ //
56+ // if ackcompare.HasNilDifference(a.ko.Spec.CreateBucketConfiguration, b.ko.Spec.CreateBucketConfiguration) {
57+ // delta.Add("Spec.CreateBucketConfiguration", a.ko.Spec.CreateBucketConfiguration, b.ko.Spec.CreateBucketConfiguration)
58+ // } else if a.ko.Spec.CreateBucketConfiguration != nil && b.ko.Spec.CreateBucketConfiguration != nil {
59+ // if ackcompare.HasNilDifference(a.ko.Spec.CreateBucketConfiguration.LocationConstraint, b.ko.Spec.CreateBucketConfiguration.LocationConstraint) {
60+ // delta.Add("Spec.CreateBucketConfiguration.LocationConstraint", a.ko.Spec.CreateBucketConfiguration.LocationConstraint, b.ko.Spec.CreateBucketConfiguration.LocationConstraint)
61+ // } else if a.ko.Spec.CreateBucketConfiguration.LocationConstraint != nil && b.ko.Spec.CreateBucketConfiguration.LocationConstraint != nil {
62+ // if *a.ko.Spec.CreateBucketConfiguration.LocationConstraint != *b.ko.Spec.CreateBucketConfiguration.LocationConstraint {
63+ // delta.Add("Spec.CreateBucketConfiguration.LocationConstraint", a.ko.Spec.CreateBucketConfiguration.LocationConstraint, b.ko.Spec.CreateBucketConfiguration.LocationConstraint)
64+ // }
65+ // }
66+ // }
67+ //
68+ // For *slice of strings* Go types, the output Go code looks like this:
69+ //
70+ // if ackcompare.HasNilDifference(a.ko.Spec.AllowedPublishers, b.ko.Spec.AllowedPublishers) {
71+ // delta.Add("Spec.AllowedPublishers", a.ko.Spec.AllowedPublishers, b.ko.Spec.AllowedPublishers)
72+ // } else if a.ko.Spec.AllowedPublishers != nil && b.ko.Spec.AllowedPublishers != nil {
73+ // if !ackcompare.SliceStringPEqual(a.ko.Spec.AllowedPublishers.SigningProfileVersionARNs, b.ko.Spec.AllowedPublishers.SigningProfileVersionARNs) {
74+ // delta.Add("Spec.AllowedPublishers.SigningProfileVersionARNs", a.ko.Spec.AllowedPublishers.SigningProfileVersionARNs, b.ko.Spec.AllowedPublishers.SigningProfileVersionARNs)
75+ // }
76+ // }
3977func CompareResource (
4078 cfg * ackgenconfig.Config ,
4179 r * model.CRD ,
@@ -113,8 +151,6 @@ func CompareResource(
113151 nilCode , firstResAdaptedVarName , secondResAdaptedVarName ,
114152 )
115153 indentLevel ++
116- } else {
117- out += "\n "
118154 }
119155
120156 switch memberShape .Type {
@@ -363,10 +399,15 @@ func compareMap(
363399 indent , firstResVarName , secondResVarName ,
364400 )
365401 case "structure" :
366- // TODO(jaypipes): Implement this by walking the keys and struct values
367- // and comparing each struct individually, building up the fieldPath
368- // appropriately...
369- return ""
402+ // NOTE(jaypipes): Using reflect here is really punting. We should
403+ // implement this in a cleaner, more efficient fashion by walking the
404+ // keys and struct values and comparing each struct individually,
405+ // building up the fieldPath appropriately and calling into a
406+ // struct-specific comparator function...
407+ out += fmt .Sprintf (
408+ "%sif !reflect.DeepEqual(%s, %s) {\n " ,
409+ indent , firstResVarName , secondResVarName ,
410+ )
370411 default :
371412 panic ("Unsupported shape type in generate.code.compareMap: " + shape .Type )
372413 }
@@ -431,10 +472,16 @@ func compareSlice(
431472 indent , firstResVarName , secondResVarName ,
432473 )
433474 case "structure" :
434- // TODO(jaypipes): Implement this by walking the slice of struct values
435- // and comparing each struct individually, building up the fieldPath
436- // appropriately...
437- return ""
475+ // NOTE(jaypipes): Using reflect here is really punting. We should
476+ // implement this in a cleaner, more efficient fashion by walking the
477+ // struct values and comparing each struct individually, building up
478+ // the fieldPath appropriately and calling into a struct-specific
479+ // comparator function...the tricky part of this is figuring out how to
480+ // sort the slice of structs...
481+ out += fmt .Sprintf (
482+ "%sif !reflect.DeepEqual(%s, %s) {\n " ,
483+ indent , firstResVarName , secondResVarName ,
484+ )
438485 default :
439486 panic ("Unsupported shape type in generate.code.compareSlice: " + shape .Type )
440487 }
@@ -531,8 +578,6 @@ func compareStruct(
531578 nilCode , firstResAdaptedVarName , secondResAdaptedVarName ,
532579 )
533580 indentLevel ++
534- } else {
535- out += "\n "
536581 }
537582 switch memberShape .Type {
538583 case "structure" :
0 commit comments