• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

sapslaj / mid / 16253455754

13 Jul 2025 09:07PM UTC coverage: 59.931% (-0.09%) from 60.02%
16253455754

push

github

sapslaj
chore: rebuild generated stuff

4695 of 7834 relevant lines covered (59.93%)

326.99 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.94
/pkg/pdiff/pdiff.go
1
package pdiff
2

3
import (
4
        "maps"
5
        "reflect"
6
        "slices"
7
        "strings"
8

9
        p "github.com/pulumi/pulumi-go-provider"
10
        "github.com/pulumi/pulumi/sdk/v3/go/common/resource"
11
        "github.com/pulumi/pulumi/sdk/v3/go/common/resource/plugin"
12
        "github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"
13

14
        "github.com/sapslaj/mid/pkg/pulumi-go-provider/ende"
15
        "github.com/sapslaj/mid/pkg/pulumi-go-provider/introspect"
16
)
17

18
// DiffAttributes performs deep equality on two structs only for the attributes
19
// provided and returns a DiffResponse
20
func DiffAttributes(inputs any, state any, attributes []string) p.DiffResponse {
39✔
21
        inputProps, err := introspect.FindProperties(reflect.TypeOf(inputs))
39✔
22
        contract.AssertNoErrorf(err, "could not get properties")
39✔
23

39✔
24
        encoder := &ende.Encoder{}
39✔
25

39✔
26
        inputsMap, err := encoder.Encode(inputs)
39✔
27
        contract.AssertNoErrorf(err, "could not diff inputs")
39✔
28

39✔
29
        stateMap, err := encoder.Encode(state)
39✔
30
        contract.AssertNoErrorf(err, "could not diff state")
39✔
31

39✔
32
        // Olds is an Output, but news is an Input. Output should be a superset of
39✔
33
        // Input, so we need to filter out fields that are in Output but not Input.
39✔
34
        oldInputsMap := resource.PropertyMap{}
39✔
35
        for k := range inputsMap {
159✔
36
                oldInputsMap[k] = stateMap[k]
120✔
37
        }
120✔
38

39
        objDiff := oldInputsMap.Diff(inputsMap)
39✔
40
        pluginDiff := plugin.NewDetailedDiffFromObjectDiff(objDiff, true)
39✔
41
        diff := map[string]p.PropertyDiff{}
39✔
42

39✔
43
        for k, v := range pluginDiff {
78✔
44
                selected := false
39✔
45
                for i := range attributes {
413✔
46
                        // FIXME: this has the potential to be too greedy and match things it
374✔
47
                        // shouldn't. It should be breaking down the components of the key and
374✔
48
                        // ensuring there is a full match for all the components but i ain't got
374✔
49
                        // time to write that.
374✔
50
                        if strings.HasPrefix(k, attributes[i]) {
397✔
51
                                selected = true
23✔
52
                        }
23✔
53
                }
54
                if !selected {
55✔
55
                        continue
16✔
56
                }
57

58
                set := func(kind p.DiffKind) {
46✔
59
                        diff[k] = p.PropertyDiff{
23✔
60
                                Kind:      kind,
23✔
61
                                InputDiff: v.InputDiff,
23✔
62
                        }
23✔
63
                }
23✔
64

65
                fieldTag := inputProps[k]
23✔
66
                if fieldTag.ReplaceOnChanges {
27✔
67
                        v.Kind = v.Kind.AsReplace()
4✔
68
                }
4✔
69

70
                switch v.Kind {
23✔
71
                case plugin.DiffAdd:
1✔
72
                        set(p.Add)
1✔
73
                case plugin.DiffAddReplace:
×
74
                        set(p.AddReplace)
×
75
                case plugin.DiffDelete:
×
76
                        set(p.Delete)
×
77
                case plugin.DiffDeleteReplace:
×
78
                        set(p.DeleteReplace)
×
79
                case plugin.DiffUpdate:
18✔
80
                        set(p.Update)
18✔
81
                case plugin.DiffUpdateReplace:
4✔
82
                        set(p.UpdateReplace)
4✔
83
                }
84
        }
85
        return p.DiffResponse{
39✔
86
                HasChanges:   len(diff) > 0,
39✔
87
                DetailedDiff: diff,
39✔
88
        }
39✔
89
}
90

91
// DiffAllAttributesExcept performs a deep equality on two structs for all
92
// attributes except the list provided and returns a diff response.
93
func DiffAllAttributesExcept(inputs any, state any, exceptAttributes []string) p.DiffResponse {
33✔
94
        inputProps, err := introspect.FindProperties(reflect.TypeOf(inputs))
33✔
95
        contract.AssertNoErrorf(err, "could not get properties")
33✔
96

33✔
97
        attributes := []string{}
33✔
98
        for prop := range inputProps {
569✔
99
                if !slices.Contains(exceptAttributes, prop) {
1,045✔
100
                        attributes = append(attributes, prop)
509✔
101
                }
509✔
102
        }
103

104
        return DiffAttributes(inputs, state, attributes)
33✔
105
}
106

107
// DiffAllAttributes performs a deep equality on two structs for all attributes
108
func DiffAllAttributes(inputs any, state any) p.DiffResponse {
6✔
109
        return DiffAllAttributesExcept(inputs, state, []string{})
6✔
110
}
6✔
111

112
// ForceDiffReplace changes all of the properties in the DiffResponse to be the
113
// "-replace" equivalent to trigger a resource replacement.
114
func ForceDiffReplace(diff p.DiffResponse) p.DiffResponse {
1✔
115
        for key, propdiff := range diff.DetailedDiff {
8✔
116
                switch propdiff.Kind {
7✔
117
                case p.Add:
1✔
118
                        propdiff.Kind = p.AddReplace
1✔
119
                case p.Delete:
1✔
120
                        propdiff.Kind = p.DeleteReplace
1✔
121
                case p.Update:
1✔
122
                        propdiff.Kind = p.UpdateReplace
1✔
123
                }
124
                diff.DetailedDiff[key] = propdiff
7✔
125
        }
126
        return diff
1✔
127
}
128

129
// MergeDiffResponses will merge an arbitrary number of DiffResponses together
130
// with the last taking the highest precedence. Any DiffResponse that has
131
// `HasChanges` or `DeleteBeforeReplace` set will result in the returned
132
// DiffResponse to have those set as well.
133
func MergeDiffResponses(drs ...p.DiffResponse) p.DiffResponse {
25✔
134
        diff := p.DiffResponse{
25✔
135
                HasChanges:   false,
25✔
136
                DetailedDiff: map[string]p.PropertyDiff{},
25✔
137
        }
25✔
138
        for _, dr := range drs {
101✔
139
                if dr.HasChanges {
91✔
140
                        diff.HasChanges = true
15✔
141
                }
15✔
142
                if dr.DeleteBeforeReplace {
87✔
143
                        diff.DeleteBeforeReplace = true
11✔
144
                }
11✔
145
                maps.Copy(diff.DetailedDiff, dr.DetailedDiff)
76✔
146
        }
147
        return diff
25✔
148
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc