Skip to content

Commit 350d7ca

Browse files
committed
Update to use markers constants
1 parent 009f2b2 commit 350d7ca

File tree

3 files changed

+54
-28
lines changed

3 files changed

+54
-28
lines changed

pkg/analysis/optionalfields/analyzer.go

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -25,30 +25,41 @@ import (
2525
kalerrors "sigs.k8s.io/kube-api-linter/pkg/analysis/errors"
2626
"sigs.k8s.io/kube-api-linter/pkg/analysis/helpers/extractjsontags"
2727
"sigs.k8s.io/kube-api-linter/pkg/analysis/helpers/inspector"
28-
"sigs.k8s.io/kube-api-linter/pkg/analysis/helpers/markers"
28+
markershelper "sigs.k8s.io/kube-api-linter/pkg/analysis/helpers/markers"
2929
"sigs.k8s.io/kube-api-linter/pkg/config"
30+
"sigs.k8s.io/kube-api-linter/pkg/markers"
3031

3132
"k8s.io/utils/ptr"
3233
)
3334

3435
const (
3536
name = "optionalfields"
3637

37-
optionalMarker = "optional"
38-
requiredMarker = "required"
39-
kubebuilderOptinalMarker = "kubebuilder:validation:Optional"
40-
kubebuilderRequiredMarker = "kubebuilder:validation:Required"
38+
optionalMarker = markers.OptionalMarker
39+
requiredMarker = markers.RequiredMarker
40+
kubebuilderOptionalMarker = markers.KubebuilderOptionalMarker
41+
kubebuilderRequiredMarker = markers.KubebuilderRequiredMarker
4142

42-
minItemsMarker = "kubebuilder:validation:MinItems"
43-
minLengthMarker = "kubebuilder:validation:MinLength"
44-
minPropertiesMarker = "kubebuilder:validation:MinProperties"
43+
minItemsMarker = markers.KubebuilderMinItemsMarker
44+
minLengthMarker = markers.KubebuilderMinLengthMarker
45+
minPropertiesMarker = markers.KubebuilderMinPropertiesMarker
4546

46-
minimumMarker = "kubebuilder:validation:Minimum"
47-
maximumMarker = "kubebuilder:validation:Maximum"
47+
minimumMarker = markers.KubebuilderMinimumMarker
48+
maximumMarker = markers.KubebuilderMaximumMarker
4849
)
4950

5051
func init() {
51-
markers.DefaultRegistry().Register(optionalMarker, kubebuilderOptinalMarker)
52+
markershelper.DefaultRegistry().Register(
53+
optionalMarker,
54+
requiredMarker,
55+
kubebuilderOptionalMarker,
56+
kubebuilderRequiredMarker,
57+
minItemsMarker,
58+
minLengthMarker,
59+
minPropertiesMarker,
60+
minimumMarker,
61+
maximumMarker,
62+
)
5263
}
5364

5465
var (
@@ -90,14 +101,14 @@ func (a *analyzer) run(pass *analysis.Pass) (any, error) {
90101
return nil, kalerrors.ErrCouldNotGetInspector
91102
}
92103

93-
inspect.InspectFields(func(field *ast.Field, stack []ast.Node, jsonTagInfo extractjsontags.FieldTagInfo, markersAccess markers.Markers) {
104+
inspect.InspectFields(func(field *ast.Field, stack []ast.Node, jsonTagInfo extractjsontags.FieldTagInfo, markersAccess markershelper.Markers) {
94105
a.checkField(pass, field, markersAccess, jsonTagInfo)
95106
})
96107

97108
return nil, nil //nolint:nilnil
98109
}
99110

100-
func (a *analyzer) checkField(pass *analysis.Pass, field *ast.Field, markersAccess markers.Markers, jsonTags extractjsontags.FieldTagInfo) {
111+
func (a *analyzer) checkField(pass *analysis.Pass, field *ast.Field, markersAccess markershelper.Markers, jsonTags extractjsontags.FieldTagInfo) {
101112
if field == nil || len(field.Names) == 0 {
102113
return
103114
}
@@ -152,7 +163,7 @@ func (a *analyzer) checkFieldOmitEmpty(pass *analysis.Pass, field *ast.Field, fi
152163
}
153164

154165
// checkFieldPointers is used to determine if a field should be a pointer, and advise on the correct action.
155-
func (a *analyzer) checkFieldPointers(pass *analysis.Pass, field *ast.Field, fieldName string, markersAccess markers.Markers, jsonTags extractjsontags.FieldTagInfo) {
166+
func (a *analyzer) checkFieldPointers(pass *analysis.Pass, field *ast.Field, fieldName string, markersAccess markershelper.Markers, jsonTags extractjsontags.FieldTagInfo) {
156167
isStarExpr, underlyingType := isStarExpr(field.Type)
157168

158169
if isPointerType(underlyingType) {
@@ -173,7 +184,7 @@ func (a *analyzer) checkFieldPointers(pass *analysis.Pass, field *ast.Field, fie
173184
// and ensures that they aren't pointered again (e.g. no *[]string).
174185
// It will also check for the presence of non-zero min-properties and min-items
175186
// when omitempty is missing, as this will.
176-
func (a *analyzer) checkFieldPointersPointerTypes(pass *analysis.Pass, field *ast.Field, fieldName string, isStarExpr bool, markersAccess markers.Markers, jsonTags extractjsontags.FieldTagInfo) {
187+
func (a *analyzer) checkFieldPointersPointerTypes(pass *analysis.Pass, field *ast.Field, fieldName string, isStarExpr bool, markersAccess markershelper.Markers, jsonTags extractjsontags.FieldTagInfo) {
177188
if a.omitEmptyPolicy == config.OptionalFieldsOmitEmptyPolicyIgnore && !jsonTags.OmitEmpty {
178189
a.checkFieldPointersPointerTypesWithoutOmitEmpty(pass, field, fieldName, markersAccess)
179190
}
@@ -190,7 +201,7 @@ func (a *analyzer) checkFieldPointersPointerTypes(pass *analysis.Pass, field *as
190201
// and does not have the omitempty tag.
191202
// In both cases, the field should not have a minimum number of items or properties greater than 0.
192203
// Without omitempty, empty json objects and arrays would be rendered ('{}' and '[]') and would breach the minimum properties/items.
193-
func (a *analyzer) checkFieldPointersPointerTypesWithoutOmitEmpty(pass *analysis.Pass, field *ast.Field, fieldName string, markersAccess markers.Markers) {
204+
func (a *analyzer) checkFieldPointersPointerTypesWithoutOmitEmpty(pass *analysis.Pass, field *ast.Field, fieldName string, markersAccess markershelper.Markers) {
194205
switch field.Type.(type) {
195206
case *ast.MapType:
196207
reportShouldRemoveAllInstancesOfIntegerMarker(pass, field, markersAccess, minPropertiesMarker, fieldName, "field %s has a greater than zero minimum number of properties without omitempty. The minimum number of properties should be removed.")
@@ -213,7 +224,7 @@ func (a *analyzer) checkFieldPointersPreferenceAlways(pass *analysis.Pass, field
213224
// For example, if it's an integer range that includes 0, then it should be a pointer.
214225
// If the range doesn't include zero, and the field has omitempty, then the field doesn't need to be a pointer
215226
// As `0` should never be committed to the API, and round trips would not be affected by the JSON library omitting the zero value when marshalling.
216-
func (a *analyzer) checkFieldPointersPreferenceWhenRequired(pass *analysis.Pass, field *ast.Field, fieldName string, isStarExpr bool, underlyingType ast.Expr, markersAccess markers.Markers, jsonTags extractjsontags.FieldTagInfo) {
227+
func (a *analyzer) checkFieldPointersPreferenceWhenRequired(pass *analysis.Pass, field *ast.Field, fieldName string, isStarExpr bool, underlyingType ast.Expr, markersAccess markershelper.Markers, jsonTags extractjsontags.FieldTagInfo) {
217228
ident, ok := underlyingType.(*ast.Ident)
218229
if !ok {
219230
// All fields should be idents, not sure when this would happen?
@@ -244,7 +255,7 @@ func (a *analyzer) checkFieldPointersPreferenceWhenRequired(pass *analysis.Pass,
244255
}
245256
}
246257

247-
func (a *analyzer) checkFieldPointersPreferenceWhenRequiredIdentObj(pass *analysis.Pass, field *ast.Field, fieldName string, isStarExpr bool, decl *ast.TypeSpec, markersAccess markers.Markers, jsonTags extractjsontags.FieldTagInfo) {
258+
func (a *analyzer) checkFieldPointersPreferenceWhenRequiredIdentObj(pass *analysis.Pass, field *ast.Field, fieldName string, isStarExpr bool, decl *ast.TypeSpec, markersAccess markershelper.Markers, jsonTags extractjsontags.FieldTagInfo) {
248259
switch t := decl.Type.(type) {
249260
case *ast.StructType:
250261
a.checkFieldPointersPreferenceWhenRequiredStructType(pass, field, fieldName, isStarExpr, t, markersAccess, jsonTags)
@@ -260,7 +271,7 @@ func (a *analyzer) checkFieldPointersPreferenceWhenRequiredIdentObj(pass *analys
260271
// Any struct that has a minimum number of properties, or has required fields, should be a pointer.
261272
// Without a pointer, the JSON library cannot omit the field, and will always render a `{}`.
262273
// A rendered empty object would then violate the minimum number of properties/required field checks.
263-
func (a *analyzer) checkFieldPointersPreferenceWhenRequiredStructType(pass *analysis.Pass, field *ast.Field, fieldName string, isStarExpr bool, typeExpr *ast.StructType, markersAccess markers.Markers, jsonTags extractjsontags.FieldTagInfo) {
274+
func (a *analyzer) checkFieldPointersPreferenceWhenRequiredStructType(pass *analysis.Pass, field *ast.Field, fieldName string, isStarExpr bool, typeExpr *ast.StructType, markersAccess markershelper.Markers, jsonTags extractjsontags.FieldTagInfo) {
264275
hasRequiredFields := structContainsRequiredFields(typeExpr, markersAccess)
265276

266277
hasMinimumProperties, err := structHasGreaterThanZeroMinProperties(typeExpr, markersAccess.StructMarkers(typeExpr))
@@ -297,7 +308,7 @@ func (a *analyzer) checkFieldPointersPreferenceWhenRequiredStructTypeWithOmitEmp
297308

298309
// checkFieldPointersPreferenceWhenRequiredStructTypeWithoutOmitEmpty recommends adding/removing pointers based on whether the struct
299310
// has any required fields or minimum properties present, where the struct does not have omitempty as a tag.
300-
func (a *analyzer) checkFieldPointersPreferenceWhenRequiredStructTypeWithoutOmitEmpty(pass *analysis.Pass, field *ast.Field, fieldName string, isStarExpr, hasMinimumProperties, fieldHasMinimumProperties bool, markersAccess markers.Markers) {
311+
func (a *analyzer) checkFieldPointersPreferenceWhenRequiredStructTypeWithoutOmitEmpty(pass *analysis.Pass, field *ast.Field, fieldName string, isStarExpr, hasMinimumProperties, fieldHasMinimumProperties bool, markersAccess markershelper.Markers) {
301312
switch {
302313
case hasMinimumProperties && isStarExpr, fieldHasMinimumProperties && isStarExpr:
303314
// The field is already a pointer and should be a pointer, so we don't need to do anything.
@@ -315,7 +326,7 @@ func (a *analyzer) checkFieldPointersPreferenceWhenRequiredStructTypeWithoutOmit
315326
// Where the minimum allowable length is 0, the field should be a pointer.
316327
// Where the minimum length is greater than 0, the field should not be a pointer.
317328
// When the field does not have omitempty, it should not be a pointer, and should not have a minimum length marker.
318-
func (a *analyzer) checkFieldPointersPreferenceWhenRequiredString(pass *analysis.Pass, field *ast.Field, fieldName string, isStarExpr bool, markersAccess markers.Markers, jsonTags extractjsontags.FieldTagInfo) {
329+
func (a *analyzer) checkFieldPointersPreferenceWhenRequiredString(pass *analysis.Pass, field *ast.Field, fieldName string, isStarExpr bool, markersAccess markershelper.Markers, jsonTags extractjsontags.FieldTagInfo) {
319330
if a.omitEmptyPolicy == config.OptionalFieldsOmitEmptyPolicyIgnore && !jsonTags.OmitEmpty {
320331
a.checkFieldPointersPreferenceWhenRequiredStringWithoutOmitEmpty(pass, field, fieldName, isStarExpr, markersAccess)
321332
return
@@ -350,7 +361,7 @@ func (a *analyzer) checkFieldPointersPreferenceWhenRequiredString(pass *analysis
350361

351362
// checkFieldPointersPreferenceWhenRequiredStringWithoutOmitEmpty checks string fields for minimum length markers
352363
// and pointers and suggests that both are removed.
353-
func (a *analyzer) checkFieldPointersPreferenceWhenRequiredStringWithoutOmitEmpty(pass *analysis.Pass, field *ast.Field, fieldName string, isStarExpr bool, markersAccess markers.Markers) {
364+
func (a *analyzer) checkFieldPointersPreferenceWhenRequiredStringWithoutOmitEmpty(pass *analysis.Pass, field *ast.Field, fieldName string, isStarExpr bool, markersAccess markershelper.Markers) {
354365
reportShouldRemoveAllInstancesOfIntegerMarker(pass, field, markersAccess, minLengthMarker, fieldName, "field %s has a greater than zero minimum length without omitempty. The minimum length should be removed.")
355366

356367
// When non-omitempty, the string field should not be a pointer.
@@ -379,7 +390,7 @@ func (a *analyzer) checkFieldPointersPreferenceWhenRequiredBool(pass *analysis.P
379390
}
380391

381392
//nolint:dupl
382-
func (a *analyzer) checkFieldPointersPreferenceWhenRequiredInteger(pass *analysis.Pass, field *ast.Field, fieldName string, isStarExpr bool, markersAccess markers.Markers, jsonTags extractjsontags.FieldTagInfo) {
393+
func (a *analyzer) checkFieldPointersPreferenceWhenRequiredInteger(pass *analysis.Pass, field *ast.Field, fieldName string, isStarExpr bool, markersAccess markershelper.Markers, jsonTags extractjsontags.FieldTagInfo) {
383394
fieldMarkers := markersAccess.FieldMarkers(field)
384395

385396
minValue, err := getMarkerIntegerValueByName(fieldMarkers, minimumMarker)
@@ -439,7 +450,7 @@ func (a *analyzer) checkFieldPointersPreferenceWhenRequiredIntegerWithOmitEmpty(
439450
// to determine whether or not 0 is a valid value for the integer.
440451
// Where 0 is not a valid value, the field should either add omitempty, or remove the limits.
441452
// We assume since there's no omitempty that the API author wants the zero value to be marshalled and as such, suggest to remove the limits.
442-
func (a *analyzer) checkFieldPointersPreferenceWhenRequiredIntegerWithoutOmitEmpty(pass *analysis.Pass, field *ast.Field, fieldName string, minValue, maxValue *int, isStarExpr bool, fieldMarkers markers.MarkerSet) {
453+
func (a *analyzer) checkFieldPointersPreferenceWhenRequiredIntegerWithoutOmitEmpty(pass *analysis.Pass, field *ast.Field, fieldName string, minValue, maxValue *int, isStarExpr bool, fieldMarkers markershelper.MarkerSet) {
443454
switch {
444455
case minValue != nil && *minValue > 0:
445456
reportShouldRemoveMarker(pass, field, fieldMarkers.Get(minimumMarker)[0], fieldName, "field %s has a greater than zero minimum value without omitempty. The minimum value should be removed.")
@@ -453,7 +464,7 @@ func (a *analyzer) checkFieldPointersPreferenceWhenRequiredIntegerWithoutOmitEmp
453464
}
454465

455466
//nolint:dupl
456-
func (a *analyzer) checkFieldPointersPreferenceWhenRequiredFloat(pass *analysis.Pass, field *ast.Field, fieldName string, isStarExpr bool, markersAccess markers.Markers, jsonTags extractjsontags.FieldTagInfo) {
467+
func (a *analyzer) checkFieldPointersPreferenceWhenRequiredFloat(pass *analysis.Pass, field *ast.Field, fieldName string, isStarExpr bool, markersAccess markershelper.Markers, jsonTags extractjsontags.FieldTagInfo) {
457468
fieldMarkers := markersAccess.FieldMarkers(field)
458469

459470
minValue, err := getMarkerFloatValueByName(fieldMarkers, minimumMarker)
@@ -513,7 +524,7 @@ func (a *analyzer) checkFieldPointersPreferenceWhenRequiredFloatWithOmitEmpty(pa
513524
// to determine whether or not 0 is a valid value for the float.
514525
// Where 0 is not a valid value, the field should either add omitempty, or remove the limits.
515526
// We assume since there's no omitempty that the API author wants the zero value to be marshalled and as such, suggest to remove the limits.
516-
func (a *analyzer) checkFieldPointersPreferenceWhenRequiredFloatWithoutOmitEmpty(pass *analysis.Pass, field *ast.Field, fieldName string, minValue, maxValue *float64, isStarExpr bool, fieldMarkers markers.MarkerSet) {
527+
func (a *analyzer) checkFieldPointersPreferenceWhenRequiredFloatWithoutOmitEmpty(pass *analysis.Pass, field *ast.Field, fieldName string, minValue, maxValue *float64, isStarExpr bool, fieldMarkers markershelper.MarkerSet) {
517528
switch {
518529
case minValue != nil && *minValue > 0:
519530
reportShouldRemoveMarker(pass, field, fieldMarkers.Get(minimumMarker)[0], fieldName, "field %s has a greater than zero minimum value without omitempty. The minimum value should be removed.")

pkg/analysis/optionalfields/util.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,12 @@ func structContainsRequiredFields(structType *ast.StructType, markersAccess mark
7070

7171
// isFieldRequired checks if a field has a required marker.
7272
func isFieldRequired(fieldMarkers markers.MarkerSet) bool {
73-
return fieldMarkers.Has("required") || fieldMarkers.Has("kubebuilder:validation:Required")
73+
return fieldMarkers.Has(requiredMarker) || fieldMarkers.Has(kubebuilderRequiredMarker)
7474
}
7575

7676
// isFieldOptional checks if a field has an optional marker.
7777
func isFieldOptional(fieldMarkers markers.MarkerSet) bool {
78-
return fieldMarkers.Has("optional") || fieldMarkers.Has("kubebuilder:validation:Optional")
78+
return fieldMarkers.Has(optionalMarker) || fieldMarkers.Has(kubebuilderOptionalMarker)
7979
}
8080

8181
// reportShouldAddPointer adds an analysis diagnostic that explains that a pointer should be added.

pkg/markers/markers.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,27 @@ const (
3636
// KubebuilderFormatMarker is the marker that indicates that a field has a format in kubebuilder.
3737
KubebuilderFormatMarker = "kubebuilder:validation:Format"
3838

39+
// KubebuilderMaximumMarker is the marker that indicates that a field has a maximum value in kubebuilder.
40+
KubebuilderMaximumMarker = "kubebuilder:validation:Maximum"
41+
3942
// KubebuilderMaxItemsMarker is the marker that indicates that a field has a maximum number of items in kubebuilder.
4043
KubebuilderMaxItemsMarker = "kubebuilder:validation:MaxItems"
4144

4245
// KubebuilderMaxLengthMarker is the marker that indicates that a field has a maximum length in kubebuilder.
4346
KubebuilderMaxLengthMarker = "kubebuilder:validation:MaxLength"
4447

48+
// KubebuilderMinimumMarker is the marker that indicates that a field has a minimum value in kubebuilder.
49+
KubebuilderMinimumMarker = "kubebuilder:validation:Minimum"
50+
51+
// KubebuilderMinItemsMarker is the marker that indicates that a field has a minimum number of items in kubebuilder.
52+
KubebuilderMinItemsMarker = "kubebuilder:validation:MinItems"
53+
54+
// KubebuilderMinLengthMarker is the marker that indicates that a field has a minimum length in kubebuilder.
55+
KubebuilderMinLengthMarker = "kubebuilder:validation:MinLength"
56+
57+
// KubebuilderMinPropertiesMarker is the marker that indicates that a field has a minimum number of properties in kubebuilder.
58+
KubebuilderMinPropertiesMarker = "kubebuilder:validation:MinProperties"
59+
4560
// KubebuilderOptionalMarker is the marker that indicates that a field is optional in kubebuilder.
4661
KubebuilderOptionalMarker = "kubebuilder:validation:Optional"
4762

0 commit comments

Comments
 (0)