Skip to content

Commit a575e84

Browse files
authored
Merge pull request #140 from JoelSpeed/update-conditions-output
Update conditions output to include parent struct name
2 parents 2e946af + 024a848 commit a575e84

File tree

13 files changed

+137
-132
lines changed

13 files changed

+137
-132
lines changed

pkg/analysis/conditions/analyzer.go

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -100,14 +100,17 @@ func (a *analyzer) run(pass *analysis.Pass) (any, error) {
100100
return nil, kalerrors.ErrCouldNotGetMarkers
101101
}
102102

103-
// Filter to structs so that we can iterate over fields in a struct.
104-
// We need a struct here so that we can tell where in the struct the field is.
105103
nodeFilter := []ast.Node{
106-
(*ast.StructType)(nil),
104+
(*ast.TypeSpec)(nil),
107105
}
108106

109107
inspect.Preorder(nodeFilter, func(n ast.Node) {
110-
sTyp, ok := n.(*ast.StructType)
108+
tSpec, ok := n.(*ast.TypeSpec)
109+
if !ok {
110+
return
111+
}
112+
113+
sTyp, ok := tSpec.Type.(*ast.StructType)
111114
if !ok {
112115
return
113116
}
@@ -116,35 +119,37 @@ func (a *analyzer) run(pass *analysis.Pass) (any, error) {
116119
return
117120
}
118121

122+
structName := tSpec.Name.Name
123+
119124
for i, field := range sTyp.Fields.List {
120125
fieldMarkers := markersAccess.FieldMarkers(field)
121126

122-
a.checkField(pass, i, field, fieldMarkers)
127+
a.checkField(pass, i, field, fieldMarkers, structName)
123128
}
124129
})
125130

126131
return nil, nil //nolint:nilnil
127132
}
128133

129-
func (a *analyzer) checkField(pass *analysis.Pass, index int, field *ast.Field, fieldMarkers markers.MarkerSet) {
134+
func (a *analyzer) checkField(pass *analysis.Pass, index int, field *ast.Field, fieldMarkers markers.MarkerSet, structName string) {
130135
if !fieldIsCalledConditions(field) {
131136
return
132137
}
133138

134139
if !isSliceMetaV1Condition(field) {
135-
pass.Reportf(field.Pos(), "Conditions field must be a slice of metav1.Condition")
140+
pass.Reportf(field.Pos(), "Conditions field in %s must be a slice of metav1.Condition", structName)
136141
return
137142
}
138143

139-
checkFieldMarkers(pass, field, fieldMarkers, a.usePatchStrategy)
140-
a.checkFieldTags(pass, index, field)
144+
checkFieldMarkers(pass, field, fieldMarkers, a.usePatchStrategy, structName)
145+
a.checkFieldTags(pass, index, field, structName)
141146

142147
if a.isFirstField == ConditionsFirstFieldWarn && index != 0 {
143-
pass.Reportf(field.Pos(), "Conditions field must be the first field in the struct")
148+
pass.Reportf(field.Pos(), "Conditions field in %s must be the first field in the struct", structName)
144149
}
145150
}
146151

147-
func checkFieldMarkers(pass *analysis.Pass, field *ast.Field, fieldMarkers markers.MarkerSet, usePatchStrategy ConditionsUsePatchStrategy) {
152+
func checkFieldMarkers(pass *analysis.Pass, field *ast.Field, fieldMarkers markers.MarkerSet, usePatchStrategy ConditionsUsePatchStrategy, structName string) {
148153
missingMarkers := []string{}
149154
additionalMarkers := []markers.Marker{}
150155

@@ -165,11 +170,11 @@ func checkFieldMarkers(pass *analysis.Pass, field *ast.Field, fieldMarkers marke
165170
}
166171

167172
if len(missingMarkers) != 0 {
168-
reportMissingMarkers(pass, field, missingMarkers, usePatchStrategy)
173+
reportMissingMarkers(pass, field, missingMarkers, usePatchStrategy, structName)
169174
}
170175

171176
if len(additionalMarkers) != 0 {
172-
reportAdditionalMarkers(pass, field, additionalMarkers)
177+
reportAdditionalMarkers(pass, field, additionalMarkers, structName)
173178
}
174179
}
175180

@@ -203,11 +208,11 @@ func checkPatchStrategyMarkers(fieldMarkers markers.MarkerSet, usePatchStrategy
203208
return missingMarkers, additionalMarkers
204209
}
205210

206-
func reportMissingMarkers(pass *analysis.Pass, field *ast.Field, missingMarkers []string, usePatchStrategy ConditionsUsePatchStrategy) {
211+
func reportMissingMarkers(pass *analysis.Pass, field *ast.Field, missingMarkers []string, usePatchStrategy ConditionsUsePatchStrategy, structName string) {
207212
suggestedFixes := []analysis.SuggestedFix{}
208213

209214
// If patch strategy is warn, and the only markers in the list are patchStrategy and patchMergeKeyType, we don't need to suggest a fix.
210-
if usePatchStrategy != ConditionsUsePatchStrategyWarn || slices.ContainsFunc[[]string, string](missingMarkers, func(marker string) bool {
215+
if usePatchStrategy != ConditionsUsePatchStrategyWarn || slices.ContainsFunc(missingMarkers, func(marker string) bool {
211216
switch marker {
212217
case patchStrategyMerge, patchMergeKeyType:
213218
return false
@@ -232,12 +237,12 @@ func reportMissingMarkers(pass *analysis.Pass, field *ast.Field, missingMarkers
232237
pass.Report(analysis.Diagnostic{
233238
Pos: field.Pos(),
234239
End: field.End(),
235-
Message: "Conditions field is missing the following markers: " + strings.Join(missingMarkers, ", "),
240+
Message: "Conditions field in " + structName + " is missing the following markers: " + strings.Join(missingMarkers, ", "),
236241
SuggestedFixes: suggestedFixes,
237242
})
238243
}
239244

240-
func reportAdditionalMarkers(pass *analysis.Pass, field *ast.Field, additionalMarkers []markers.Marker) {
245+
func reportAdditionalMarkers(pass *analysis.Pass, field *ast.Field, additionalMarkers []markers.Marker, structName string) {
241246
suggestedFixes := []analysis.SuggestedFix{}
242247
additionalMarkerValues := []string{}
243248

@@ -259,7 +264,7 @@ func reportAdditionalMarkers(pass *analysis.Pass, field *ast.Field, additionalMa
259264
pass.Report(analysis.Diagnostic{
260265
Pos: field.Pos(),
261266
End: field.End(),
262-
Message: fmt.Sprintf("Conditions field has the following additional markers: %s", strings.Join(additionalMarkerValues, ", ")),
267+
Message: fmt.Sprintf("Conditions field in %s has the following additional markers: %s", structName, strings.Join(additionalMarkerValues, ", ")),
263268
SuggestedFixes: suggestedFixes,
264269
})
265270
}
@@ -274,14 +279,14 @@ func getNewMarkers(missingMarkers []string) []byte {
274279
return []byte(out)
275280
}
276281

277-
func (a *analyzer) checkFieldTags(pass *analysis.Pass, index int, field *ast.Field) {
282+
func (a *analyzer) checkFieldTags(pass *analysis.Pass, index int, field *ast.Field, structName string) {
278283
if field.Tag == nil {
279284
expectedTag := getExpectedTag(a.usePatchStrategy, a.useProtobuf, a.isFirstField, index)
280285

281286
pass.Report(analysis.Diagnostic{
282287
Pos: field.Pos(),
283288
End: field.End(),
284-
Message: fmt.Sprintf("Conditions field is missing tags, should be: %s", expectedTag),
289+
Message: fmt.Sprintf("Conditions field in %s is missing tags, should be: %s", structName, expectedTag),
285290
SuggestedFixes: []analysis.SuggestedFix{
286291
{
287292
Message: fmt.Sprintf("Add missing tags: %s", expectedTag),
@@ -304,12 +309,12 @@ func (a *analyzer) checkFieldTags(pass *analysis.Pass, index int, field *ast.Fie
304309
expectedTag := getExpectedTag(a.usePatchStrategy, a.useProtobuf, a.isFirstField, index)
305310

306311
if !shouldFix {
307-
pass.Reportf(field.Tag.ValuePos, "Conditions field has incorrect tags, should be: %s", expectedTag)
312+
pass.Reportf(field.Tag.ValuePos, "Conditions field in %s has incorrect tags, should be: %s", structName, expectedTag)
308313
} else {
309314
pass.Report(analysis.Diagnostic{
310315
Pos: field.Tag.ValuePos,
311316
End: field.Tag.End(),
312-
Message: fmt.Sprintf("Conditions field has incorrect tags, should be: %s", expectedTag),
317+
Message: fmt.Sprintf("Conditions field in %s has incorrect tags, should be: %s", structName, expectedTag),
313318
SuggestedFixes: []analysis.SuggestedFix{
314319
{
315320
Message: fmt.Sprintf("Update tags to: %s", expectedTag),

pkg/analysis/conditions/testdata/src/a/a.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,48 +32,48 @@ type ConditionsNotFirst struct {
3232
// +patchStrategy=merge
3333
// +patchMergeKey=type
3434
// +optional
35-
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` // want "Conditions field must be the first field in the struct"
35+
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` // want "Conditions field in ConditionsNotFirst must be the first field in the struct"
3636
}
3737

3838
type ConditionsIncorrectType struct {
3939
// conditions has an incorrect type.
40-
Conditions map[string]metav1.Condition // want "Conditions field must be a slice of metav1.Condition"
40+
Conditions map[string]metav1.Condition // want "Conditions field in ConditionsIncorrectType must be a slice of metav1.Condition"
4141
}
4242

4343
type ConditionsIncorrectSliceElement struct {
4444
// conditions has an incorrect type.
45-
Conditions []string // want "Conditions field must be a slice of metav1.Condition"
45+
Conditions []string // want "Conditions field in ConditionsIncorrectSliceElement must be a slice of metav1.Condition"
4646
}
4747

4848
type ConditionsIncorrectImportedSliceElement struct {
4949
// conditions has an incorrect type.
50-
Conditions []metav1.Time // want "Conditions field must be a slice of metav1.Condition"
50+
Conditions []metav1.Time // want "Conditions field in ConditionsIncorrectImportedSliceElement must be a slice of metav1.Condition"
5151
}
5252

5353
type ConditionsIncorrectImportedPackage struct {
5454
// conditions has an incorrect type.
55-
Conditions []ast.Node // want "Conditions field must be a slice of metav1.Condition"
55+
Conditions []ast.Node // want "Conditions field in ConditionsIncorrectImportedPackage must be a slice of metav1.Condition"
5656
}
5757

5858
type MissingAllMarkers struct {
5959
// conditions is missing all markers.
60-
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` // want "Conditions field is missing the following markers: listType=map, listMapKey=type, patchStrategy=merge, patchMergeKey=type, optional"
60+
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` // want "Conditions field in MissingAllMarkers is missing the following markers: listType=map, listMapKey=type, patchStrategy=merge, patchMergeKey=type, optional"
6161
}
6262

6363
type MissingListMarkers struct {
6464
// conditions is missing list markers.
6565
// +patchStrategy=merge
6666
// +patchMergeKey=type
6767
// +optional
68-
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` // want "Conditions field is missing the following markers: listType=map, listMapKey=type"
68+
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` // want "Conditions field in MissingListMarkers is missing the following markers: listType=map, listMapKey=type"
6969
}
7070

7171
type MissingPatchMarkers struct {
7272
// conditions is missing patch markers.
7373
// +listType=map
7474
// +listMapKey=type
7575
// +optional
76-
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` // want "Conditions field is missing the following markers: patchStrategy=merge, patchMergeKey=type"
76+
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` // want "Conditions field in MissingPatchMarkers is missing the following markers: patchStrategy=merge, patchMergeKey=type"
7777
}
7878

7979
type MissingOptionalMarker struct {
@@ -82,7 +82,7 @@ type MissingOptionalMarker struct {
8282
// +listMapKey=type
8383
// +patchStrategy=merge
8484
// +patchMergeKey=type
85-
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` // want "Conditions field is missing the following markers: optional"
85+
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` // want "Conditions field in MissingOptionalMarker is missing the following markers: optional"
8686
}
8787

8888
type MissingFieldTag struct {
@@ -92,7 +92,7 @@ type MissingFieldTag struct {
9292
// +patchStrategy=merge
9393
// +patchMergeKey=type
9494
// +optional
95-
Conditions []metav1.Condition // want "Conditions field is missing tags, should be: `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`"
95+
Conditions []metav1.Condition // want "Conditions field in MissingFieldTag is missing tags, should be: `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`"
9696
}
9797

9898
type IncorrectFieldTag struct {
@@ -102,5 +102,5 @@ type IncorrectFieldTag struct {
102102
// +patchStrategy=merge
103103
// +patchMergeKey=type
104104
// +optional
105-
Conditions []metav1.Condition `json:"conditions" patchMergeKey:"type" protobuf:"bytes,3,rep,name=conditions"` // want "Conditions field has incorrect tags, should be: `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`"
105+
Conditions []metav1.Condition `json:"conditions" patchMergeKey:"type" protobuf:"bytes,3,rep,name=conditions"` // want "Conditions field in IncorrectFieldTag has incorrect tags, should be: `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`"
106106
}

pkg/analysis/conditions/testdata/src/a/a.go.golden

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,27 +32,27 @@ type ConditionsNotFirst struct {
3232
// +patchStrategy=merge
3333
// +patchMergeKey=type
3434
// +optional
35-
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` // want "Conditions field must be the first field in the struct"
35+
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` // want "Conditions field in ConditionsNotFirst must be the first field in the struct"
3636
}
3737

3838
type ConditionsIncorrectType struct {
3939
// conditions has an incorrect type.
40-
Conditions map[string]metav1.Condition // want "Conditions field must be a slice of metav1.Condition"
40+
Conditions map[string]metav1.Condition // want "Conditions field in ConditionsIncorrectType must be a slice of metav1.Condition"
4141
}
4242

4343
type ConditionsIncorrectSliceElement struct {
4444
// conditions has an incorrect type.
45-
Conditions []string // want "Conditions field must be a slice of metav1.Condition"
45+
Conditions []string // want "Conditions field in ConditionsIncorrectSliceElement must be a slice of metav1.Condition"
4646
}
4747

4848
type ConditionsIncorrectImportedSliceElement struct {
4949
// conditions has an incorrect type.
50-
Conditions []metav1.Time // want "Conditions field must be a slice of metav1.Condition"
50+
Conditions []metav1.Time // want "Conditions field in ConditionsIncorrectImportedSliceElement must be a slice of metav1.Condition"
5151
}
5252

5353
type ConditionsIncorrectImportedPackage struct {
5454
// conditions has an incorrect type.
55-
Conditions []ast.Node // want "Conditions field must be a slice of metav1.Condition"
55+
Conditions []ast.Node // want "Conditions field in ConditionsIncorrectImportedPackage must be a slice of metav1.Condition"
5656
}
5757

5858
type MissingAllMarkers struct {
@@ -62,7 +62,7 @@ type MissingAllMarkers struct {
6262
// +patchStrategy=merge
6363
// +patchMergeKey=type
6464
// +optional
65-
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` // want "Conditions field is missing the following markers: listType=map, listMapKey=type, patchStrategy=merge, patchMergeKey=type, optional"
65+
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` // want "Conditions field in MissingAllMarkers is missing the following markers: listType=map, listMapKey=type, patchStrategy=merge, patchMergeKey=type, optional"
6666
}
6767

6868
type MissingListMarkers struct {
@@ -72,7 +72,7 @@ type MissingListMarkers struct {
7272
// +optional
7373
// +listType=map
7474
// +listMapKey=type
75-
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` // want "Conditions field is missing the following markers: listType=map, listMapKey=type"
75+
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` // want "Conditions field in MissingListMarkers is missing the following markers: listType=map, listMapKey=type"
7676
}
7777

7878
type MissingPatchMarkers struct {
@@ -82,7 +82,7 @@ type MissingPatchMarkers struct {
8282
// +optional
8383
// +patchStrategy=merge
8484
// +patchMergeKey=type
85-
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` // want "Conditions field is missing the following markers: patchStrategy=merge, patchMergeKey=type"
85+
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` // want "Conditions field in MissingPatchMarkers is missing the following markers: patchStrategy=merge, patchMergeKey=type"
8686
}
8787

8888
type MissingOptionalMarker struct {
@@ -92,7 +92,7 @@ type MissingOptionalMarker struct {
9292
// +patchStrategy=merge
9393
// +patchMergeKey=type
9494
// +optional
95-
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` // want "Conditions field is missing the following markers: optional"
95+
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` // want "Conditions field in MissingOptionalMarker is missing the following markers: optional"
9696
}
9797

9898
type MissingFieldTag struct {
@@ -102,7 +102,7 @@ type MissingFieldTag struct {
102102
// +patchStrategy=merge
103103
// +patchMergeKey=type
104104
// +optional
105-
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` // want "Conditions field is missing tags, should be: `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`"
105+
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` // want "Conditions field in MissingFieldTag is missing tags, should be: `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`"
106106
}
107107

108108
type IncorrectFieldTag struct {
@@ -112,5 +112,5 @@ type IncorrectFieldTag struct {
112112
// +patchStrategy=merge
113113
// +patchMergeKey=type
114114
// +optional
115-
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` // want "Conditions field has incorrect tags, should be: `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`"
115+
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` // want "Conditions field in IncorrectFieldTag has incorrect tags, should be: `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`"
116116
}

0 commit comments

Comments
 (0)