Skip to content

Commit 6aaaa0d

Browse files
committed
docs(markerscope): document strictTypeConstraint and scope exclusions
Signed-off-by: nayuta-ai <nayuta723@gmail.com>
1 parent 96c80ca commit 6aaaa0d

File tree

2 files changed

+46
-4
lines changed

2 files changed

+46
-4
lines changed

docs/linters.md

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,35 @@ OpenAPI schema types map to Go types as follows:
325325
- `array`: []T, [N]T (slices and arrays)
326326
- `object`: struct, map[K]V
327327

328+
#### Strict Type Constraints
329+
330+
For markers with `AnyScope` and type constraints, the `strictTypeConstraint` flag controls where the marker should be declared when used with named types:
331+
332+
- When `strictTypeConstraint` is `false` (default): The marker can be declared on either the field or the type definition.
333+
- When `strictTypeConstraint` is `true`: The marker must be declared on the type definition, not on fields using that type.
334+
335+
Example with `strictTypeConstraint: true`:
336+
337+
```go
338+
// ✅ Valid: marker on type definition
339+
// +kubebuilder:validation:Minimum=0
340+
type Port int32
341+
342+
type Service struct {
343+
Port Port `json:"port"`
344+
}
345+
346+
// ❌ Invalid: marker on field using named type
347+
type Port int32
348+
349+
type Service struct {
350+
// +kubebuilder:validation:Minimum=0 // Error: should be on Port type definition
351+
Port Port `json:"port"`
352+
}
353+
```
354+
355+
Most built-in kubebuilder validation markers use `strictTypeConstraint: true` to encourage consistent marker placement on type definitions.
356+
328357
### Default Marker Rules
329358

330359
The linter includes built-in rules for all standard kubebuilder markers and k8s declarative validation markers. Examples:
@@ -356,6 +385,7 @@ You can customize marker rules or add support for custom markers:
356385
lintersConfig:
357386
markerscope:
358387
policy: Warn | SuggestFix # The policy for marker scope violations. Defaults to `Warn`.
388+
allowDangerousTypes: false # Allow dangerous number types (float32, float64). Defaults to `false`.
359389
markerRules:
360390
# Override default rule for a built-in marker
361391
"optional":
@@ -368,6 +398,7 @@ lintersConfig:
368398
# Add a custom marker with scope and type constraints
369399
"mycompany:validation:NumericLimit":
370400
scope: any
401+
strictTypeConstraint: true # Require declaration on type definition for named types
371402
typeConstraint:
372403
allowedSchemaTypes:
373404
- integer
@@ -392,13 +423,22 @@ lintersConfig:
392423
**Type constraint fields:**
393424
- `allowedSchemaTypes`: List of allowed OpenAPI schema types (`integer`, `number`, `string`, `boolean`, `array`, `object`)
394425
- `elementConstraint`: Nested constraint for array element types (only valid when `allowedSchemaTypes` includes `array`)
426+
- `strictTypeConstraint`: When `true`, markers with `AnyScope` and type constraints applied to fields using named types must be declared on the type definition instead of the field. Defaults to `false`.
395427

396428
If a marker is not in `markerRules` and not in the default rules, no validation is performed for that marker.
397429
If a marker is in both `markerRules` and the default rules, your configuration takes precedence.
398430

399431
### Fixes
400432

401-
The `markerscope` linter does not currently provide automatic fixes. It reports violations as warnings or errors based on the configured policy.
433+
When the `policy` is set to `SuggestFix`, the `markerscope` linter provides automatic fix suggestions for marker violations:
434+
435+
1. **Scope violations**: For markers applied to the wrong scope (field vs type), the linter suggests moving the marker to the correct location.
436+
437+
2. **Type constraint violations**: For markers applied to incompatible types, the linter suggests removing the invalid marker.
438+
439+
3. **Named type violations**: For AnyScope markers with type constraints applied to fields using named types, the linter suggests moving the marker to the type definition if the underlying type is compatible with the marker's type constraints.
440+
441+
When the `policy` is set to `Warn`, violations are reported as warnings without suggesting fixes.
402442

403443
**Note**: This linter is not enabled by default and must be explicitly enabled in the configuration.
404444

pkg/analysis/markerscope/config.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,11 @@ type MarkerScopeConfig struct {
128128
// Users can override these rules or add custom markers by providing a MarkerScopeConfig
129129
// with MarkerRules that will be merged with (and take precedence over) these defaults.
130130
//
131+
// Note: This function currently covers validation and SSA markers with type and struct constraints.
132+
// Markers from crd.go (e.g., resource, subresource) and pkg.go (e.g., groupName, versionName)
133+
// are not included as they don't have type or struct constraints and are out of scope for
134+
// this linter's current validation capabilities.
135+
//
131136
// ref: https://github.com/kubernetes-sigs/controller-tools/blob/v0.19.0/pkg/crd/markers/
132137
func DefaultMarkerRules() map[string]MarkerScopeRule {
133138
rules := make(map[string]MarkerScopeRule)
@@ -143,9 +148,6 @@ func DefaultMarkerRules() map[string]MarkerScopeRule {
143148
addSSATopologyMarkers(rules)
144149
addArrayItemsMarkers(rules)
145150

146-
// TODO crd.go
147-
// TODO package.go
148-
149151
return rules
150152
}
151153

0 commit comments

Comments
 (0)