Skip to content

Commit 4822af7

Browse files
Added/removed extra comments, moved helper functions at the bottom of the file
1 parent 6f6da92 commit 4822af7

File tree

2 files changed

+30
-33
lines changed

2 files changed

+30
-33
lines changed

docs/linters.md

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -244,19 +244,6 @@ This provides better API evolution, self-documentation, and validation compared
244244

245245
By default, `enums` is not enabled.
246246

247-
### Configuration
248-
249-
```yaml
250-
linterConfig:
251-
enums:
252-
allowlist:
253-
- kubectl
254-
- docker
255-
- helm
256-
```
257-
258-
The `allowlist` field contains enum values that should be exempt from PascalCase validation, such as command-line executable names.
259-
260247
## ForbiddenMarkers
261248

262249
The `forbiddenmarkers` linter ensures that types and fields do not contain any markers that are forbidden.

pkg/analysis/enums/analyzer.go

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,7 @@ import (
3232
"sigs.k8s.io/kube-api-linter/pkg/markers"
3333
)
3434

35-
const (
36-
name = "enums"
37-
)
35+
const name = "enums"
3836

3937
type analyzer struct {
4038
config *Config
@@ -76,6 +74,7 @@ func (a *analyzer) checkField(pass *analysis.Pass, field *ast.Field, markersAcce
7674
if fieldName == "" {
7775
return
7876
}
77+
7978
// Get the underlying type, unwrapping pointers and arrays
8079
fieldType, isArray := unwrapTypeWithArrayTracking(field.Type)
8180

@@ -87,23 +86,17 @@ func (a *analyzer) checkField(pass *analysis.Pass, field *ast.Field, markersAcce
8786

8887
prefix := buildFieldPrefix(fieldName, isArray)
8988

89+
// Check if it's a plain string (basic type) vs. a type alias
9090
if ident.Name == "string" && utils.IsBasicType(pass, ident) {
9191
a.checkPlainStringField(pass, field, markersAccess, prefix)
9292

9393
return
9494
}
9595

96+
// Check if it's a type alias that might be an enum
9697
a.checkTypeAliasField(pass, field, ident, markersAccess, prefix)
9798
}
9899

99-
func buildFieldPrefix(fieldName string, isArray bool) string {
100-
if isArray {
101-
return fmt.Sprintf("field %s array element", fieldName)
102-
}
103-
104-
return fmt.Sprintf("field %s", fieldName)
105-
}
106-
107100
func (a *analyzer) checkPlainStringField(pass *analysis.Pass, field *ast.Field, markersAccess markershelper.Markers, prefix string) {
108101
if !hasEnumMarker(markersAccess.FieldMarkers(field)) {
109102
pass.Reportf(field.Pos(),
@@ -216,6 +209,25 @@ func (a *analyzer) getEnumTypeSpec(pass *analysis.Pass, name *ast.Ident) *ast.Ty
216209
return typeSpec
217210
}
218211

212+
func (a *analyzer) isInAllowlist(value string) bool {
213+
if a.config == nil {
214+
return false
215+
}
216+
217+
return slices.Contains(a.config.Allowlist, value)
218+
}
219+
220+
// Helper functions below this line.
221+
222+
// buildFieldPrefix constructs a human-readable prefix for error messages.
223+
func buildFieldPrefix(fieldName string, isArray bool) string {
224+
if isArray {
225+
return fmt.Sprintf("field %s array element", fieldName)
226+
}
227+
228+
return fmt.Sprintf("field %s", fieldName)
229+
}
230+
219231
// unwrapType removes pointer and array wrappers to get the underlying type.
220232
func unwrapType(expr ast.Expr) ast.Expr {
221233
switch t := expr.(type) {
@@ -246,6 +258,7 @@ func unwrapTypeWithArrayTracking(expr ast.Expr) (ast.Expr, bool) {
246258
}
247259
}
248260

261+
// isStringTypeAlias checks if a type spec is a string type alias.
249262
func isStringTypeAlias(pass *analysis.Pass, typeSpec *ast.TypeSpec) bool {
250263
underlyingType := unwrapType(typeSpec.Type)
251264

@@ -258,10 +271,12 @@ func isStringTypeAlias(pass *analysis.Pass, typeSpec *ast.TypeSpec) bool {
258271
return ident.Name == "string" && utils.IsBasicType(pass, ident)
259272
}
260273

274+
// hasEnumMarker checks if a marker set contains enum markers.
261275
func hasEnumMarker(markerSet markershelper.MarkerSet) bool {
262276
return markerSet.Has(markers.KubebuilderEnumMarker) || markerSet.Has(markers.K8sEnumMarker)
263277
}
264278

279+
// hasEnumMarkerOnTypeSpec checks if a type spec has enum markers in its documentation.
265280
func hasEnumMarkerOnTypeSpec(pass *analysis.Pass, typeSpec *ast.TypeSpec) bool {
266281
for _, file := range pass.Files {
267282
if genDecl := findGenDeclForSpec(file, typeSpec); genDecl != nil {
@@ -272,6 +287,7 @@ func hasEnumMarkerOnTypeSpec(pass *analysis.Pass, typeSpec *ast.TypeSpec) bool {
272287
return false
273288
}
274289

290+
// findGenDeclForSpec finds the GenDecl that contains a given TypeSpec.
275291
func findGenDeclForSpec(file *ast.File, typeSpec *ast.TypeSpec) *ast.GenDecl {
276292
for _, decl := range file.Decls {
277293
genDecl, ok := decl.(*ast.GenDecl)
@@ -289,6 +305,7 @@ func findGenDeclForSpec(file *ast.File, typeSpec *ast.TypeSpec) *ast.GenDecl {
289305
return nil
290306
}
291307

308+
// hasEnumMarkerInDoc checks if a comment group contains enum markers.
292309
func hasEnumMarkerInDoc(doc *ast.CommentGroup) bool {
293310
if doc == nil {
294311
return false
@@ -304,15 +321,7 @@ func hasEnumMarkerInDoc(doc *ast.CommentGroup) bool {
304321
return false
305322
}
306323

307-
// isInAllowlist checks if a value is in the configured allowlist.
308-
func (a *analyzer) isInAllowlist(value string) bool {
309-
if a.config == nil {
310-
return false
311-
}
312-
313-
return slices.Contains(a.config.Allowlist, value)
314-
}
315-
324+
// findTypeSpecByName finds a type spec by its name in the pass's files.
316325
func findTypeSpecByName(pass *analysis.Pass, typeName string) *ast.TypeSpec {
317326
for _, file := range pass.Files {
318327
for _, decl := range file.Decls {
@@ -337,6 +346,7 @@ func findTypeSpecByName(pass *analysis.Pass, typeName string) *ast.TypeSpec {
337346
return nil
338347
}
339348

349+
// isPascalCase checks if a string follows PascalCase naming convention.
340350
func isPascalCase(s string) bool {
341351
if len(s) == 0 {
342352
return false

0 commit comments

Comments
 (0)