@@ -18,8 +18,11 @@ package arrayofstruct
1818import (
1919 "fmt"
2020 "go/ast"
21+ "regexp"
22+ "slices"
2123
2224 "golang.org/x/tools/go/analysis"
25+
2326 kalerrors "sigs.k8s.io/kube-api-linter/pkg/analysis/errors"
2427 "sigs.k8s.io/kube-api-linter/pkg/analysis/helpers/extractjsontags"
2528 "sigs.k8s.io/kube-api-linter/pkg/analysis/helpers/inspector"
@@ -74,6 +77,13 @@ func checkField(pass *analysis.Pass, field *ast.Field, markersAccess markershelp
7477 return
7578 }
7679
80+ // Check if the struct has union markers that satisfy the required constraint
81+ if hasExactlyOneOfMarker (structType ) {
82+ // ExactlyOneOf marker enforces that exactly one field is set,
83+ // so we don't need to report an error
84+ return
85+ }
86+
7787 // Check if at least one field in the struct has a required marker
7888 if hasRequiredField (structType , markersAccess ) {
7989 return
@@ -208,3 +218,35 @@ func hasRequiredField(structType *ast.StructType, markersAccess markershelper.Ma
208218
209219 return false
210220}
221+
222+ // hasExactlyOneOfMarker checks if the struct has an ExactlyOneOf marker,
223+ // which satisfies the required field constraint by ensuring exactly one field is set.
224+ func hasExactlyOneOfMarker (structType * ast.StructType ) bool {
225+ if structType .Fields == nil {
226+ return false
227+ }
228+
229+ for _ , field := range structType .Fields .List {
230+ var markers []string
231+
232+ if field .Doc != nil {
233+ for _ , comment := range field .Doc .List {
234+ markers = append (markers , comment .Text )
235+ }
236+ }
237+ // Check for ExactlyOneOf marker
238+ if hasMarkerPattern (markers , "ExactlyOneOf" ) {
239+ return true
240+ }
241+ }
242+
243+ return false
244+ }
245+
246+ // hasMarkerPattern checks if any of the markers match the given pattern.
247+ func hasMarkerPattern (markers []string , markerName string ) bool {
248+ pattern := fmt .Sprintf (`\+kubebuilder:validation:%s=` , markerName )
249+ re := regexp .MustCompile (pattern )
250+
251+ return slices .ContainsFunc (markers , re .MatchString )
252+ }
0 commit comments