Skip to content

Commit 70b4f7c

Browse files
authored
add Delta.DifferentExcept() method (#86)
I need the ability to detect whether there are any differences in a resource's fields *other than* a particular one. Basically, in doing the tagging work for DBInstance, I came across a problem where we were calling the ModifyDBInstance API call even though there were no changes to DBInstance Spec fields *other than* the Tags collection. So, I need to add the following in an sdk_update_pre_build_request template for DBInstance: ```go if delta.DifferentAt("Spec.Tags") { if err = rm.SyncTags(ctx, desired, latest); err != nil { return nil, err } } if !delta.DifferentExcept("Spec.Tags") { // We don't want to proceed to call the ModifyDBInstance API since // no other resource fields have changed. return desired, nil } ``` This PR adds the `delta.DifferentExcept()` implementation to enable the above code. Issue aws-controllers-k8s/community#1276 Signed-off-by: Jay Pipes <[email protected]> By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent bd4ee1d commit 70b4f7c

File tree

2 files changed

+72
-3
lines changed

2 files changed

+72
-3
lines changed

pkg/compare/delta.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,49 @@ func (d *Delta) DifferentAt(subject string) bool {
3434
return false
3535
}
3636

37+
// DifferentExcept returns true if the delta contains any differences *other*
38+
// than any of the supplied path strings.
39+
//
40+
// This method is useful if you have a scenario where you don't want to proceed
41+
// with a modification action if certain fields in a resource have not been
42+
// changed.
43+
//
44+
// For example, consider this code:
45+
//
46+
// if delta.DifferentAt("Spec.Tags") {
47+
// if err = rm.SyncTags(ctx, desired, latest); err != nil {
48+
// return nil, err
49+
// }
50+
// }
51+
// if !delta.DifferentExcept("Spec.Tags") {
52+
// // We don't want to proceed to call the ModifyDBInstance API since
53+
// // no other resource fields have changed.
54+
// return desired, nil
55+
// }
56+
//
57+
// might be placed in an sdk_update_pre_build_request custom code hook to
58+
// prevent the ModifyDBInstance call from being executed if the DBInstance's
59+
// Tags field is the only field with changes.
60+
func (d *Delta) DifferentExcept(
61+
exceptPaths ...string,
62+
) bool {
63+
numDiffs := len(d.Differences)
64+
if numDiffs == 0 {
65+
return false
66+
} else if numDiffs > len(exceptPaths) {
67+
return true
68+
}
69+
foundExcepts := 0
70+
for _, diff := range d.Differences {
71+
for _, exceptPath := range exceptPaths {
72+
if diff.Path.Contains(exceptPath) {
73+
foundExcepts++
74+
}
75+
}
76+
}
77+
return foundExcepts != numDiffs
78+
}
79+
3780
// Add adds a new Difference to the Delta
3881
func (d *Delta) Add(
3982
path string,

pkg/compare/delta_test.go

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,34 @@ func TestDifferentAt(t *testing.T) {
5959
d.Add("Baz.Y", a.Baz.Y, b.Baz.Y)
6060
require.True(d.DifferentAt("Baz"))
6161
require.True(d.DifferentAt("Baz.Y"))
62-
require.False(d.DifferentAt("Y")) // there is no diff for top-level field "Y"
63-
require.False(d.DifferentAt("Bar")) // diff exists but it was not added to Delta
62+
require.False(d.DifferentAt("Y")) // there is no diff for top-level field "Y"
63+
require.False(d.DifferentAt("Bar")) // diff exists but it was not added to Delta
6464
require.False(d.DifferentAt("Baz.Y.Z")) // subject length exceeds length of diff Path
65-
require.False(d.DifferentAt("Baz.Z")) // matches Path top-level field but not sub-field
65+
require.False(d.DifferentAt("Baz.Z")) // matches Path top-level field but not sub-field
66+
}
67+
68+
func TestDifferentExcept(t *testing.T) {
69+
require := require.New(t)
70+
71+
a := Foo{
72+
Bar: "a_bar",
73+
Baz: Baz{
74+
Y: "a_baz_y",
75+
},
76+
}
77+
b := Foo{
78+
Bar: "b_bar",
79+
Baz: Baz{
80+
Y: "b_baz_y",
81+
},
82+
}
83+
84+
d := compare.NewDelta()
85+
d.Add("", a, nil)
86+
require.False(d.DifferentExcept(""))
87+
88+
d = compare.NewDelta()
89+
d.Add("Baz.Y", a.Baz.Y, b.Baz.Y)
90+
require.True(d.DifferentExcept("Bar")) // there is a difference that is *not* Bar
91+
require.False(d.DifferentExcept("Baz.Y")) // there is *not* a different that is *not* Bar
6692
}

0 commit comments

Comments
 (0)