From 95093571e9dafeca426bef3ccff278f901118a2c Mon Sep 17 00:00:00 2001 From: Harald Nordgren Date: Thu, 30 Oct 2025 16:54:14 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=8C=B1=20use=20modernize=20linter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/golangci-lint.yml | 2 +- .golangci.yml | 1 + .../applyconfiguration_integration_test.go | 3 ++ .../api/v1/applyconfiguration/utils.go | 2 +- .../testdata/cronjob/api/v1/cronjob_types.go | 11 +++---- pkg/crd/flatten.go | 2 +- pkg/crd/gen.go | 12 +++---- pkg/crd/known_types.go | 10 +++--- pkg/crd/markers/register.go | 2 +- pkg/crd/markers/validation.go | 10 +++--- pkg/crd/schema_test.go | 4 +-- pkg/crd/testdata/cronjob_types.go | 6 ++-- .../wrong_annotation_format/cronjob_types.go | 6 ++-- pkg/deepcopy/traverse.go | 9 ++---- pkg/genall/genall.go | 16 +++++----- pkg/genall/help/pretty/print.go | 2 +- pkg/genall/options.go | 7 ++-- pkg/loader/testutils/helpers.go | 16 +++++----- pkg/markers/collect.go | 6 ++-- pkg/markers/markers_suite_test.go | 2 +- pkg/markers/parse.go | 32 +++++++++---------- pkg/markers/parse_test.go | 16 +++++----- pkg/markers/reg.go | 2 +- pkg/rbac/parser.go | 12 +++---- pkg/rbac/parser_integration_test.go | 2 +- pkg/schemapatcher/internal/yaml/convert.go | 2 +- .../internal/yaml/delete_test.go | 20 ++++++------ .../internal/yaml/nested_test.go | 20 ++++++------ pkg/schemapatcher/internal/yaml/set_test.go | 30 ++++++++--------- pkg/webhook/parser.go | 2 +- pkg/webhook/parser_integration_test.go | 4 +-- 31 files changed, 133 insertions(+), 138 deletions(-) diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index 841ea43c7..311b695ea 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -33,6 +33,6 @@ jobs: - name: golangci-lint uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # tag=v8.0.0 with: - version: v2.5.0 + version: v2.6.0 args: --output.text.print-linter-name=true --output.text.colors=true --timeout 10m working-directory: ${{matrix.working-directory}} diff --git a/.golangci.yml b/.golangci.yml index db6d2f49e..3ade6ef19 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -32,6 +32,7 @@ linters: - iotamixing - makezero - misspell + - modernize - nakedret - nilerr - nolintlint diff --git a/pkg/applyconfiguration/applyconfiguration_integration_test.go b/pkg/applyconfiguration/applyconfiguration_integration_test.go index 7462a4d3a..080ec5776 100644 --- a/pkg/applyconfiguration/applyconfiguration_integration_test.go +++ b/pkg/applyconfiguration/applyconfiguration_integration_test.go @@ -193,6 +193,9 @@ var _ = Describe("ApplyConfiguration generation from API types", func() { // Make sure the import paths are correct for the newly generated content. content = []byte(strings.ReplaceAll(string(content), "testdata/cronjob/api/v1/applyconfiguration", filepath.Join("testdata/cronjob/api/v1", outputPackage))) + // Make sure the interface{} is replaced with any. + content = []byte(strings.ReplaceAll(string(content), "any", "interface{}")) + Expect(string(filesInOutput[name])).To(BeComparableTo(string(content)), "Generated files should match the checked in files, diff found in %s", name) } }, diff --git a/pkg/applyconfiguration/testdata/cronjob/api/v1/applyconfiguration/utils.go b/pkg/applyconfiguration/testdata/cronjob/api/v1/applyconfiguration/utils.go index e7221c7ca..6c131fee9 100644 --- a/pkg/applyconfiguration/testdata/cronjob/api/v1/applyconfiguration/utils.go +++ b/pkg/applyconfiguration/testdata/cronjob/api/v1/applyconfiguration/utils.go @@ -13,7 +13,7 @@ import ( // ForKind returns an apply configuration type for the given GroupVersionKind, or nil if no // apply configuration type exists for the given GroupVersionKind. -func ForKind(kind schema.GroupVersionKind) interface{} { +func ForKind(kind schema.GroupVersionKind) any { switch kind { // Group=testdata.kubebuilder.io, Version=v1 case v1.SchemeGroupVersion.WithKind("AssociativeType"): diff --git a/pkg/applyconfiguration/testdata/cronjob/api/v1/cronjob_types.go b/pkg/applyconfiguration/testdata/cronjob/api/v1/cronjob_types.go index edf63ae8c..9497df1a9 100644 --- a/pkg/applyconfiguration/testdata/cronjob/api/v1/cronjob_types.go +++ b/pkg/applyconfiguration/testdata/cronjob/api/v1/cronjob_types.go @@ -26,6 +26,7 @@ import ( "encoding" "encoding/json" "fmt" + "maps" "net/url" "strconv" "time" @@ -412,8 +413,8 @@ type ContainsNestedMap struct { // +kubebuilder:validation:Type=object // +kubebuilder:pruning:PreserveUnknownFields type Preserved struct { - ConcreteField string `json:"concreteField"` - Rest map[string]interface{} `json:"-"` + ConcreteField string `json:"concreteField"` + Rest map[string]any `json:"-"` } func (p *Preserved) UnmarshalJSON(data []byte) error { @@ -434,10 +435,8 @@ func (p *Preserved) UnmarshalJSON(data []byte) error { } func (p *Preserved) MarshalJSON() ([]byte, error) { - full := make(map[string]interface{}, len(p.Rest)+1) - for k, v := range p.Rest { - full[k] = v - } + full := make(map[string]any, len(p.Rest)+1) + maps.Copy(full, p.Rest) full["concreteField"] = p.ConcreteField return json.Marshal(full) } diff --git a/pkg/crd/flatten.go b/pkg/crd/flatten.go index cf02c9b71..d3f2293ba 100644 --- a/pkg/crd/flatten.go +++ b/pkg/crd/flatten.go @@ -38,7 +38,7 @@ type ErrorRecorder interface { // isOrNil checks if val is nil if val is of a nillable type, otherwise, // it compares val to valInt (which should probably be the zero value). -func isOrNil(val reflect.Value, valInt interface{}, zeroInt interface{}) bool { +func isOrNil(val reflect.Value, valInt any, zeroInt any) bool { switch valKind := val.Kind(); valKind { case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: return val.IsNil() diff --git a/pkg/crd/gen.go b/pkg/crd/gen.go index 5fad65a71..5d01db82e 100644 --- a/pkg/crd/gen.go +++ b/pkg/crd/gen.go @@ -108,15 +108,15 @@ func (Generator) RegisterMarkers(into *markers.Registry) error { } // transformRemoveCRDStatus ensures we do not write the CRD status field. -func transformRemoveCRDStatus(obj map[string]interface{}) error { +func transformRemoveCRDStatus(obj map[string]any) error { delete(obj, "status") return nil } // transformPreserveUnknownFields adds spec.preserveUnknownFields=value. -func transformPreserveUnknownFields(value bool) func(map[string]interface{}) error { - return func(obj map[string]interface{}) error { - if spec, ok := obj["spec"].(map[interface{}]interface{}); ok { +func transformPreserveUnknownFields(value bool) func(map[string]any) error { + return func(obj map[string]any) error { + if spec, ok := obj["spec"].(map[any]any); ok { spec["preserveUnknownFields"] = value } return nil @@ -185,7 +185,7 @@ func (g Generator) Generate(ctx *genall.GenerationContext) error { // Prevent the top level metadata for the CRD to be generate regardless of the intention in the arguments FixTopLevelMetadata(crdRaw) - versionedCRDs := make([]interface{}, len(crdVersions)) + versionedCRDs := make([]any, len(crdVersions)) for i, ver := range crdVersions { conv, err := AsVersion(crdRaw, schema.GroupVersion{Group: apiext.SchemeGroupVersion.Group, Version: ver}) if err != nil { @@ -202,7 +202,7 @@ func (g Generator) Generate(ctx *genall.GenerationContext) error { } else { fileName = fmt.Sprintf("%s_%s.%s.yaml", crdRaw.Spec.Group, crdRaw.Spec.Names.Plural, crdVersions[i]) } - if err := ctx.WriteYAML(fileName, headerText, []interface{}{crd}, yamlOpts...); err != nil { + if err := ctx.WriteYAML(fileName, headerText, []any{crd}, yamlOpts...); err != nil { return err } } diff --git a/pkg/crd/known_types.go b/pkg/crd/known_types.go index 904b39d01..78488665a 100644 --- a/pkg/crd/known_types.go +++ b/pkg/crd/known_types.go @@ -17,6 +17,8 @@ limitations under the License. package crd import ( + "maps" + apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/utils/ptr" "sigs.k8s.io/controller-tools/pkg/loader" @@ -156,13 +158,9 @@ func AddKnownTypes(parser *Parser) { // ensure everything is there before adding to PackageOverrides // TODO(directxman12): this is a bit of a hack, maybe just use constructors? parser.init() - for pkgName, override := range KnownPackages { - parser.PackageOverrides[pkgName] = override - } + maps.Copy(parser.PackageOverrides, KnownPackages) // if we want to generate the embedded ObjectMeta in the CRD we need to add the ObjectMetaPackages if parser.GenerateEmbeddedObjectMeta { - for pkgName, override := range ObjectMetaPackages { - parser.PackageOverrides[pkgName] = override - } + maps.Copy(parser.PackageOverrides, ObjectMetaPackages) } } diff --git a/pkg/crd/markers/register.go b/pkg/crd/markers/register.go index b5a2760b0..d219689aa 100644 --- a/pkg/crd/markers/register.go +++ b/pkg/crd/markers/register.go @@ -79,7 +79,7 @@ type hasHelp interface { // mustMakeAllWithPrefix converts each object into a marker definition using // the object's type's with the prefix to form the marker name. -func mustMakeAllWithPrefix(prefix string, target markers.TargetType, objs ...interface{}) []*definitionWithHelp { +func mustMakeAllWithPrefix(prefix string, target markers.TargetType, objs ...any) []*definitionWithHelp { defs := make([]*definitionWithHelp, len(objs)) for i, obj := range objs { name := prefix + reflect.TypeOf(obj).Name() diff --git a/pkg/crd/markers/validation.go b/pkg/crd/markers/validation.go index c91f5e6a1..8600a4081 100644 --- a/pkg/crd/markers/validation.go +++ b/pkg/crd/markers/validation.go @@ -233,7 +233,7 @@ type MinProperties int // Enum specifies that this (scalar) field is restricted to the *exact* values specified here. // +controllertools:marker:generateHelp:category="CRD validation" -type Enum []interface{} +type Enum []any // Format specifies additional "complex" formatting for this field. // @@ -265,7 +265,7 @@ type Nullable struct{} // submission of the containing CRD to an apiserver. // +controllertools:marker:generateHelp:category="CRD validation" type Default struct { - Value interface{} + Value any } // Title sets the title for this field. @@ -276,7 +276,7 @@ type Default struct { // important context about what the schema represents. // +controllertools:marker:generateHelp:category="CRD validation" type Title struct { - Value interface{} + Value any } // KubernetesDefault sets the default value for this field. @@ -290,7 +290,7 @@ type Title struct { // submission of the containing CRD to an apiserver. // +controllertools:marker:generateHelp:category="CRD validation" type KubernetesDefault struct { - Value interface{} + Value any } // Example sets the example value for this field. @@ -303,7 +303,7 @@ type KubernetesDefault struct { // submission of the containing CRD to an apiserver. // +controllertools:marker:generateHelp:category="CRD validation" type Example struct { - Value interface{} + Value any } // XPreserveUnknownFields stops the apiserver from pruning fields which are not specified. diff --git a/pkg/crd/schema_test.go b/pkg/crd/schema_test.go index ab37eb966..2a4326366 100644 --- a/pkg/crd/schema_test.go +++ b/pkg/crd/schema_test.go @@ -39,7 +39,7 @@ func transform(t *testing.T, expr string) *apiext.JSONSchemaProps { modules := []pkgstest.Module{ { Name: moduleName, - Files: map[string]interface{}{ + Files: map[string]any{ "test.go": ` package crd type Test ` + expr, @@ -121,7 +121,7 @@ func Test_Schema_ApplyMarkers(t *testing.T) { var invocations []string applyMarkers(ctx, markers.MarkerValues{ - "blah": []interface{}{ + "blah": []any{ &testPriorityMarker{ priority: 0, callback: func() { invocations = append(invocations, "0") diff --git a/pkg/crd/testdata/cronjob_types.go b/pkg/crd/testdata/cronjob_types.go index 8f6caea58..40569df94 100644 --- a/pkg/crd/testdata/cronjob_types.go +++ b/pkg/crd/testdata/cronjob_types.go @@ -452,8 +452,8 @@ type ContainsNestedMap struct { // +kubebuilder:validation:Type=object // +kubebuilder:pruning:PreserveUnknownFields type Preserved struct { - ConcreteField string `json:"concreteField"` - Rest map[string]interface{} `json:"-"` + ConcreteField string `json:"concreteField"` + Rest map[string]any `json:"-"` } func (p *Preserved) UnmarshalJSON(data []byte) error { @@ -474,7 +474,7 @@ func (p *Preserved) UnmarshalJSON(data []byte) error { } func (p *Preserved) MarshalJSON() ([]byte, error) { - full := make(map[string]interface{}, len(p.Rest)+1) + full := make(map[string]any, len(p.Rest)+1) for k, v := range p.Rest { full[k] = v } diff --git a/pkg/crd/testdata/wrong_annotation_format/cronjob_types.go b/pkg/crd/testdata/wrong_annotation_format/cronjob_types.go index 7c84ab81e..3c80fc2df 100644 --- a/pkg/crd/testdata/wrong_annotation_format/cronjob_types.go +++ b/pkg/crd/testdata/wrong_annotation_format/cronjob_types.go @@ -242,8 +242,8 @@ type ContainsNestedMap struct { // +kubebuilder:validation:Type=object // +kubebuilder:pruning:PreserveUnknownFields type Preserved struct { - ConcreteField string `json:"concreteField"` - Rest map[string]interface{} `json:"-"` + ConcreteField string `json:"concreteField"` + Rest map[string]any `json:"-"` } func (p *Preserved) UnmarshalJSON(data []byte) error { @@ -264,7 +264,7 @@ func (p *Preserved) UnmarshalJSON(data []byte) error { } func (p *Preserved) MarshalJSON() ([]byte, error) { - full := make(map[string]interface{}, len(p.Rest)+1) + full := make(map[string]any, len(p.Rest)+1) for k, v := range p.Rest { full[k] = v } diff --git a/pkg/deepcopy/traverse.go b/pkg/deepcopy/traverse.go index b0fa52de2..bf24526d6 100644 --- a/pkg/deepcopy/traverse.go +++ b/pkg/deepcopy/traverse.go @@ -49,7 +49,7 @@ func (c *codeWriter) Line(line string) { } // Linef writes a single line with formatting (as per fmt.Sprintf). -func (c *codeWriter) Linef(line string, args ...interface{}) { +func (c *codeWriter) Linef(line string, args ...any) { fmt.Fprintf(c.out, line+"\n", args...) } @@ -447,9 +447,7 @@ func (c *copyMethodMaker) genSliceDeepCopy(actualName *namingInfo, sliceType *ty func (c *copyMethodMaker) genStructDeepCopy(_ *namingInfo, structType *types.Struct) { c.Line("*out = *in") - for i := 0; i < structType.NumFields(); i++ { - field := structType.Field(i) - + for field := range structType.Fields() { // if we have a manual deepcopy, use that hasDeepCopy, copyOnPtr := hasDeepCopyMethod(c.pkg, field.Type()) hasDeepCopyInto := hasDeepCopyIntoMethod(c.pkg, field.Type()) @@ -769,8 +767,7 @@ func fineToShallowCopy(typeInfo types.Type) bool { return fineToShallowCopy(typeInfo.Underlying()) case *types.Struct: // structs are fine to shallow-copy if they have all shallow-copyable fields - for i := 0; i < typeInfo.NumFields(); i++ { - field := typeInfo.Field(i) + for field := range typeInfo.Fields() { if !fineToShallowCopy(field.Type()) { return false } diff --git a/pkg/genall/genall.go b/pkg/genall/genall.go index b6f37409b..85333f88d 100644 --- a/pkg/genall/genall.go +++ b/pkg/genall/genall.go @@ -121,19 +121,19 @@ type GenerationContext struct { // WriteYAMLOptions implements the Options Pattern for WriteYAML. type WriteYAMLOptions struct { - transform func(obj map[string]interface{}) error + transform func(obj map[string]any) error } // WithTransform applies a transformation to objects just before writing them. -func WithTransform(transform func(obj map[string]interface{}) error) *WriteYAMLOptions { +func WithTransform(transform func(obj map[string]any) error) *WriteYAMLOptions { return &WriteYAMLOptions{ transform: transform, } } // TransformRemoveCreationTimestamp ensures we do not write the metadata.creationTimestamp field. -func TransformRemoveCreationTimestamp(obj map[string]interface{}) error { - metadata := obj["metadata"].(map[interface{}]interface{}) +func TransformRemoveCreationTimestamp(obj map[string]any) error { + metadata := obj["metadata"].(map[any]any) delete(metadata, "creationTimestamp") return nil } @@ -141,7 +141,7 @@ func TransformRemoveCreationTimestamp(obj map[string]interface{}) error { // WriteYAML writes the given objects out, serialized as YAML, using the // context's OutputRule. Objects are written as separate documents, separated // from each other by `---` (as per the YAML spec). -func (g GenerationContext) WriteYAML(itemPath, headerText string, objs []interface{}, options ...*WriteYAMLOptions) error { +func (g GenerationContext) WriteYAML(itemPath, headerText string, objs []any, options ...*WriteYAMLOptions) error { out, err := g.Open(nil, itemPath) if err != nil { return err @@ -171,7 +171,7 @@ func (g GenerationContext) WriteYAML(itemPath, headerText string, objs []interfa } // yamlMarshal is based on sigs.k8s.io/yaml.Marshal, but allows for transforming the final data before writing. -func yamlMarshal(o interface{}, options ...*WriteYAMLOptions) ([]byte, error) { +func yamlMarshal(o any, options ...*WriteYAMLOptions) ([]byte, error) { j, err := json.Marshal(o) if err != nil { return nil, fmt.Errorf("error marshaling into JSON: %w", err) @@ -183,10 +183,10 @@ func yamlMarshal(o interface{}, options ...*WriteYAMLOptions) ([]byte, error) { // yamlJSONToYAMLWithFilter is based on sigs.k8s.io/yaml.JSONToYAML, but allows for transforming the final data before writing. func yamlJSONToYAMLWithFilter(j []byte, options ...*WriteYAMLOptions) ([]byte, error) { // Convert the JSON to an object. - var jsonObj map[string]interface{} + var jsonObj map[string]any // We are using yaml.Unmarshal here (instead of json.Unmarshal) because the // Go JSON library doesn't try to pick the right number type (int, float, - // etc.) when unmarshalling to interface{}, it just picks float64 + // etc.) when unmarshalling to any, it just picks float64 // universally. go-yaml does go through the effort of picking the right // number type, so we can preserve number type throughout this process. if err := rawyaml.Unmarshal(j, &jsonObj); err != nil { diff --git a/pkg/genall/help/pretty/print.go b/pkg/genall/help/pretty/print.go index 8d7452a0b..477496f81 100644 --- a/pkg/genall/help/pretty/print.go +++ b/pkg/genall/help/pretty/print.go @@ -291,7 +291,7 @@ func writePadding(out io.Writer, typ []byte, amt int) error { num := amt / len(typ) rem := amt % len(typ) - for i := 0; i < num; i++ { + for range num { if _, err := out.Write(typ); err != nil { return err } diff --git a/pkg/genall/options.go b/pkg/genall/options.go index 192235b76..8aa56a4bc 100644 --- a/pkg/genall/options.go +++ b/pkg/genall/options.go @@ -18,6 +18,7 @@ package genall import ( "fmt" + "maps" "strings" "golang.org/x/tools/go/packages" @@ -42,7 +43,7 @@ func RegisterOptionsMarkers(into *markers.Registry) error { return err } // NB(directxman12): we make this optional so we don't have a bootstrap problem with helpgen - if helpGiver, hasHelp := ((interface{})(InputPaths(nil))).(HasHelp); hasHelp { + if helpGiver, hasHelp := ((any)(InputPaths(nil))).(HasHelp); hasHelp { into.AddHelp(InputPathsMarker, helpGiver.Help()) } return nil @@ -100,9 +101,7 @@ func FromOptionsWithConfig(cfg *packages.Config, optionsRegistry *markers.Regist } outRules := DirectoryPerGenerator("config", protoRt.GeneratorsByName) - for gen, rule := range protoRt.OutputRules.ByGenerator { - outRules.ByGenerator[gen] = rule - } + maps.Copy(outRules.ByGenerator, protoRt.OutputRules.ByGenerator) genRuntime.OutputRules = outRules return genRuntime, nil diff --git a/pkg/loader/testutils/helpers.go b/pkg/loader/testutils/helpers.go index b0029b5eb..e87f9ee03 100644 --- a/pkg/loader/testutils/helpers.go +++ b/pkg/loader/testutils/helpers.go @@ -45,11 +45,11 @@ func (t fakeT) Cleanup(f func()) { t.g.Cleanup(f) } -func (t fakeT) Error(args ...interface{}) { +func (t fakeT) Error(args ...any) { t.g.Error(args...) } -func (t fakeT) Errorf(format string, args ...interface{}) { +func (t fakeT) Errorf(format string, args ...any) { t.g.Errorf(format, args...) } @@ -65,11 +65,11 @@ func (t fakeT) Failed() bool { return t.g.Failed() } -func (t fakeT) Fatal(args ...interface{}) { +func (t fakeT) Fatal(args ...any) { t.g.Fatal(args...) } -func (t fakeT) Fatalf(format string, args ...interface{}) { +func (t fakeT) Fatalf(format string, args ...any) { t.g.Fatalf(format, args...) } @@ -77,11 +77,11 @@ func (t fakeT) Helper() { t.g.Helper() } -func (t fakeT) Log(args ...interface{}) { +func (t fakeT) Log(args ...any) { t.g.Log(args...) } -func (t fakeT) Logf(format string, args ...interface{}) { +func (t fakeT) Logf(format string, args ...any) { t.g.Logf(format, args...) } @@ -93,7 +93,7 @@ func (t fakeT) Setenv(key, value string) { t.g.Setenv(key, value) } -func (t fakeT) Skip(args ...interface{}) { +func (t fakeT) Skip(args ...any) { t.g.Skip(args...) } @@ -101,7 +101,7 @@ func (t fakeT) SkipNow() { t.g.SkipNow() } -func (t fakeT) Skipf(format string, args ...interface{}) { +func (t fakeT) Skipf(format string, args ...any) { t.g.Skipf(format, args...) } diff --git a/pkg/markers/collect.go b/pkg/markers/collect.go index 23f52e3d2..4e4a61cc1 100644 --- a/pkg/markers/collect.go +++ b/pkg/markers/collect.go @@ -36,11 +36,11 @@ type Collector struct { } // MarkerValues are all the values for some set of markers. -type MarkerValues map[string][]interface{} +type MarkerValues map[string][]any // Get fetches the first value that for the given marker, returning // nil if no values are available. -func (v MarkerValues) Get(name string) interface{} { +func (v MarkerValues) Get(name string) any { vals := v[name] if len(vals) == 0 { return nil @@ -109,7 +109,7 @@ func (c *Collector) parseMarkersInPackage(nodeMarkersRaw map[ast.Node][]markerCo default: target = DescribesType } - markerVals := make(map[string][]interface{}) + markerVals := make(map[string][]any) for _, markerRaw := range markersRaw { markerText := markerRaw.Text() def := c.Registry.Lookup(markerText, target) diff --git a/pkg/markers/markers_suite_test.go b/pkg/markers/markers_suite_test.go index 1d6d246be..93cba0ae0 100644 --- a/pkg/markers/markers_suite_test.go +++ b/pkg/markers/markers_suite_test.go @@ -40,7 +40,7 @@ var _ = BeforeSuite(func() { modules := []pkgstest.Module{ { Name: "sigs.k8s.io/controller-tools/pkg/markers/testdata", - Files: map[string]interface{}{ + Files: map[string]any{ "file.go": ` package testdata diff --git a/pkg/markers/parse.go b/pkg/markers/parse.go index 42279f82c..e0994983d 100644 --- a/pkg/markers/parse.go +++ b/pkg/markers/parse.go @@ -50,8 +50,8 @@ func peekNoSpace(scanner *sc.Scanner) rune { var ( // interfaceType is a pre-computed reflect.Type representing the empty interface. - interfaceType = reflect.TypeOf((*interface{})(nil)).Elem() - rawArgsType = reflect.TypeOf((*RawArguments)(nil)).Elem() + interfaceType = reflect.TypeFor[*any]().Elem() + rawArgsType = reflect.TypeFor[*RawArguments]().Elem() ) // lowerCamelCase converts PascalCase string to @@ -69,7 +69,7 @@ func lowerCamelCase(in string) string { // RawArguments is a special type that can be used for a marker // to receive *all* raw, underparsed argument data for a marker. -// You probably want to use `interface{}` to match any type instead. +// You probably want to use `any` to match any type instead. // Use *only* for legacy markers that don't follow Definition's normal // parsing logic. It should *not* be used as a field in a marker struct. type RawArguments []byte @@ -183,13 +183,13 @@ func makeSliceType(itemType Argument) (reflect.Type, error) { var itemReflectedType reflect.Type switch itemType.Type { case IntType: - itemReflectedType = reflect.TypeOf(int(0)) + itemReflectedType = reflect.TypeFor[int]() case NumberType: - itemReflectedType = reflect.TypeOf(float64(0)) + itemReflectedType = reflect.TypeFor[float64]() case StringType: - itemReflectedType = reflect.TypeOf("") + itemReflectedType = reflect.TypeFor[string]() case BoolType: - itemReflectedType = reflect.TypeOf(false) + itemReflectedType = reflect.TypeFor[bool]() case SliceType: subItemType, err := makeSliceType(*itemType.ItemType) if err != nil { @@ -220,13 +220,13 @@ func makeMapType(itemType Argument) (reflect.Type, error) { var itemReflectedType reflect.Type switch itemType.Type { case IntType: - itemReflectedType = reflect.TypeOf(int(0)) + itemReflectedType = reflect.TypeFor[int]() case NumberType: - itemReflectedType = reflect.TypeOf(float64(0)) + itemReflectedType = reflect.TypeFor[float64]() case StringType: - itemReflectedType = reflect.TypeOf("") + itemReflectedType = reflect.TypeFor[string]() case BoolType: - itemReflectedType = reflect.TypeOf(false) + itemReflectedType = reflect.TypeFor[bool]() case SliceType: subItemType, err := makeSliceType(*itemType.ItemType) if err != nil { @@ -251,7 +251,7 @@ func makeMapType(itemType Argument) (reflect.Type, error) { itemReflectedType = reflect.PointerTo(itemReflectedType) } - return reflect.MapOf(reflect.TypeOf(""), itemReflectedType), nil + return reflect.MapOf(reflect.TypeFor[string](), itemReflectedType), nil } // guessType takes an educated guess about the type of the next field. If allowSlice @@ -825,7 +825,7 @@ type markerParser interface { // Parse uses the type information in this Definition to parse the given // raw marker in the form `+a:b:c=arg,d=arg` into an output object of the // type specified in the definition. -func (d *Definition) Parse(rawMarker string) (interface{}, error) { +func (d *Definition) Parse(rawMarker string) (any, error) { name, anonName, fields := splitMarker(rawMarker) outPointer := reflect.New(d.Output) @@ -929,7 +929,7 @@ func (d *Definition) Parse(rawMarker string) (interface{}, error) { // type, its public fields will automatically be populated into Fields (and similar // fields in Definition). Other values will have a single, empty-string-named Fields // entry. -func MakeDefinition(name string, target TargetType, output interface{}) (*Definition, error) { +func MakeDefinition(name string, target TargetType, output any) (*Definition, error) { def := &Definition{ Name: name, Target: target, @@ -945,9 +945,9 @@ func MakeDefinition(name string, target TargetType, output interface{}) (*Defini } // MakeAnyTypeDefinition constructs a definition for an output struct with a -// field named `Value` of type `interface{}`. The argument to the marker will +// field named `Value` of type `any`. The argument to the marker will // be parsed as AnyType and assigned to the field named `Value`. -func MakeAnyTypeDefinition(name string, target TargetType, output interface{}) (*Definition, error) { +func MakeAnyTypeDefinition(name string, target TargetType, output any) (*Definition, error) { defn, err := MakeDefinition(name, target, output) if err != nil { return nil, err diff --git a/pkg/markers/parse_test.go b/pkg/markers/parse_test.go index f21b45412..0a66ee81f 100644 --- a/pkg/markers/parse_test.go +++ b/pkg/markers/parse_test.go @@ -27,7 +27,7 @@ import ( . "sigs.k8s.io/controller-tools/pkg/markers" ) -func mustDefine(reg *Registry, name string, target TargetType, obj interface{}) { +func mustDefine(reg *Registry, name string, target TargetType, obj any) { Expect(reg.Define(name, target, obj)).To(Succeed()) } @@ -36,7 +36,7 @@ type multiFieldStruct struct { Str string Int int Bool bool - Any interface{} + Any any PtrOpt *string NormalOpt string `marker:",optional"` DiffNamed string `marker:"other"` @@ -51,7 +51,7 @@ type allOptionalStruct struct { } type CustomType struct { - Value interface{} + Value any } var _ = Describe("Parsing", func() { @@ -208,11 +208,11 @@ var _ = Describe("Parsing", func() { It("should support delimitted slices of bare slices", argParseTestCase{arg: anyArg, raw: "{1;1,2;3,5;8}", output: sliceOSliceOut}.Run) It("should support delimitted slices of delimitted slices", argParseTestCase{arg: anyArg, raw: "{{1,1},{2,3},{5,8}}", output: sliceOSliceOut}.Run) - complexMap := map[string]interface{}{ + complexMap := map[string]any{ "text": "abc", "len": 3, "as bytes": []int{97, 98, 99}, - "props": map[string]interface{}{ + "props": map[string]any{ "encoding": "ascii", "nullsafe": true, "tags": []string{"triple", "in a row"}, @@ -226,7 +226,7 @@ var _ = Describe("Parsing", func() { type parseTestCase struct { reg **Registry raw string - output interface{} + output any target TargetType // NB(directxman12): iota is DescribesPackage } @@ -247,7 +247,7 @@ func (tc parseTestCase) Run() { type argParseTestCase struct { arg Argument raw string - output interface{} + output any } func (tc argParseTestCase) Run() { @@ -260,7 +260,7 @@ func (tc argParseTestCase) Run() { var actualOut reflect.Value if tc.arg.Type == AnyType { - actualOut = reflect.Indirect(reflect.New(reflect.TypeOf((*interface{})(nil)).Elem())) + actualOut = reflect.Indirect(reflect.New(reflect.TypeFor[*any]().Elem())) } else { actualOut = reflect.Indirect(reflect.New(reflect.TypeOf(tc.output))) } diff --git a/pkg/markers/reg.go b/pkg/markers/reg.go index 7dcd45899..0897e9437 100644 --- a/pkg/markers/reg.go +++ b/pkg/markers/reg.go @@ -54,7 +54,7 @@ func (r *Registry) init() { // It's a shortcut around // // r.Register(MakeDefinition(name, target, obj)) -func (r *Registry) Define(name string, target TargetType, obj interface{}) error { +func (r *Registry) Define(name string, target TargetType, obj any) error { def, err := MakeDefinition(name, target, obj) if err != nil { return err diff --git a/pkg/rbac/parser.go b/pkg/rbac/parser.go index 6521d2658..ed12a0a62 100644 --- a/pkg/rbac/parser.go +++ b/pkg/rbac/parser.go @@ -24,6 +24,7 @@ package rbac import ( "fmt" + "slices" "sort" "strings" @@ -181,7 +182,7 @@ func (Generator) RegisterMarkers(into *markers.Registry) error { // GenerateRoles generate a slice of objs representing either a ClusterRole or a Role object // The order of the objs in the returned slice is stable and determined by their namespaces. -func GenerateRoles(ctx *genall.GenerationContext, roleName string) ([]interface{}, error) { +func GenerateRoles(ctx *genall.GenerationContext, roleName string) ([]any, error) { rulesByNSResource := make(map[string][]*Rule) for _, root := range ctx.Roots { markerSet, err := markers.PackageMarkers(ctx.Collector, root) @@ -308,11 +309,8 @@ func GenerateRoles(ctx *genall.GenerationContext, roleName string) ([]interface{ // Normalize rule verbs to "*" if any verb in the rule is an asterisk for _, rule := range ruleMap { - for _, verb := range rule.Verbs { - if verb == "*" { - rule.Verbs = []string{"*"} - break - } + if slices.Contains(rule.Verbs, "*") { + rule.Verbs = []string{"*"} } } var policyRules []rbacv1.PolicyRule @@ -330,7 +328,7 @@ func GenerateRoles(ctx *genall.GenerationContext, roleName string) ([]interface{ sort.Strings(namespaces) // process the items in rulesByNS by the order specified in `namespaces` to make sure that the Role order is stable - var objs []interface{} + var objs []any for _, ns := range namespaces { rules := rulesByNSResource[ns] policyRules := NormalizeRules(rules) diff --git a/pkg/rbac/parser_integration_test.go b/pkg/rbac/parser_integration_test.go index 6d877d966..a668b4c45 100644 --- a/pkg/rbac/parser_integration_test.go +++ b/pkg/rbac/parser_integration_test.go @@ -19,7 +19,7 @@ import ( var _ = Describe("ClusterRole generated by the RBAC Generator", func() { // run this test multiple times to make sure the Rule order is stable. const stableTestCount = 5 - for i := 0; i < stableTestCount; i++ { + for range stableTestCount { It("should match the expected result", func() { By("switching into testdata to appease go modules") cwd, err := os.Getwd() diff --git a/pkg/schemapatcher/internal/yaml/convert.go b/pkg/schemapatcher/internal/yaml/convert.go index b0ac00158..51c7d5d44 100644 --- a/pkg/schemapatcher/internal/yaml/convert.go +++ b/pkg/schemapatcher/internal/yaml/convert.go @@ -26,7 +26,7 @@ import ( // ToYAML converts some object that serializes to JSON into a YAML node tree. // It's useful since it pays attention to JSON tags, unlike yaml.Unmarshal or // yaml.Node.Decode. -func ToYAML(rawObj interface{}) (*yaml.Node, error) { +func ToYAML(rawObj any) (*yaml.Node, error) { if rawObj == nil { return &yaml.Node{Kind: yaml.ScalarNode, Value: "null", Tag: "!!null"}, nil } diff --git a/pkg/schemapatcher/internal/yaml/delete_test.go b/pkg/schemapatcher/internal/yaml/delete_test.go index 259cbb04e..038a5a0c3 100644 --- a/pkg/schemapatcher/internal/yaml/delete_test.go +++ b/pkg/schemapatcher/internal/yaml/delete_test.go @@ -25,38 +25,38 @@ import ( var _ = Describe("DeleteNode", func() { tests := []struct { name string - obj interface{} + obj any path []string - want interface{} + want any wantErr bool }{ /* {name: "non-empty, unknown path", - obj: map[string]interface{}{ + obj: map[string]any{ "bar": int64(42), }, path: []string{"foo"}, - want: map[string]interface{}{ + want: map[string]any{ "bar": int64(42), }, }, {name: "non-empty, existing path", - obj: map[string]interface{}{ + obj: map[string]any{ "bar": int64(42), }, path: []string{"bar"}, - want: map[string]interface{}{}, + want: map[string]any{}, }, */ {name: "non-empty, long path", - obj: map[string]interface{}{ - "foo": map[string]interface{}{ + obj: map[string]any{ + "foo": map[string]any{ "bar": int64(42), }, }, path: []string{"foo", "bar"}, - want: map[string]interface{}{ - "foo": map[string]interface{}{}, + want: map[string]any{ + "foo": map[string]any{}, }, }, } diff --git a/pkg/schemapatcher/internal/yaml/nested_test.go b/pkg/schemapatcher/internal/yaml/nested_test.go index 54a76555e..2a72e908a 100644 --- a/pkg/schemapatcher/internal/yaml/nested_test.go +++ b/pkg/schemapatcher/internal/yaml/nested_test.go @@ -24,9 +24,9 @@ import ( var _ = Describe("GetNode", func() { tests := []struct { name string - obj interface{} + obj any path []string - want interface{} + want any found bool wantErr bool }{ @@ -34,18 +34,18 @@ var _ = Describe("GetNode", func() { found: true, }, {name: "empty", - obj: map[string]interface{}{}, + obj: map[string]any{}, found: true, - want: map[string]interface{}{}, + want: map[string]any{}, }, {name: "non-empty, wrong path", - obj: map[string]interface{}{ + obj: map[string]any{ "bar": int64(42), }, path: []string{"foo"}, }, {name: "non-empty, right path", - obj: map[string]interface{}{ + obj: map[string]any{ "bar": int64(42), }, path: []string{"bar"}, @@ -53,8 +53,8 @@ var _ = Describe("GetNode", func() { found: true, }, {name: "non-empty, long path", - obj: map[string]interface{}{ - "foo": map[string]interface{}{ + obj: map[string]any{ + "foo": map[string]any{ "bar": int64(42), }, }, @@ -63,8 +63,8 @@ var _ = Describe("GetNode", func() { found: true, }, {name: "invalid type", - obj: map[string]interface{}{ - "foo": []interface{}{int64(42)}, + obj: map[string]any{ + "foo": []any{int64(42)}, }, path: []string{"foo", "bar"}, wantErr: true, diff --git a/pkg/schemapatcher/internal/yaml/set_test.go b/pkg/schemapatcher/internal/yaml/set_test.go index e6d8bf6ff..8597196c7 100644 --- a/pkg/schemapatcher/internal/yaml/set_test.go +++ b/pkg/schemapatcher/internal/yaml/set_test.go @@ -25,61 +25,61 @@ import ( var _ = Describe("SetNode", func() { tests := []struct { name string - obj interface{} - value interface{} + obj any + value any path []string - want interface{} + want any wantErr bool }{ {name: "null"}, {name: "empty, null value", - obj: map[string]interface{}{}, + obj: map[string]any{}, value: nil, want: nil, }, {name: "empty, non-null value", - obj: map[string]interface{}{}, + obj: map[string]any{}, value: int64(64), want: int64(64), }, {name: "non-empty, unknown path", - obj: map[string]interface{}{ + obj: map[string]any{ "bar": int64(42), }, value: "foo", path: []string{"foo"}, - want: map[string]interface{}{ + want: map[string]any{ "bar": int64(42), "foo": "foo", }, }, {name: "non-empty, existing path", - obj: map[string]interface{}{ + obj: map[string]any{ "bar": int64(42), }, value: "foo", path: []string{"bar"}, - want: map[string]interface{}{ + want: map[string]any{ "bar": "foo", }, }, {name: "non-empty, long path", - obj: map[string]interface{}{ - "foo": map[string]interface{}{ + obj: map[string]any{ + "foo": map[string]any{ "bar": int64(42), }, }, value: "foo", path: []string{"foo", "bar"}, - want: map[string]interface{}{ - "foo": map[string]interface{}{ + want: map[string]any{ + "foo": map[string]any{ "bar": "foo", }, }, }, {name: "invalid type", - obj: map[string]interface{}{ - "foo": []interface{}{int64(42)}, + obj: map[string]any{ + "foo": []any{int64(42)}, }, value: "foo", path: []string{"foo", "bar"}, diff --git a/pkg/webhook/parser.go b/pkg/webhook/parser.go index 2737562be..d650c1943 100644 --- a/pkg/webhook/parser.go +++ b/pkg/webhook/parser.go @@ -514,7 +514,7 @@ func (g Generator) Generate(ctx *genall.GenerationContext) error { } } - versionedWebhooks := make(map[string][]interface{}, len(supportedWebhookVersions)) + versionedWebhooks := make(map[string][]any, len(supportedWebhookVersions)) //nolint:dupl for _, version := range supportedWebhookVersions { if cfgs, ok := mutatingCfgs[version]; ok { diff --git a/pkg/webhook/parser_integration_test.go b/pkg/webhook/parser_integration_test.go index ce2ca51b3..b7d773016 100644 --- a/pkg/webhook/parser_integration_test.go +++ b/pkg/webhook/parser_integration_test.go @@ -36,7 +36,7 @@ import ( // now, we're trusting k/k's conversion code, though, which is probably // fine for the time being) var _ = Describe("Webhook Generation From Parsing to CustomResourceDefinition", func() { - assertSame := func(actual, expected interface{}) { + assertSame := func(actual, expected any) { ExpectWithOffset(1, actual).To(Equal(expected), "type not as expected, check pkg/webhook/testdata/README.md for more details.\n\nDiff:\n\n%s", cmp.Diff(actual, expected)) } @@ -276,7 +276,7 @@ var _ = Describe("Webhook Generation From Parsing to CustomResourceDefinition", Expect(err).NotTo(HaveOccurred()) defer os.RemoveAll(outputDir) - for i := 0; i < 10; i++ { + for range 10 { genCtx := &genall.GenerationContext{ Collector: &markers.Collector{Registry: reg}, Roots: pkgs,