diff --git a/.editorconfig b/.editorconfig index bd35fa9d83..4b89edcf9b 100644 --- a/.editorconfig +++ b/.editorconfig @@ -16,5 +16,7 @@ charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true -[Makefile] +# https://github.com/editorconfig/editorconfig-core-go/blob/master/.editorconfig +[{Makefile,go.mod,go.sum,*.go}] indent_style = tab +indent_size = 4 diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index a894704f2c..e28df912b2 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -27,9 +27,22 @@ jobs: with: go-version-file: go.mod - - name: Lint go code + - name: Go formatting + run: | + if [ -z "$(gofmt -l .)" ]; then + echo -e "All '*.go' files are properly formatted." + else + echo -e "Please run 'make go-lint' to fix. Some files need formatting:" + gofmt -d -l . + exit 1 + fi + + + # https://github.com/golangci/golangci-lint-action?tab=readme-ov-file#verify + - name: Verify linter configuration and Lint go code uses: golangci/golangci-lint-action@v6 with: + verify: true args: --timeout=30m version: v1.63 diff --git a/.golangci.yml b/.golangci.yml index 93dff1d174..69572734fb 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -3,8 +3,6 @@ linters-settings: default-signifies-exhaustive: false goimports: local-prefixes: sigs.k8s.io/external-dns - maligned: - suggest-new: true misspell: locale: US revive: @@ -36,6 +34,8 @@ linters: issues: # Excluding configuration per-path, per-linter, per-text and per-source + exclude-files: + - endpoint/zz_generated.deepcopy.go exclude-rules: - path: _test\.go linters: @@ -67,7 +67,3 @@ issues: linters: [ typecheck ] - path: source/kong_tcpingress.go linters: [ typecheck ] - -run: - exclude-files: - - endpoint/zz_generated.deepcopy.go diff --git a/Makefile b/Makefile index d9392e7082..f1a1b2f334 100644 --- a/Makefile +++ b/Makefile @@ -44,9 +44,14 @@ endif golangci-lint: @command -v golangci-lint > /dev/null || curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.63.4 +#? golangci-lint-verify: Verify golangci-lint configuration +golangci-lint-verify: golangci-lint + @golangci-lint config verify + #? go-lint: Run the golangci-lint tool .PHONY: go-lint go-lint: golangci-lint + gofmt -l -s -w . golangci-lint run --timeout=30m ./... #? licensecheck: Run the to check for license headers diff --git a/docs/contributing/index.md b/docs/contributing/index.md index f534b4db4a..4ddf33637a 100644 --- a/docs/contributing/index.md +++ b/docs/contributing/index.md @@ -4,7 +4,7 @@ This folder contains developer documentation. When you are ready to contribute, you can select issue at [Good First Issues](https://github.com/kubernetes-sigs/external-dns/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22help%20wanted%22). -To get started see: [dev-guide.md](devguide.md). +To get started see: [dev-guide.md](dev-guide.md). > Note; when new feature/fix is ready, consider also to provide a way to test this manually with manifests and kubectl commands diff --git a/provider/aws/aws_fixtures_test.go b/provider/aws/aws_fixtures_test.go index 5317bb64d3..21c65e3329 100644 --- a/provider/aws/aws_fixtures_test.go +++ b/provider/aws/aws_fixtures_test.go @@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/provider/aws/aws_test.go b/provider/aws/aws_test.go index 59ea876f60..75e291033d 100644 --- a/provider/aws/aws_test.go +++ b/provider/aws/aws_test.go @@ -1919,7 +1919,7 @@ func TestAWSCanonicalHostedZoneNotExist(t *testing.T) { func BenchmarkTestAWSCanonicalHostedZone(b *testing.B) { for i := 0; i < b.N; i++ { - for suffix, _ := range canonicalHostedZones { + for suffix := range canonicalHostedZones { _ = canonicalHostedZone(fmt.Sprintf("foo.%s", suffix)) } } @@ -1927,7 +1927,7 @@ func BenchmarkTestAWSCanonicalHostedZone(b *testing.B) { func BenchmarkTestAWSNonCanonicalHostedZone(b *testing.B) { for i := 0; i < b.N; i++ { - for _, _ = range canonicalHostedZones { + for range canonicalHostedZones { _ = canonicalHostedZone("extremely.long.zone-2.ext.dns.test.zone.non.canonical.example.com") } } diff --git a/provider/aws/aws_utils_test.go b/provider/aws/aws_utils_test.go index 704bd83921..23c0f02e18 100644 --- a/provider/aws/aws_utils_test.go +++ b/provider/aws/aws_utils_test.go @@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -17,132 +17,132 @@ limitations under the License. package aws import ( - "context" - "os" - "testing" - "time" - - "github.com/aws/aws-sdk-go-v2/service/route53" - route53types "github.com/aws/aws-sdk-go-v2/service/route53/types" - "github.com/stretchr/testify/assert" - "gopkg.in/yaml.v3" - "sigs.k8s.io/external-dns/endpoint" - "sigs.k8s.io/external-dns/provider" + "context" + "os" + "testing" + "time" + + "github.com/aws/aws-sdk-go-v2/service/route53" + route53types "github.com/aws/aws-sdk-go-v2/service/route53/types" + "github.com/stretchr/testify/assert" + "gopkg.in/yaml.v3" + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/provider" ) type HostedZones struct { - Zones []*HostedZone `yaml:"zones"` + Zones []*HostedZone `yaml:"zones"` } type HostedZone struct { - Name string - ID string - Tags []route53types.Tag `yaml:"tags"` + Name string + ID string + Tags []route53types.Tag `yaml:"tags"` } var _ Route53API = &Route53APIFixtureStub{} type Route53APIFixtureStub struct { - zones map[string]*route53types.HostedZone - zoneTags map[string][]route53types.Tag - calls map[string]int + zones map[string]*route53types.HostedZone + zoneTags map[string][]route53types.Tag + calls map[string]int } func providerFilters(client *Route53APIFixtureStub, options ...func(awsProvider *AWSProvider)) *AWSProvider { - p := &AWSProvider{ - clients: map[string]Route53API{defaultAWSProfile: client}, - evaluateTargetHealth: false, - dryRun: false, - domainFilter: endpoint.NewDomainFilter([]string{}), - zoneIDFilter: provider.NewZoneIDFilter([]string{}), - zoneTypeFilter: provider.NewZoneTypeFilter(""), - zoneTagFilter: provider.NewZoneTagFilter([]string{}), - zonesCache: &zonesListCache{duration: 1 * time.Second}, - } - for _, o := range options { - o(p) - } - return p + p := &AWSProvider{ + clients: map[string]Route53API{defaultAWSProfile: client}, + evaluateTargetHealth: false, + dryRun: false, + domainFilter: endpoint.NewDomainFilter([]string{}), + zoneIDFilter: provider.NewZoneIDFilter([]string{}), + zoneTypeFilter: provider.NewZoneTypeFilter(""), + zoneTagFilter: provider.NewZoneTagFilter([]string{}), + zonesCache: &zonesListCache{duration: 1 * time.Second}, + } + for _, o := range options { + o(p) + } + return p } func WithDomainFilters(filters ...string) func(awsProvider *AWSProvider) { - return func(awsProvider *AWSProvider) { - awsProvider.domainFilter = endpoint.NewDomainFilter(filters) - } + return func(awsProvider *AWSProvider) { + awsProvider.domainFilter = endpoint.NewDomainFilter(filters) + } } func WithZoneIDFilters(filters ...string) func(awsProvider *AWSProvider) { - return func(awsProvider *AWSProvider) { - awsProvider.zoneIDFilter = provider.NewZoneIDFilter(filters) - } + return func(awsProvider *AWSProvider) { + awsProvider.zoneIDFilter = provider.NewZoneIDFilter(filters) + } } func WithZoneTagFilters(filters []string) func(awsProvider *AWSProvider) { - return func(awsProvider *AWSProvider) { - awsProvider.zoneTagFilter = provider.NewZoneTagFilter(filters) - } + return func(awsProvider *AWSProvider) { + awsProvider.zoneTagFilter = provider.NewZoneTagFilter(filters) + } } func NewRoute53APIFixtureStub(zones *HostedZones) *Route53APIFixtureStub { - route53Zones := make(map[string]*route53types.HostedZone) - zoneTags := make(map[string][]route53types.Tag) - for _, zone := range zones.Zones { - route53Zones[zone.ID] = &route53types.HostedZone{ - Id: &zone.ID, - Name: &zone.Name, - } - zoneTags[cleanZoneID(zone.ID)] = zone.Tags - } - return &Route53APIFixtureStub{ - zones: route53Zones, - zoneTags: zoneTags, - calls: make(map[string]int), - } + route53Zones := make(map[string]*route53types.HostedZone) + zoneTags := make(map[string][]route53types.Tag) + for _, zone := range zones.Zones { + route53Zones[zone.ID] = &route53types.HostedZone{ + Id: &zone.ID, + Name: &zone.Name, + } + zoneTags[cleanZoneID(zone.ID)] = zone.Tags + } + return &Route53APIFixtureStub{ + zones: route53Zones, + zoneTags: zoneTags, + calls: make(map[string]int), + } } func (r Route53APIFixtureStub) ListResourceRecordSets(ctx context.Context, input *route53.ListResourceRecordSetsInput, optFns ...func(options *route53.Options)) (*route53.ListResourceRecordSetsOutput, error) { - // TODO implement me - panic("implement me") + // TODO implement me + panic("implement me") } func (r Route53APIFixtureStub) ChangeResourceRecordSets(ctx context.Context, input *route53.ChangeResourceRecordSetsInput, optFns ...func(options *route53.Options)) (*route53.ChangeResourceRecordSetsOutput, error) { - // TODO implement me - panic("implement me") + // TODO implement me + panic("implement me") } func (r Route53APIFixtureStub) CreateHostedZone(ctx context.Context, input *route53.CreateHostedZoneInput, optFns ...func(*route53.Options)) (*route53.CreateHostedZoneOutput, error) { - // TODO implement me - panic("implement me") + // TODO implement me + panic("implement me") } func (r Route53APIFixtureStub) ListHostedZones(ctx context.Context, input *route53.ListHostedZonesInput, optFns ...func(options *route53.Options)) (*route53.ListHostedZonesOutput, error) { - r.calls["listhostedzones"]++ - output := &route53.ListHostedZonesOutput{} - for _, zone := range r.zones { - output.HostedZones = append(output.HostedZones, *zone) - } - return output, nil + r.calls["listhostedzones"]++ + output := &route53.ListHostedZonesOutput{} + for _, zone := range r.zones { + output.HostedZones = append(output.HostedZones, *zone) + } + return output, nil } func (r Route53APIFixtureStub) ListTagsForResource(ctx context.Context, input *route53.ListTagsForResourceInput, optFns ...func(options *route53.Options)) (*route53.ListTagsForResourceOutput, error) { - r.calls["listtagsforresource"]++ - tags := r.zoneTags[*input.ResourceId] - return &route53.ListTagsForResourceOutput{ - ResourceTagSet: &route53types.ResourceTagSet{ - ResourceId: input.ResourceId, - ResourceType: input.ResourceType, - Tags: tags, - }, - }, nil + r.calls["listtagsforresource"]++ + tags := r.zoneTags[*input.ResourceId] + return &route53.ListTagsForResourceOutput{ + ResourceTagSet: &route53types.ResourceTagSet{ + ResourceId: input.ResourceId, + ResourceType: input.ResourceType, + Tags: tags, + }, + }, nil } func unmarshalTestHelper(input string, obj any, t *testing.T) { - t.Helper() - path, _ := os.Getwd() - file, err := os.Open(path + input) - assert.NoError(t, err) - defer file.Close() - dec := yaml.NewDecoder(file) - err = dec.Decode(obj) - assert.NoError(t, err) + t.Helper() + path, _ := os.Getwd() + file, err := os.Open(path + input) + assert.NoError(t, err) + defer file.Close() + dec := yaml.NewDecoder(file) + err = dec.Decode(obj) + assert.NoError(t, err) } diff --git a/source/contour_httpproxy_test.go b/source/contour_httpproxy_test.go index f26d2b0292..895adeaa01 100644 --- a/source/contour_httpproxy_test.go +++ b/source/contour_httpproxy_test.go @@ -1145,7 +1145,7 @@ func (ir fakeHTTPProxy) HTTPProxy() *projectcontour.HTTPProxy { }, Spec: spec, Status: projectcontour.HTTPProxyStatus{ - LoadBalancer: lb, + LoadBalancer: lb, }, }