Skip to content

Commit 7c6d5fa

Browse files
authored
Merge pull request #104 from yongruilin/doc-linters
docs: move linters to a dedicated file
2 parents bce00ef + e851a51 commit 7c6d5fa

File tree

3 files changed

+324
-301
lines changed

3 files changed

+324
-301
lines changed

README.md

Lines changed: 4 additions & 291 deletions
Original file line numberDiff line numberDiff line change
@@ -154,303 +154,16 @@ allowing for customisation or automatic copmilation of the project should it not
154154
}
155155
```
156156

157-
# Linters
158-
159-
## Conditions
160-
161-
The `conditions` linter checks that `Conditions` fields in the API types are correctly formatted.
162-
The `Conditions` field should be a slice of `metav1.Condition` with the following tags and markers:
163-
164-
```go
165-
// +listType=map
166-
// +listMapKey=type
167-
// +patchStrategy=merge
168-
// +patchMergeKey=type
169-
// +optional
170-
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,opt,name=conditions"`
171-
```
172-
173-
Conditions are idiomatically the first field within the status struct, and the linter will highlight when the Conditions are not the first field.
174-
175-
Protobuf tags and patch strategy are required for in-tree API types, but not for CRDs.
176-
When linting CRD based types, set the `useProtobuf` and `usePatchStrategy` config option to `Ignore` or `Forbid`.
177-
178-
### Configuration
179-
180-
```yaml
181-
lintersConfig:
182-
conditions:
183-
isFirstField: Warn | Ignore # The policy for the Conditions field being the first field. Defaults to `Warn`.
184-
useProtobuf: SuggestFix | Warn | Ignore | Forbid # The policy for the protobuf tag on the Conditions field. Defaults to `SuggestFix`.
185-
usePatchStrategy: SuggestFix | Warn | Ignore | Forbid # The policy for the patchStrategy tag on the Conditions field. Defaults to `SuggestFix`.
186-
```
187-
188-
### Fixes
189-
190-
The `conditions` linter can automatically fix the tags on the `Conditions` field.
191-
When they do not match the expected format, the linter will suggest to update the tags to match the expected format.
192-
193-
For CRDs, protobuf tags and patch strategy are not expected.
194-
By setting the `useProtobuf`/`usePatchStrategy` configuration to `Ignore`, the linter will not suggest to add the protobuf/patch strategy tag to the `Conditions` field tags.
195-
By setting the `useProtobuf`/`usePatchStrategy` configuration to `Forbid`, the linter will suggest to remove the protobuf/patch strategy tag from the `Conditions` field tags.
196-
197-
The linter will also suggest to add missing markers.
198-
If any of the 5 markers in the example above are missing, the linter will suggest to add them directly above the field.
199-
200-
When `usePatchStrategy` is set to `Ignore`, the linter will not suggest to add the `patchStrategy` and `patchMergeKey` tags to the `Conditions` field markers.
201-
When `usePatchStrategy` is set to `Forbid`, the linter will suggest to remove the `patchStrategy` and `patchMergeKey` tags from the `Conditions` field markers.
202-
203-
## CommentStart
204-
205-
The `commentstart` linter checks that all comments in the API types start with the serialized form of the type they are commenting on.
206-
This helps to ensure that generated documentation reflects the most common usage of the field, the serialized YAML form.
207-
208-
### Fixes
209-
210-
The `commentstart` linter can automatically fix comments that do not start with the serialized form of the type.
211-
212-
When the `json` tag is present, and matches the first word of the field comment in all but casing, the linter will suggest that the comment be updated to match the `json` tag.
213-
214-
## DuplicateMarkers
215-
216-
The duplicatemarkers linter checks for exact duplicates of markers for types and fields.
217-
This means that something like:
218-
219-
```go
220-
// +kubebuilder:validation:MaxLength=10
221-
// +kubebuilder:validation:MaxLength=10
222-
```
223-
224-
Will be flagged by this linter, while something like:
225-
226-
```go
227-
// +kubebuilder:validation:MaxLength=10
228-
// +kubebuilder:validation:MaxLength=11
229-
```
230-
231-
will not.
232-
233-
### Fixes
234-
235-
The `duplicatemarkers` linter can automatically fix all markers that are exact match to another markers.
236-
If there are duplicates across fields and their underlying type, the marker on the type will be preferred and the marker on the field will be removed.
237-
238-
## Integers
239-
240-
The `integers` linter checks for usage of unsupported integer types.
241-
Only `int32` and `int64` types should be used in APIs, and other integer types, including unsigned integers are forbidden.
242-
243-
## JSONTags
244-
245-
The `jsontags` linter checks that all fields in the API types have a `json` tag, and that those tags are correctly formatted.
246-
The `json` tag for a field within a Kubernetes API type should use a camel case version of the field name.
247-
248-
The `jsontags` linter checks the tag name against the regex `"^[a-z][a-z0-9]*(?:[A-Z][a-z0-9]*)*$"` which allows consecutive upper case characters, to allow for acronyms, e.g. `requestTTL`.
249-
250-
### Configuration
251-
252-
```yaml
253-
lintersConfig:
254-
jsonTags:
255-
jsonTagRegex: "^[a-z][a-z0-9]*(?:[A-Z][a-z0-9]*)*$" # Provide a custom regex, which the json tag must match.
256-
```
257-
258-
## MaxLength
259-
260-
The `maxlength` linter checks that string and array fields in the API are bounded by a maximum length.
261-
262-
For strings, this means they have a `+kubebuilder:validation:MaxLength` marker.
263-
264-
For arrays, this means they have a `+kubebuilder:validation:MaxItems` marker.
265-
266-
For arrays of strings, the array element should also have a `+kubebuilder:validation:MaxLength` marker if the array element is a type alias,
267-
or `+kubebuilder:validation:items:MaxLenth` if the array is an element of the built-in string type.
268-
269-
Adding maximum lengths to strings and arrays not only ensures that the API is not abused (used to store overly large data, reduces DDOS etc.),
270-
but also allows CEL validation cost estimations to be kept within reasonable bounds.
271-
272-
## NoBools
273-
274-
The `nobools` linter checks that fields in the API types do not contain a `bool` type.
275-
276-
Booleans are limited and do not evolve well over time.
277-
It is recommended instead to create a string alias with meaningful values, as an enum.
278-
279-
## NoFloats
280-
281-
The `nofloats` linter checks that fields in the API types do not contain a `float32` or `float64` type.
282-
283-
Floating-point values cannot be reliably round-tripped without changing and have varying precision and representation across languages and architectures.
284-
Their use should be avoided as much as possible.
285-
They should never be used in spec.
286-
287-
## Nomaps
288-
289-
The `nomaps` linter checks the usage of map types.
290-
291-
Maps are discouraged apart from `map[string]string` which is used for labels and annotations in Kubernetes APIs since it's hard to distinguish between structs and maps in spec. Instead of plain map, lists of named subobjects are preferred.
292-
293-
### Configuration
294-
295-
```yaml
296-
lintersConfig:
297-
nomaps:
298-
policy: Enforce | AllowStringToStringMaps | Ignore # Determines how the linter should handle maps of simple types. Defaults to AllowStringToStringMaps.
299-
```
300-
301-
## Nophase
302-
303-
The `nophase` linter checks that the fields in the API types don't contain a 'Phase', or any field which contains 'Phase' as a substring, e.g MachinePhase.
304-
305-
## OptionalFields
306-
307-
The `optionalfields` linter checks that all fields marked as optional adhere to being pointers and having the `omitempty` value in their `json` tag where appropriate.
308-
309-
If you prefer to avoid pointers where possible, the linter can be configured with the `WhenRequired` preference to determine, based on the serialization and valid values for the field, whether the field should be a pointer or not.
310-
For example, an optional string with a non-zero minimum length does not need to be a pointer, as the zero value is not valid, and it is safe for the Go marshaller to omit the empty value.
311-
312-
In certain use cases, it can be desirable to not omit optional fields from the serialized form of the object.
313-
In this case, the `omitempty` policy can be set to `Ignore`, and the linter will ensure that the zero value of the object is an acceptable value for the field.
314-
315-
### Configuration
316-
317-
```yaml
318-
lintersConfig:
319-
optionalFields:
320-
pointers:
321-
preference: Always | WhenRequired # Whether to always require pointers, or only when required. Defaults to `Always`.
322-
policy: SuggestFix | Warn # The policy for pointers in optional fields. Defaults to `SuggestFix`.
323-
omitempty:
324-
policy: SuggestFix | Warn | Ignore # The policy for omitempty in optional fields. Defaults to `SuggestFix`.
325-
```
326-
327-
### Fixes
328-
329-
The `optionalfields` linter can automatically fix fields that are marked as optional, that are either not pointers or do not have the `omitempty` value in their `json` tag.
330-
It will suggest to add the pointer to the field, and update the `json` tag to include the `omitempty` value.
331-
332-
If you prefer not to suggest fixes for pointers in optional fields, you can change the `pointers.policy` to `Warn`.
333-
334-
If you prefer not to suggest fixes for `omitempty` in optional fields, you can change the `omitempty.policy` to `Warn` or `Ignore`.
335-
336-
When the `pointers.preference` is set to `WhenRequired`, the linter will suggest to add the pointer to the field only when the field zero value is a valid value for the field.
337-
When the field zero value is not a valid value for the field, the linter will suggest to remove the pointer from the field.
338-
339-
When the `pointers.preference` is set to `Always`, the linter will always suggest to add the pointer to the field, regardless of the validity of the zero value of the field.
340-
341-
## OptionalOrRequired
342-
343-
The `optionalorrequired` linter checks that all fields in the API types are either optional or required, and are marked explicitly as such.
344-
345-
The linter expects to find a comment marker `// +optional` or `// +required` within the comment for the field.
346-
347-
It also supports the `// +kubebuilder:validation:Optional` and `// +kubebuilder:validation:Required` markers, but will suggest to use the `// +optional` and `// +required` markers instead.
348-
349-
If you prefer to use the Kubebuilder markers instead, you can change the preference in the configuration.
350-
351-
The `optionalorrequired` linter also checks for the presence of optional or required markers on type declarations, and forbids this pattern.
352-
353-
### Configuration
354-
355-
```yaml
356-
lintersConfig:
357-
optionalOrRequired:
358-
preferredOptionalMarker: optional | kubebuilder:validation:Optional # The preferred optional marker to use, fixes will suggest to use this marker. Defaults to `optional`.
359-
preferredRequiredMarker: required | kubebuilder:validation:Required # The preferred required marker to use, fixes will suggest to use this marker. Defaults to `required`.
360-
```
361-
362-
### Fixes
363-
364-
The `optionalorrequired` linter can automatically fix fields that are using the incorrect form of either the optional or required marker.
365-
366-
It will also remove the secondary marker where both the preferred and secondary marker are present on a field.
367-
368-
## RequiredFields
369-
370-
The `requiredfields` linter checks that fields that are marked as required, follow the convention of not being pointers,
371-
and not having an `omitempty` value in their `json` tag.
372-
373-
### Configuration
374-
375-
```yaml
376-
lintersConfig:
377-
requiredFields:
378-
pointerPolicy: Warn | SuggestFix # The policy for pointers in required fields. Defaults to `SuggestFix`.
379-
```
380-
381-
### Fixes
382-
383-
The `requiredfields` linter can automatically fix fields that are marked as required, but are pointers.
384-
385-
It will suggest to remove the pointer from the field, and update the `json` tag to remove the `omitempty` value.
386-
387-
If you prefer not to suggest fixes for pointers in required fields, you can change the `pointerPolicy` to `Warn`.
388-
The linter will then only suggest to remove the `omitempty` value from the `json` tag.
389-
390-
## StatusOptional
391-
392-
The `statusoptional` linter checks that all first-level children fields within a status struct are marked as optional.
393-
394-
This is important because status fields should be optional to allow for partial updates and backward compatibility.
395-
The linter ensures that all direct child fields of any status struct have either the `// +optional` or
396-
`// +kubebuilder:validation:Optional` marker.
397-
398-
### Fixes
399-
400-
The `statusoptional` linter can automatically fix fields in status structs that are not marked as optional.
401-
402-
It will suggest adding the `// +optional` marker to any status field that is missing it.
403-
404-
## StatusSubresource
405-
406-
The `statussubresource` linter checks that the status subresource is configured correctly for
407-
structs marked with the `kubebuilder:object:root:=true` marker. Correct configuration is that
408-
when there is a status field the `kubebuilder:subresource:status` marker is present on the struct
409-
OR when the `kubebuilder:subresource:status` marker is present on the struct there is a status field.
410-
411-
This linter is not enabled by default as it is only applicable to CustomResourceDefinitions.
412-
413-
### Fixes
414-
415-
In the case where there is a status field present but no `kubebuilder:subresource:status` marker, the
416-
linter will suggest adding the comment `// +kubebuilder:subresource:status` above the struct.
417-
418-
## UniqueMarkers
419-
420-
The `uniquemarkers` linter ensures that types and fields do not contain more than a single definition of a marker that should only be present once.
421-
422-
Because this linter has no way of determining which marker definition was intended it does not suggest any fixes
423-
424-
### Configuration
425-
It can configured to include a set of custom markers in the analysis by setting:
426-
```yaml
427-
lintersConfig:
428-
uniqueMarkers:
429-
customMarkers:
430-
- identifier: custom:SomeCustomMarker
431-
attributes:
432-
- fruit
433-
```
434-
435-
For each custom marker, it must specify an `identifier` and optionally some `attributes`.
436-
As an example, take the marker definition `kubebuilder:validation:XValidation:rule='has(self.foo)',message='should have foo',fieldPath='.foo'`.
437-
The identifier for the marker is `kubebuilder:validation:XValidation` and its attributes are `rule`, `message`, and `fieldPath`.
438-
439-
When specifying `attributes`, those attributes are included in the uniqueness identification of a marker definition.
440-
441-
Taking the example configuration from above:
442-
443-
- Marker definitions of `custom:SomeCustomMarker:fruit=apple,color=red` and `custom:SomeCustomMarker:fruit=apple,color=green` would violate the uniqueness requirement and be flagged.
444-
- Marker definitions of `custom:SomeCustomMarker:fruit=apple,color=red` and `custom:SomeCustomMarker:fruit=orange,color=red` would _not_ violate the uniqueness requirement.
445-
446-
Each entry in `customMarkers` must have a unique `identifier`.
447-
448157
# Contributing
449158

450159
New linters can be added by following the [New Linter][new-linter] guide.
451160

452161
[new-linter]: docs/new-linter.md
453162

163+
# Linters
164+
165+
For a complete list of available linters and their configuration options, see [docs/linters.md](docs/linters.md).
166+
454167
# License
455168

456169
KAL is licensed under the Apache License, Version 2.0. See [LICENSE](LICENSE) for the full license text.

0 commit comments

Comments
 (0)