@@ -99,6 +99,11 @@ func CompareResource(
99
99
100
100
resConfig := cfg .GetResourceConfig (r .Names .Camel )
101
101
102
+ tagField , err := r .GetTagField ()
103
+ if err != nil {
104
+ panic (err )
105
+ }
106
+
102
107
// We need a deterministic order to traverse our top-level fields...
103
108
specFieldNames := []string {}
104
109
for fieldName := range r .SpecFields {
@@ -147,10 +152,18 @@ func CompareResource(
147
152
out += fmt .Sprintf ("%s}\n " , indent )
148
153
continue
149
154
}
155
+
156
+ // Use a special comparison model for tags, since they need to be
157
+ // converted into the common ACK tag type before doing a map delta
158
+ if tagField != nil && specField == tagField {
159
+ out += compareTags (deltaVarName , firstResAdaptedVarName , secondResAdaptedVarName , fieldPath , indentLevel )
160
+ continue
161
+ }
162
+
150
163
memberShapeRef := specField .ShapeRef
151
164
memberShape := memberShapeRef .Shape
152
165
153
- // if ackcompare.HasNilDifference(a.ko.Spec.Name, b.ko.Spec.Name == nil ) {
166
+ // if ackcompare.HasNilDifference(a.ko.Spec.Name, b.ko.Spec.Name) {
154
167
// delta.Add("Spec.Name", a.ko.Spec.Name, b.ko.Spec.Name)
155
168
// }
156
169
nilCode := compareNil (
@@ -520,6 +533,46 @@ func compareSlice(
520
533
return out
521
534
}
522
535
536
+ // compareTags outputs Go code that compares two slices of tags from two
537
+ // resource fields by first converting them to the common ACK tag type and then
538
+ // using a map comparison. If there is a difference, adds the difference to a
539
+ // variable representing an `ackcompare.Delta`.
540
+ //
541
+ // Output code will look something like this:
542
+ //
543
+ // if !ackcompare.MapStringStringEqual(ToACKTags(a.ko.Spec.Tags), ToACKTags(b.ko.Spec.Tags)) {
544
+ // delta.Add("Spec.Tags", a.ko.Spec.Tags, b.ko.Spec.Tags)
545
+ // }
546
+ func compareTags (
547
+ // String representing the name of the variable that is of type
548
+ // `*ackcompare.Delta`. We will generate Go code that calls the `Add()`
549
+ // method of this variable when differences between fields are detected.
550
+ deltaVarName string ,
551
+ // String representing the name of the variable that represents the first
552
+ // CR under comparison. This will typically be something like
553
+ // "a.ko.Spec.Name". See `templates/pkg/resource/delta.go.tpl`.
554
+ firstResVarName string ,
555
+ // String representing the name of the variable that represents the second
556
+ // CR under comparison. This will typically be something like
557
+ // "b.ko.Spec.Name". See `templates/pkg/resource/delta.go.tpl`.
558
+ secondResVarName string ,
559
+ // String indicating the current field path being evaluated, e.g.
560
+ // "Author.Name". This does not include the top-level Spec or Status
561
+ // struct.
562
+ fieldPath string ,
563
+ // Number of levels of indentation to use
564
+ indentLevel int ,
565
+ ) string {
566
+ out := ""
567
+ indent := strings .Repeat ("\t " , indentLevel )
568
+
569
+ out += fmt .Sprintf ("%sif !ackcompare.MapStringStringEqual(ToACKTags(%s), ToACKTags(%s)) {\n " , indent , firstResVarName , secondResVarName )
570
+ out += fmt .Sprintf ("%s\t %s.Add(\" %s\" , %s, %s)\n " , indent , deltaVarName , fieldPath , firstResVarName , secondResVarName )
571
+ out += fmt .Sprintf ("%s}\n " , indent )
572
+
573
+ return out
574
+ }
575
+
523
576
// CompareStruct outputs Go code that compares two struct values from two
524
577
// resource fields and, if there is a difference, adds the difference to a
525
578
// variable representing an `ackcompare.Delta`.
@@ -551,6 +604,11 @@ func CompareStruct(
551
604
) string {
552
605
out := ""
553
606
607
+ tagField , err := r .GetTagField ()
608
+ if err != nil {
609
+ panic (err )
610
+ }
611
+
554
612
fieldConfigs := cfg .GetFieldConfigs (r .Names .Original )
555
613
556
614
for _ , memberName := range shape .MemberNames () {
@@ -572,7 +630,9 @@ func CompareStruct(
572
630
// memberFieldPath contains the field path along with the prefix cfg.PrefixConfig.SpecField + "." hence we
573
631
// would need to substring to exclude cfg.PrefixConfig.SpecField + "." to get correct field config.
574
632
specFieldLen := len (strings .TrimPrefix (cfg .PrefixConfig .SpecField , "." ))
575
- fieldConfig := fieldConfigs [memberFieldPath [specFieldLen + 1 :len (memberFieldPath )]]
633
+ trimmedFieldPath := memberFieldPath [specFieldLen + 1 :]
634
+
635
+ fieldConfig := fieldConfigs [trimmedFieldPath ]
576
636
if fieldConfig != nil {
577
637
compareConfig = fieldConfig .Compare
578
638
}
@@ -583,6 +643,13 @@ func CompareStruct(
583
643
584
644
memberShape := memberShapeRef .Shape
585
645
646
+ // Use a special comparison model for tags, since they need to be
647
+ // converted into the common ACK tag type before doing a map delta
648
+ if tagField != nil && tagField .Path == trimmedFieldPath {
649
+ out += compareTags (deltaVarName , firstResAdaptedVarName , secondResAdaptedVarName , fieldPath , indentLevel )
650
+ continue
651
+ }
652
+
586
653
// if ackcompare.HasNilDifference(a.ko.Spec.Name, b.ko.Spec.Name == nil) {
587
654
// delta.Add("Spec.Name", a.ko.Spec.Name, b.ko.Spec.Name)
588
655
// }
@@ -604,6 +671,7 @@ func CompareStruct(
604
671
)
605
672
indentLevel ++
606
673
}
674
+
607
675
switch memberShape .Type {
608
676
case "structure" :
609
677
// Recurse through all the struct's fields and subfields, building
0 commit comments