Skip to content

Commit ba76ed1

Browse files
Merge branch 'main' into numericbounds
2 parents 5d9441a + d3015c9 commit ba76ed1

File tree

35 files changed

+1606
-303
lines changed

35 files changed

+1606
-303
lines changed

docs/linters.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
- [NoDurations](#nodurations) - Prevents usage of duration types
1818
- [NoFloats](#nofloats) - Prevents usage of floating-point types
1919
- [Nomaps](#nomaps) - Restricts usage of map types
20+
- [NonPointerStructs](#nonpointerstructs) - Ensures non-pointer structs are marked correctly with required/optional markers
2021
- [NoNullable](#nonullable) - Prevents usage of the nullable marker
2122
- [Nophase](#nophase) - Prevents usage of 'Phase' fields
2223
- [Notimestamp](#notimestamp) - Prevents usage of 'TimeStamp' fields
@@ -533,6 +534,39 @@ lintersConfig:
533534
policy: Enforce | AllowStringToStringMaps | Ignore # Determines how the linter should handle maps of simple types. Defaults to AllowStringToStringMaps.
534535
```
535536

537+
## NonPointerStructs
538+
539+
The `nonpointerstructs` linter checks that non-pointer structs that contain required fields are marked as required.
540+
Non-pointer structs that contain no required fields are marked as optional.
541+
542+
This linter is important for types validated in Go as there is no way to validate the optionality of the fields at runtime,
543+
aside from checking the fields within them.
544+
545+
This linter is NOT intended to be used to check for CRD types.
546+
The advice of this linter may be applied to CRD types, but it is not necessary for CRD types due to optionality being validated by openapi and no native Go code.
547+
For CRD types, the optionalfields and requiredfields linters should be used instead.
548+
549+
If a struct is marked required, this can only be validated by having a required field within it.
550+
If there are no required fields, the struct is implicitly optional and must be marked as so.
551+
552+
To have an optional struct field that includes required fields, the struct must be a pointer.
553+
To have a required struct field that includes no required fields, the struct must be a pointer.
554+
555+
### Configuration
556+
557+
```yaml
558+
lintersConfig:
559+
nonpointerstructs:
560+
preferredRequiredMarker: required | kubebuilder:validation:Required | k8s:required # The preferred required marker to use for required fields when providing fixes. Defaults to `required`.
561+
preferredOptionalMarker: optional | kubebuilder:validation:Optional | k8s:optional # The preferred optional marker to use for optional fields when providing fixes. Defaults to `optional`.
562+
```
563+
564+
### Fixes
565+
566+
The `nonpointerstructs` linter can automatically fix non-pointer struct fields that are not marked as required or optional.
567+
568+
It will suggest to mark the field as required or optional, depending on the fields within the non-pointer struct.
569+
536570
## NoNullable
537571

538572
The `nonullable` linter ensures that types and fields do not have the `nullable` marker.

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,16 @@ type IncorrectFieldTag struct {
104104
// +optional
105105
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
}
107+
108+
// ConditionsWithOrphanedMarkers tests the fix for orphaned markers where markers
109+
// separated from the field doc comment by a blank line were not being detected.
110+
type ConditionsWithOrphanedMarkers struct {
111+
// +optional
112+
// +listType=map
113+
// +listMapKey=type
114+
// +patchStrategy=merge
115+
// +patchMergeKey=type
116+
117+
// Conditions update as changes occur in the status.
118+
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`
119+
}

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,16 @@ type IncorrectFieldTag struct {
114114
// +optional
115115
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
}
117+
118+
// ConditionsWithOrphanedMarkers tests the fix for orphaned markers where markers
119+
// separated from the field doc comment by a blank line were not being detected.
120+
type ConditionsWithOrphanedMarkers struct {
121+
// +optional
122+
// +listType=map
123+
// +listMapKey=type
124+
// +patchStrategy=merge
125+
// +patchMergeKey=type
126+
127+
// Conditions update as changes occur in the status.
128+
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`
129+
}

0 commit comments

Comments
 (0)