-
Notifications
You must be signed in to change notification settings - Fork 21
Add markerscope linter #161
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: nayuta723 The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some of this code appears to be a little over complex for what we were expecting here. Lets try and get this cleaned up and simplified a bit.
Lets focus initially on what the public configuration should look like, and then look at the implementation I think
Out of interest, were any code assistants used to help prepare this PR? (I'm currently comparing different models so good to have context on what models are being used where)
| // SchemaType represents OpenAPI schema types that markers can target. | ||
| type SchemaType string | ||
|
|
||
| const ( | ||
| // SchemaTypeInteger represents integer types (int, int32, int64, uint, etc.) | ||
| SchemaTypeInteger SchemaType = "integer" | ||
| // SchemaTypeNumber represents floating-point types (float32, float64). | ||
| SchemaTypeNumber SchemaType = "number" | ||
| // SchemaTypeString represents string types. | ||
| SchemaTypeString SchemaType = "string" | ||
| // SchemaTypeBoolean represents boolean types. | ||
| SchemaTypeBoolean SchemaType = "boolean" | ||
| // SchemaTypeArray represents array/slice types. | ||
| SchemaTypeArray SchemaType = "array" | ||
| // SchemaTypeObject represents struct/map types. | ||
| SchemaTypeObject SchemaType = "object" | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this all need to be exported? Is this part of configuration?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is configured this way because it's necessary for the Configuration settings.
| "golang.org/x/tools/go/analysis/analysistest" | ||
| ) | ||
|
|
||
| func TestAnalyzerWarnOnly(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We normally have a test for the default configuration, what is the default? Is defaulting of the config implemented?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The following is the default configuration. I will add a defaultConfig function.
- Policy: Warn
- OverrideMarkers: empty (use built-in defaults)
- CustomMarkers: empty
pkg/analysis/markerscope/analyzer.go
Outdated
| // Check if dangerous types are disallowed | ||
| if !allowDangerousTypes && schemaType == SchemaTypeNumber { | ||
| // Get the underlying type for better error messages | ||
| underlyingType := getUnderlyingType(t) | ||
| return &DengerousTypeError{Type: underlyingType.String()} | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand what this is trying to achieve, can you explain this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When DangerousTypes is enabled, it allows floats configuration. However, since there is a nofloat linter, this is no longer necessary and should be removed.
https://github.com/kubernetes-sigs/kube-api-linter/pull/161/files#r2470349926
The original intention was to produce errors for patterns where SchemaTypeNumber (which includes float32, float64) is used when Float is not allowed (DangerousTypes disabled).
| lintersConfig: | ||
| markerscope: | ||
| policy: Warn | SuggestFix # The policy for marker scope violations. Defaults to `Warn`. | ||
| allowDangerousTypes: false # Allow dangerous number types (float32, float64). Defaults to `false`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this linter should care about that, we have a nofloats linter already
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Understood. I'm going to turn this setting off.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We handled it here.
875b36c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add override test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have taken care of the matter below.
6270f45
| if rule.Scope == FieldScope { | ||
| message = fmt.Sprintf("marker %q can only be applied to fields", marker.Identifier) | ||
|
|
||
| if a.policy == MarkerScopePolicySuggestFix { | ||
| fixes = a.suggestMoveToField(pass, typeSpec, marker, rule) | ||
| } | ||
| } else { | ||
| message = fmt.Sprintf("marker %q cannot be applied to types", marker.Identifier) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if rule.Scope == FieldScope { | |
| message = fmt.Sprintf("marker %q can only be applied to fields", marker.Identifier) | |
| if a.policy == MarkerScopePolicySuggestFix { | |
| fixes = a.suggestMoveToField(pass, typeSpec, marker, rule) | |
| } | |
| } else { | |
| message = fmt.Sprintf("marker %q cannot be applied to types", marker.Identifier) | |
| } | |
| message := fmt.Sprintf("marker %q cannot be applied to types", marker.Identifier) | |
| if rule.Scope == FieldScope { | |
| message = fmt.Sprintf("marker %q can only be applied to fields", marker.Identifier) | |
| if a.policy == MarkerScopePolicySuggestFix { | |
| fixes = a.suggestMoveToField(pass, typeSpec, marker, rule) | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have taken care of the matter below.
9c0a9b6
Signed-off-by: nayuta-ai <nayuta723@gmail.com>
Signed-off-by: nayuta-ai <nayuta723@gmail.com>
Signed-off-by: nayuta-ai <nayuta723@gmail.com>
Signed-off-by: nayuta-ai <nayuta723@gmail.com>
Signed-off-by: nayuta-ai <nayuta723@gmail.com>
…ag and updating type constraints. Refactor schema type definitions and improve error handling for invalid markers. Add new test cases for various marker scenarios. Signed-off-by: nayuta-ai <nayuta723@gmail.com>
…tom error types for invalid schema types, type constraints, and element constraints. Update validation functions to return these new error types for improved clarity and maintainability. Signed-off-by: nayuta-ai <nayuta723@gmail.com>
Signed-off-by: nayuta-ai <nayuta723@gmail.com>
Signed-off-by: nayuta-ai <nayuta723@gmail.com>
…object lists Signed-off-by: nayuta-ai <nayuta723@gmail.com>
…h validation Signed-off-by: nayuta-ai <nayuta723@gmail.com>
Signed-off-by: nayuta-ai <nayuta723@gmail.com>
Signed-off-by: nayuta-ai <nayuta723@gmail.com>
…straint and improve code quality Signed-off-by: nayuta-ai <nayuta723@gmail.com>
… constants Signed-off-by: nayuta-ai <nayuta723@gmail.com>
Signed-off-by: nayuta-ai <nayuta723@gmail.com>
6aaaa0d to
9c0a9b6
Compare
|
@JoelSpeed @sivchari
I'm currently using Claude Sonnet 4.5 to write docstrings and handle minor implementation details. |
…tive Signed-off-by: nayuta-ai <nayuta723@gmail.com>
Fixes #148
Implements a new
markerscopelinter that validates markers are applied in the correct scope (field vs type) and to compatible data types, ensuring proper usage of kubebuilder/controller-runtime annotations throughout Kubernetes API definitions.Key Features:
Scope Validation: Ensures markers are placed on the correct Go language construct
FieldScope: Can only be applied to struct fields (e.g.,optional,required,nullable)TypeScope: Can only be applied to type definitions (e.g.,kubebuilder:validation:items:ExactlyOneOf)AnyScope: Can be applied to either fields or type definitions (e.g.,Minimum,Pattern)kubebuilder:resource,kubebuilder:subresource) and package-level markers (e.g.,groupName) are out of scope for this PRType Constraint Validation: Ensures markers are applied to compatible OpenAPI schema types
Minimum,Maximum,MultipleOf) only forinteger/numbertypesPattern,MinLength,MaxLength) only forstringtypesMinItems,MaxItems,UniqueItems) only forarraytypesMinProperties,MaxProperties) only forobjecttypes (struct/map)items:Minimum,items:Pattern, etc.) apply constraints to array element typesStrict Type Constraint Mode:
strictTypeConstraintflag enforces that markers withAnyScopeand type constraints must be declared on type definitions rather than fields when using named types, promoting consistent marker placementAutomatic Fix Suggestions: When
policy: SuggestFixis configured, provides automatic fix suggestions for violations:Configurable Rules: Supports overriding default rules and adding custom marker validation
Comprehensive Default Rules: Includes 100+ built-in rules for: