diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml index e46b77a06362..f5c69841abef 100644 --- a/.github/workflows/pr-checks.yml +++ b/.github/workflows/pr-checks.yml @@ -27,21 +27,22 @@ jobs: git diff --exit-code go.mod git diff --exit-code go.sum + # This check is disabled because of GitHub API instability: 504 Gateway Timeout. # Checks: GitHub action assets - check-generated: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - uses: actions/setup-go@v5 - with: - go-version: ${{ env.GO_VERSION }} - - name: Check generated files are up-to-date - run: make fast_check_generated - env: - # needed for github-action-config.json generation - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} +# check-generated: +# runs-on: ubuntu-latest +# steps: +# - uses: actions/checkout@v4 +# with: +# fetch-depth: 0 +# - uses: actions/setup-go@v5 +# with: +# go-version: ${{ env.GO_VERSION }} +# - name: Check generated files are up-to-date +# run: make fast_check_generated +# env: +# # needed for github-action-config.json generation +# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} check-local-install-script: name: Installation script (local) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08b729267d2c..b2b57f004361 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,16 @@ If you value it, consider supporting us, we appreciate it! ❤️ ### v2.1.2 +1. Linters bug fixes + * `fatcontext`: from 0.7.2 to 0.8.0 +2. Misc. + * migration: fix `nakedret.max-func-lines: 0` + * migration: fix order of `staticcheck` settings + * fix: add `go.mod` hash to the cache salt + * fix: use diagnostic position for related information position + +### v2.1.2 + 1. Linters bug fixes * `exptostd`: from 0.4.2 to 0.4.3 * `gofumpt`: from 0.7.0 to 0.8.0 diff --git a/assets/github-action-config-v2.json b/assets/github-action-config-v2.json index 470995520d2c..4ec367aa9ef7 100644 --- a/assets/github-action-config-v2.json +++ b/assets/github-action-config-v2.json @@ -1,7 +1,7 @@ { "MinorVersionToConfig": { "latest": { - "TargetVersion": "v2.1.1" + "TargetVersion": "v2.1.2" }, "v1.10": { "Error": "golangci-lint version 'v1.10' isn't supported: we support only v2.0.0 and later versions" @@ -193,7 +193,7 @@ "TargetVersion": "v2.0.2" }, "v2.1": { - "TargetVersion": "v2.1.1" + "TargetVersion": "v2.1.2" } } } diff --git a/docs/src/docs/welcome/integrations.mdx b/docs/src/docs/welcome/integrations.mdx index 8658e2aa3f5c..747b7ee29e2d 100644 --- a/docs/src/docs/welcome/integrations.mdx +++ b/docs/src/docs/welcome/integrations.mdx @@ -6,9 +6,10 @@ title: Integrations ### GoLand -The integration for golangci-lint v2 is currently in work in progress: [GO-18363](https://youtrack.jetbrains.com/issue/GO-18363/Go-Linter-plugin-fails-with-golangci-lint-v2). +Starting from version 2025.1, GoLand has built-in support of golangci-lint. +For IntelliJ IDEA with the Go plugin, please install the [plugin](https://plugins.jetbrains.com/plugin/12496-go-linter). -Install [plugin](https://plugins.jetbrains.com/plugin/12496-go-linter). +Both v1 and v2 versions are supported. ### Visual Studio Code diff --git a/go.mod b/go.mod index 00695fdf37ad..a8835e203561 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,6 @@ require ( github.com/Antonboom/nilnil v1.1.0 github.com/Antonboom/testifylint v1.6.1 github.com/BurntSushi/toml v1.5.0 - github.com/Crocmagnon/fatcontext v0.7.2 github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.1 github.com/OpenPeeDeeP/depguard/v2 v2.2.1 @@ -127,6 +126,7 @@ require ( gitlab.com/bosi/decorder v0.4.2 go-simpler.org/musttag v0.13.0 go-simpler.org/sloglint v0.11.0 + go.augendre.info/fatcontext v0.8.0 go.uber.org/automaxprocs v1.6.0 golang.org/x/mod v0.24.0 golang.org/x/sys v0.32.0 diff --git a/go.sum b/go.sum index 9bc80fb7cd9b..ff028d1c4652 100644 --- a/go.sum +++ b/go.sum @@ -49,8 +49,6 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/Crocmagnon/fatcontext v0.7.2 h1:BY5/dUhs2kuD3sDn7vZrgOneRib5EHk9GOiyK8Vg+14= -github.com/Crocmagnon/fatcontext v0.7.2/go.mod h1:OAZCUteH59eiddbJZ9/bF4ppC140jYD/hepU2FDkFk4= github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM= github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.1 h1:Sz1JIXEcSfhz7fUi7xHnhpIE0thVASYjvosApmHuD2k= @@ -630,6 +628,8 @@ go-simpler.org/musttag v0.13.0 h1:Q/YAW0AHvaoaIbsPj3bvEI5/QFP7w696IMUpnKXQfCE= go-simpler.org/musttag v0.13.0/go.mod h1:FTzIGeK6OkKlUDVpj0iQUXZLUO1Js9+mvykDQy9C5yM= go-simpler.org/sloglint v0.11.0 h1:JlR1X4jkbeaffiyjLtymeqmGDKBDO1ikC6rjiuFAOco= go-simpler.org/sloglint v0.11.0/go.mod h1:CFDO8R1i77dlciGfPEPvYke2ZMx4eyGiEIWkyeW2Pvw= +go.augendre.info/fatcontext v0.8.0 h1:2dfk6CQbDGeu1YocF59Za5Pia7ULeAM6friJ3LP7lmk= +go.augendre.info/fatcontext v0.8.0/go.mod h1:oVJfMgwngMsHO+KB2MdgzcO+RvtNdiCEOlWvSFtax/s= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= diff --git a/pkg/commands/internal/migrate/cloner/cloner.go b/pkg/commands/internal/migrate/cloner/cloner.go index 9c2400bc69b1..9a94aaf8e070 100644 --- a/pkg/commands/internal/migrate/cloner/cloner.go +++ b/pkg/commands/internal/migrate/cloner/cloner.go @@ -142,7 +142,7 @@ func convertType(expr ast.Expr) ast.Expr { } switch ident.Name { - case "bool", "string", "int", "int8", "int16", "int32", "int64", "float32", "float64": + case "bool", "string", "uint", "uint8", "uint16", "uint32", "uint64", "int", "int8", "int16", "int32", "int64", "float32", "float64": return &ast.StarExpr{X: ident} default: diff --git a/pkg/commands/internal/migrate/migrate_linters_settings.go b/pkg/commands/internal/migrate/migrate_linters_settings.go index a0559388d403..5accd9f593e5 100644 --- a/pkg/commands/internal/migrate/migrate_linters_settings.go +++ b/pkg/commands/internal/migrate/migrate_linters_settings.go @@ -789,10 +789,32 @@ func toSpancheckSettings(old versionone.SpancheckSettings) versiontwo.SpancheckS } func toStaticCheckSettings(old versionone.LintersSettings) versiontwo.StaticCheckSettings { - checks := slices.Concat(old.Staticcheck.Checks, old.Stylecheck.Checks, old.Gosimple.Checks) + var checks []string + + for _, check := range slices.Concat(old.Staticcheck.Checks, old.Stylecheck.Checks, old.Gosimple.Checks) { + if check == "*" { + checks = append(checks, "all") + continue + } + checks = append(checks, check) + } + + checks = Unique(checks) + + slices.SortFunc(checks, func(a, b string) int { + if a == "all" { + return -1 + } + + if b == "all" { + return 1 + } + + return strings.Compare(a, b) + }) return versiontwo.StaticCheckSettings{ - Checks: Unique(checks), + Checks: checks, Initialisms: old.Stylecheck.Initialisms, DotImportWhitelist: old.Stylecheck.DotImportWhitelist, HTTPStatusCodeWhitelist: old.Stylecheck.HTTPStatusCodeWhitelist, diff --git a/pkg/commands/internal/migrate/testdata/yaml/linters-settings_nakedret_zero.golden.yml b/pkg/commands/internal/migrate/testdata/yaml/linters-settings_nakedret_zero.golden.yml new file mode 100644 index 000000000000..69e5a3b11394 --- /dev/null +++ b/pkg/commands/internal/migrate/testdata/yaml/linters-settings_nakedret_zero.golden.yml @@ -0,0 +1,6 @@ +version: "2" + +linters: + settings: + nakedret: + max-func-lines: 0 diff --git a/pkg/commands/internal/migrate/testdata/yaml/linters-settings_nakedret_zero.yml b/pkg/commands/internal/migrate/testdata/yaml/linters-settings_nakedret_zero.yml new file mode 100644 index 000000000000..c15f3c7bab1a --- /dev/null +++ b/pkg/commands/internal/migrate/testdata/yaml/linters-settings_nakedret_zero.yml @@ -0,0 +1,11 @@ +issues: + # Only to not generate unrelated elements inside golden. + exclude-use-default: false + # Only to not generate unrelated elements inside golden. + exclude-generated: strict + # Only to not generate unrelated elements inside golden. + exclude-dirs-use-default: false + +linters-settings: + nakedret: + max-func-lines: 0 diff --git a/pkg/commands/internal/migrate/testdata/yaml/linters-settings_staticcheck_merge.golden.yml b/pkg/commands/internal/migrate/testdata/yaml/linters-settings_staticcheck_merge.golden.yml new file mode 100644 index 000000000000..229a095f01f8 --- /dev/null +++ b/pkg/commands/internal/migrate/testdata/yaml/linters-settings_staticcheck_merge.golden.yml @@ -0,0 +1,204 @@ +version: "2" +linters: + settings: + staticcheck: + checks: + - all + - -S1000 + - -S1001 + - -S1002 + - -SA1000 + - -SA1001 + - -SA1002 + - -ST1000 + - -ST1001 + - -ST1003 + - S1003 + - S1004 + - S1005 + - S1006 + - S1007 + - S1008 + - S1009 + - S1010 + - S1011 + - S1012 + - S1016 + - S1017 + - S1018 + - S1019 + - S1020 + - S1021 + - S1023 + - S1024 + - S1025 + - S1028 + - S1029 + - S1030 + - S1031 + - S1032 + - S1033 + - S1034 + - S1035 + - S1036 + - S1037 + - S1038 + - S1039 + - S1040 + - SA1003 + - SA1004 + - SA1005 + - SA1006 + - SA1007 + - SA1008 + - SA1010 + - SA1011 + - SA1012 + - SA1013 + - SA1014 + - SA1015 + - SA1016 + - SA1017 + - SA1018 + - SA1019 + - SA1020 + - SA1021 + - SA1023 + - SA1024 + - SA1025 + - SA1026 + - SA1027 + - SA1028 + - SA1029 + - SA1030 + - SA1031 + - SA1032 + - SA2000 + - SA2001 + - SA2002 + - SA2003 + - SA3000 + - SA3001 + - SA4000 + - SA4001 + - SA4003 + - SA4004 + - SA4005 + - SA4006 + - SA4008 + - SA4009 + - SA4010 + - SA4011 + - SA4012 + - SA4013 + - SA4014 + - SA4015 + - SA4016 + - SA4017 + - SA4018 + - SA4019 + - SA4020 + - SA4021 + - SA4022 + - SA4023 + - SA4024 + - SA4025 + - SA4026 + - SA4027 + - SA4028 + - SA4029 + - SA4030 + - SA4031 + - SA4032 + - SA5000 + - SA5001 + - SA5002 + - SA5003 + - SA5004 + - SA5005 + - SA5007 + - SA5008 + - SA5009 + - SA5010 + - SA5011 + - SA5012 + - SA6000 + - SA6001 + - SA6002 + - SA6003 + - SA6005 + - SA6006 + - SA9001 + - SA9002 + - SA9003 + - SA9004 + - SA9005 + - SA9006 + - SA9007 + - SA9008 + - SA9009 + - ST1005 + - ST1006 + - ST1008 + - ST1011 + - ST1012 + - ST1013 + - ST1015 + - ST1016 + - ST1017 + - ST1018 + - ST1019 + - ST1020 + - ST1021 + - ST1022 + - ST1023 + initialisms: + - ACL + - API + - ASCII + - CPU + - CSS + - DNS + - EOF + - GUID + - HTML + - HTTP + - HTTPS + - ID + - IP + - JSON + - QPS + - RAM + - RPC + - SLA + - SMTP + - SQL + - SSH + - TCP + - TLS + - TTL + - UDP + - UI + - GID + - UID + - UUID + - URI + - URL + - UTF8 + - VM + - XML + - XMPP + - XSRF + - XSS + - SIP + - RTP + - AMQP + - DB + - TS + dot-import-whitelist: + - fmt + http-status-code-whitelist: + - "200" + - "400" + - "404" + - "500" diff --git a/pkg/commands/internal/migrate/testdata/yaml/linters-settings_staticcheck_merge.yml b/pkg/commands/internal/migrate/testdata/yaml/linters-settings_staticcheck_merge.yml new file mode 100644 index 000000000000..3d9fe3cbbfc0 --- /dev/null +++ b/pkg/commands/internal/migrate/testdata/yaml/linters-settings_staticcheck_merge.yml @@ -0,0 +1,172 @@ +issues: + # Only to not generate unrelated elements inside golden. + exclude-use-default: false + # Only to not generate unrelated elements inside golden. + exclude-generated: strict + # Only to not generate unrelated elements inside golden. + exclude-dirs-use-default: false + +linters-settings: + staticcheck: + checks: + - all + - '-SA1000' + - '-SA1001' + - '-SA1002' + - SA1003 + - SA1004 + - SA1005 + - SA1006 + - SA1007 + - SA1008 + - SA1010 + - SA1011 + - SA1012 + - SA1013 + - SA1014 + - SA1015 + - SA1016 + - SA1017 + - SA1018 + - SA1019 + - SA1020 + - SA1021 + - SA1023 + - SA1024 + - SA1025 + - SA1026 + - SA1027 + - SA1028 + - SA1029 + - SA1030 + - SA1031 + - SA1032 + - SA2000 + - SA2001 + - SA2002 + - SA2003 + - SA3000 + - SA3001 + - SA4000 + - SA4001 + - SA4003 + - SA4004 + - SA4005 + - SA4006 + - SA4008 + - SA4009 + - SA4010 + - SA4011 + - SA4012 + - SA4013 + - SA4014 + - SA4015 + - SA4016 + - SA4017 + - SA4018 + - SA4019 + - SA4020 + - SA4021 + - SA4022 + - SA4023 + - SA4024 + - SA4025 + - SA4026 + - SA4027 + - SA4028 + - SA4029 + - SA4030 + - SA4031 + - SA4032 + - SA5000 + - SA5001 + - SA5002 + - SA5003 + - SA5004 + - SA5005 + - SA5007 + - SA5008 + - SA5009 + - SA5010 + - SA5011 + - SA5012 + - SA6000 + - SA6001 + - SA6002 + - SA6003 + - SA6005 + - SA6006 + - SA9001 + - SA9002 + - SA9003 + - SA9004 + - SA9005 + - SA9006 + - SA9007 + - SA9008 + - SA9009 + + gosimple: + checks: + - '*' + - '-S1000' + - '-S1001' + - '-S1002' + - S1003 + - S1004 + - S1005 + - S1006 + - S1007 + - S1008 + - S1009 + - S1010 + - S1011 + - S1012 + - S1016 + - S1017 + - S1018 + - S1019 + - S1020 + - S1021 + - S1023 + - S1024 + - S1025 + - S1028 + - S1029 + - S1030 + - S1031 + - S1032 + - S1033 + - S1034 + - S1035 + - S1036 + - S1037 + - S1038 + - S1039 + - S1040 + + stylecheck: + dot-import-whitelist: + - fmt + initialisms: [ "ACL", "API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "QPS", "RAM", "RPC", "SLA", "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", "UDP", "UI", "GID", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS", "SIP", "RTP", "AMQP", "DB", "TS" ] + http-status-code-whitelist: [ "200", "400", "404", "500" ] + checks: + - all + - '-ST1000' + - '-ST1001' + - '-ST1003' + - ST1005 + - ST1006 + - ST1008 + - ST1011 + - ST1012 + - ST1013 + - ST1015 + - ST1016 + - ST1017 + - ST1018 + - ST1019 + - ST1020 + - ST1021 + - ST1022 + - ST1023 diff --git a/pkg/commands/internal/migrate/versionone/linters_settings.go b/pkg/commands/internal/migrate/versionone/linters_settings.go index 49427c447530..44583b7d34e0 100644 --- a/pkg/commands/internal/migrate/versionone/linters_settings.go +++ b/pkg/commands/internal/migrate/versionone/linters_settings.go @@ -489,7 +489,7 @@ type MustTagSettings struct { } type NakedretSettings struct { - MaxFuncLines uint `mapstructure:"max-func-lines"` + MaxFuncLines *uint `mapstructure:"max-func-lines"` } type NestifSettings struct { diff --git a/pkg/commands/internal/migrate/versiontwo/formatters.go b/pkg/commands/internal/migrate/versiontwo/formatters.go index bd1b6f931155..417714947a69 100644 --- a/pkg/commands/internal/migrate/versiontwo/formatters.go +++ b/pkg/commands/internal/migrate/versiontwo/formatters.go @@ -9,6 +9,7 @@ type Formatters struct { } type FormatterExclusions struct { - Generated *string `yaml:"generated,omitempty" toml:"generated,multiline,omitempty"` - Paths []string `yaml:"paths,omitempty" toml:"paths,multiline,omitempty"` + Generated *string `yaml:"generated,omitempty" toml:"generated,multiline,omitempty"` + Paths []string `yaml:"paths,omitempty" toml:"paths,multiline,omitempty"` + WarnUnused *bool `yaml:"warn-unused,omitempty" toml:"warn-unused,multiline,omitempty"` } diff --git a/pkg/commands/internal/migrate/versiontwo/linters_settings.go b/pkg/commands/internal/migrate/versiontwo/linters_settings.go index 3461620e20f7..3a0d6b7b6a2a 100644 --- a/pkg/commands/internal/migrate/versiontwo/linters_settings.go +++ b/pkg/commands/internal/migrate/versiontwo/linters_settings.go @@ -21,6 +21,7 @@ type LintersSettings struct { Exhaustruct ExhaustructSettings `yaml:"exhaustruct,omitempty" toml:"exhaustruct,multiline,omitempty"` Fatcontext FatcontextSettings `yaml:"fatcontext,omitempty" toml:"fatcontext,multiline,omitempty"` Forbidigo ForbidigoSettings `yaml:"forbidigo,omitempty" toml:"forbidigo,multiline,omitempty"` + FuncOrder FuncOrderSettings `yaml:"funcorder,omitempty" toml:"funcorder,multiline,omitempty"` Funlen FunlenSettings `yaml:"funlen,omitempty" toml:"funlen,multiline,omitempty"` GinkgoLinter GinkgoLinterSettings `yaml:"ginkgolinter,omitempty" toml:"ginkgolinter,multiline,omitempty"` Gocognit GocognitSettings `yaml:"gocognit,omitempty" toml:"gocognit,multiline,omitempty"` @@ -210,6 +211,11 @@ type ForbidigoPattern struct { Msg *string `yaml:"msg,omitempty,omitempty" toml:"msg,omitempty,multiline,omitempty"` } +type FuncOrderSettings struct { + Constructor *bool `yaml:"constructor,omitempty,omitempty" toml:"constructor,omitempty,multiline,omitempty"` + StructMethod *bool `yaml:"struct-method,omitempty,omitempty" toml:"struct-method,omitempty,multiline,omitempty"` +} + type FunlenSettings struct { Lines *int `yaml:"lines,omitempty" toml:"lines,multiline,omitempty"` Statements *int `yaml:"statements,omitempty" toml:"statements,multiline,omitempty"` @@ -241,14 +247,18 @@ type GocognitSettings struct { } type GoConstSettings struct { - IgnoreStrings *string `yaml:"ignore-strings,omitempty" toml:"ignore-strings,multiline,omitempty"` - MatchWithConstants *bool `yaml:"match-constant,omitempty" toml:"match-constant,multiline,omitempty"` - MinStringLen *int `yaml:"min-len,omitempty" toml:"min-len,multiline,omitempty"` - MinOccurrencesCount *int `yaml:"min-occurrences,omitempty" toml:"min-occurrences,multiline,omitempty"` - ParseNumbers *bool `yaml:"numbers,omitempty" toml:"numbers,multiline,omitempty"` - NumberMin *int `yaml:"min,omitempty" toml:"min,multiline,omitempty"` - NumberMax *int `yaml:"max,omitempty" toml:"max,multiline,omitempty"` - IgnoreCalls *bool `yaml:"ignore-calls,omitempty" toml:"ignore-calls,multiline,omitempty"` + IgnoreStringValues []string `yaml:"ignore-string-values,omitempty" toml:"ignore-string-values,multiline,omitempty"` + MatchWithConstants *bool `yaml:"match-constant,omitempty" toml:"match-constant,multiline,omitempty"` + MinStringLen *int `yaml:"min-len,omitempty" toml:"min-len,multiline,omitempty"` + MinOccurrencesCount *int `yaml:"min-occurrences,omitempty" toml:"min-occurrences,multiline,omitempty"` + ParseNumbers *bool `yaml:"numbers,omitempty" toml:"numbers,multiline,omitempty"` + NumberMin *int `yaml:"min,omitempty" toml:"min,multiline,omitempty"` + NumberMax *int `yaml:"max,omitempty" toml:"max,multiline,omitempty"` + IgnoreCalls *bool `yaml:"ignore-calls,omitempty" toml:"ignore-calls,multiline,omitempty"` + FindDuplicates *bool `yaml:"find-duplicates,omitempty" toml:"find-duplicates,multiline,omitempty"` + EvalConstExpressions *bool `yaml:"eval-const-expressions,omitempty" toml:"eval-const-expressions,multiline,omitempty"` + + IgnoreStrings *string `yaml:"ignore-strings,omitempty" toml:"ignore-strings,multiline,omitempty"` } type GoCriticSettings struct { @@ -436,7 +446,7 @@ type MustTagFunction struct { } type NakedretSettings struct { - MaxFuncLines uint `yaml:"max-func-lines,omitempty" toml:"max-func-lines,multiline,omitempty"` + MaxFuncLines *uint `yaml:"max-func-lines,omitempty" toml:"max-func-lines,multiline,omitempty"` } type NestifSettings struct { @@ -444,6 +454,7 @@ type NestifSettings struct { } type NilNilSettings struct { + OnlyTwo *bool `yaml:"only-two,omitempty" toml:"only-two,multiline,omitempty"` DetectOpposite *bool `yaml:"detect-opposite,omitempty" toml:"detect-opposite,multiline,omitempty"` CheckedTypes []string `yaml:"checked-types,omitempty" toml:"checked-types,multiline,omitempty"` } @@ -560,6 +571,7 @@ type SlogLintSettings struct { NoGlobal *string `yaml:"no-global,omitempty" toml:"no-global,multiline,omitempty"` Context *string `yaml:"context,omitempty" toml:"context,multiline,omitempty"` StaticMsg *bool `yaml:"static-msg,omitempty" toml:"static-msg,multiline,omitempty"` + MsgStyle *string `yaml:"msg-style,omitempty" toml:"msg-style,multiline,omitempty"` NoRawKeys *bool `yaml:"no-raw-keys,omitempty" toml:"no-raw-keys,multiline,omitempty"` KeyNamingCase *string `yaml:"key-naming-case,omitempty" toml:"key-naming-case,multiline,omitempty"` ForbiddenKeys []string `yaml:"forbidden-keys,omitempty" toml:"forbidden-keys,multiline,omitempty"` @@ -639,6 +651,7 @@ type TestifylintExpectedActual struct { type TestifylintFormatter struct { CheckFormatString *bool `yaml:"check-format-string,omitempty" toml:"check-format-string,multiline,omitempty"` RequireFFuncs *bool `yaml:"require-f-funcs,omitempty" toml:"require-f-funcs,multiline,omitempty"` + RequireStringMsg *bool `yaml:"require-string-msg,omitempty" toml:"require-string-msg,multiline,omitempty"` } type TestifylintGoRequire struct { @@ -736,6 +749,7 @@ type WrapcheckSettings struct { IgnoreSigRegexps []string `yaml:"ignore-sig-regexps,omitempty" toml:"ignore-sig-regexps,multiline,omitempty"` IgnorePackageGlobs []string `yaml:"ignore-package-globs,omitempty" toml:"ignore-package-globs,multiline,omitempty"` IgnoreInterfaceRegexps []string `yaml:"ignore-interface-regexps,omitempty" toml:"ignore-interface-regexps,multiline,omitempty"` + ReportInternalErrors *bool `yaml:"report-internal-errors,omitempty" toml:"report-internal-errors,multiline,omitempty"` } type WSLSettings struct { diff --git a/pkg/commands/internal/migrate/versiontwo/output.go b/pkg/commands/internal/migrate/versiontwo/output.go index ed6bab7e375d..16afb6701eef 100644 --- a/pkg/commands/internal/migrate/versiontwo/output.go +++ b/pkg/commands/internal/migrate/versiontwo/output.go @@ -5,6 +5,7 @@ package versiontwo type Output struct { Formats Formats `yaml:"formats,omitempty" toml:"formats,multiline,omitempty"` SortOrder []string `yaml:"sort-order,omitempty" toml:"sort-order,multiline,omitempty"` - PathPrefix *string `yaml:"path-prefix,omitempty" toml:"path-prefix,multiline,omitempty"` ShowStats *bool `yaml:"show-stats,omitempty" toml:"show-stats,multiline,omitempty"` + PathPrefix *string `yaml:"path-prefix,omitempty" toml:"path-prefix,multiline,omitempty"` + PathMode *string `yaml:"path-mode,omitempty" toml:"path-mode,multiline,omitempty"` } diff --git a/pkg/commands/run.go b/pkg/commands/run.go index a3e9df6de3fc..53902eafac24 100644 --- a/pkg/commands/run.go +++ b/pkg/commands/run.go @@ -21,10 +21,12 @@ import ( "github.com/fatih/color" "github.com/gofrs/flock" + "github.com/ldez/grignotin/goenv" "github.com/spf13/cobra" "github.com/spf13/pflag" "github.com/spf13/viper" "go.uber.org/automaxprocs/maxprocs" + "golang.org/x/mod/sumdb/dirhash" "gopkg.in/yaml.v3" "github.com/golangci/golangci-lint/v2/internal/cache" @@ -216,7 +218,7 @@ func (c *runCommand) preRunE(_ *cobra.Command, args []string) error { c.contextBuilder = lint.NewContextBuilder(c.cfg, pkgLoader, pkgCache, guard) - if err = initHashSalt(c.buildInfo.Version, c.cfg); err != nil { + if err = initHashSalt(c.log.Child(logutils.DebugKeyGoModSalt), c.buildInfo.Version, c.cfg); err != nil { return fmt.Errorf("failed to init hash salt: %w", err) } @@ -618,7 +620,7 @@ func formatMemory(memBytes uint64) string { // Related to cache. -func initHashSalt(version string, cfg *config.Config) error { +func initHashSalt(logger logutils.Log, version string, cfg *config.Config) error { binSalt, err := computeBinarySalt(version) if err != nil { return fmt.Errorf("failed to calculate binary salt: %w", err) @@ -629,9 +631,18 @@ func initHashSalt(version string, cfg *config.Config) error { return fmt.Errorf("failed to calculate config salt: %w", err) } + goModSalt, err := computeGoModSalt() + if err != nil { + // NOTE: missing go.mod must be ignored. + logger.Warnf("Failed to calculate go.mod salt: %v", err) + } + b := bytes.NewBuffer(binSalt) b.Write(configSalt) + b.WriteString(goModSalt) + cache.SetSalt(b) + return nil } @@ -648,15 +659,19 @@ func computeBinarySalt(version string) ([]byte, error) { if err != nil { return nil, err } + f, err := os.Open(p) if err != nil { return nil, err } + defer f.Close() + h := sha256.New() if _, err := io.Copy(h, f); err != nil { return nil, err } + return h.Sum(nil), nil } @@ -678,5 +693,29 @@ func computeConfigSalt(cfg *config.Config) ([]byte, error) { if _, err := h.Write(configData.Bytes()); err != nil { return nil, err } + return h.Sum(nil), nil } + +func computeGoModSalt() (string, error) { + values, err := goenv.Get(context.Background(), goenv.GOMOD) + if err != nil { + return "", fmt.Errorf("failed to get goenv: %w", err) + } + + goModPath := filepath.Clean(values[goenv.GOMOD]) + + data, err := os.ReadFile(goModPath) + if err != nil { + return "", fmt.Errorf("failed to read go.mod: %w", err) + } + + sum, err := dirhash.Hash1([]string{goModPath}, func(string) (io.ReadCloser, error) { + return io.NopCloser(bytes.NewReader(data)), nil + }) + if err != nil { + return "", fmt.Errorf("failed to compute go.sum: %w", err) + } + + return sum, nil +} diff --git a/pkg/config/config.go b/pkg/config/config.go index a6236a23f3af..6d7586621d8b 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -13,6 +13,8 @@ import ( "github.com/ldez/grignotin/goenv" "github.com/ldez/grignotin/gomod" "golang.org/x/mod/modfile" + + "github.com/golangci/golangci-lint/v2/pkg/logutils" ) // defaultGoVersion the value should be "oldstable" - 1. @@ -102,8 +104,8 @@ func IsGoGreaterThanOrEqual(current, limit string) bool { return v1.GreaterThanOrEqual(l) } -func detectGoVersion(ctx context.Context) string { - return cmp.Or(detectGoVersionFromGoMod(ctx), defaultGoVersion) +func detectGoVersion(ctx context.Context, log logutils.Log) string { + return cmp.Or(detectGoVersionFromGoMod(ctx, log), defaultGoVersion) } // detectGoVersionFromGoMod tries to get Go version from go.mod. @@ -111,7 +113,7 @@ func detectGoVersion(ctx context.Context) string { // else it returns `go` version if present, // else it returns `GOVERSION` version if present, // else it returns empty. -func detectGoVersionFromGoMod(ctx context.Context) string { +func detectGoVersionFromGoMod(ctx context.Context, log logutils.Log) string { values, err := goenv.Get(ctx, goenv.GOMOD, goenv.GOVERSION) if err != nil { values = map[string]string{ @@ -128,6 +130,10 @@ func detectGoVersionFromGoMod(ctx context.Context) string { return parseGoVersion(values[goenv.GOVERSION]) } + if file.Module != nil { + log.Infof("Module name %q", file.Module.Mod.Path) + } + // The toolchain exists only if 'toolchain' version > 'go' version. // If 'toolchain' version <= 'go' version, `go mod tidy` will remove 'toolchain' version from go.mod. if file.Toolchain != nil && file.Toolchain.Name != "" { diff --git a/pkg/config/loader.go b/pkg/config/loader.go index 19a17e7d71db..3ff9306486ab 100644 --- a/pkg/config/loader.go +++ b/pkg/config/loader.go @@ -161,7 +161,7 @@ func (l *Loader) checkConfigurationVersion() error { func (l *Loader) handleGoVersion() { if l.cfg.Run.Go == "" { - l.cfg.Run.Go = detectGoVersion(context.Background()) + l.cfg.Run.Go = detectGoVersion(context.Background(), l.log) } l.cfg.Linters.Settings.Govet.Go = l.cfg.Run.Go diff --git a/pkg/goanalysis/runners.go b/pkg/goanalysis/runners.go index 5ffc1529363b..fe8d8fe854d3 100644 --- a/pkg/goanalysis/runners.go +++ b/pkg/goanalysis/runners.go @@ -136,10 +136,16 @@ func buildIssues(diags []Diagnostic, linterNameBuilder func(diag *Diagnostic) st if len(diag.Related) > 0 { for _, info := range diag.Related { + relatedPos := diag.Pkg.Fset.Position(info.Pos) + + if relatedPos.Filename != diag.Position.Filename { + relatedPos = diag.Position + } + issues = append(issues, result.Issue{ FromLinter: linterName, Text: fmt.Sprintf("%s(related information): %s", diag.Analyzer.Name, info.Message), - Pos: diag.Pkg.Fset.Position(info.Pos), + Pos: relatedPos, Pkg: diag.Pkg, }) } diff --git a/pkg/golinters/fatcontext/fatcontext.go b/pkg/golinters/fatcontext/fatcontext.go index 8f34064dc057..e0506259bee9 100644 --- a/pkg/golinters/fatcontext/fatcontext.go +++ b/pkg/golinters/fatcontext/fatcontext.go @@ -1,7 +1,7 @@ package fatcontext import ( - "github.com/Crocmagnon/fatcontext/pkg/analyzer" + "go.augendre.info/fatcontext/pkg/analyzer" "golang.org/x/tools/go/analysis" "github.com/golangci/golangci-lint/v2/pkg/config" diff --git a/pkg/logutils/logutils.go b/pkg/logutils/logutils.go index 2fbb4a7b2493..0ee48a3664bd 100644 --- a/pkg/logutils/logutils.go +++ b/pkg/logutils/logutils.go @@ -17,6 +17,7 @@ const envDebug = "GL_DEBUG" const ( DebugKeyBinSalt = "bin_salt" + DebugKeyGoModSalt = "gomod_salt" DebugKeyConfigReader = "config_reader" DebugKeyEmpty = "" DebugKeyEnabledLinters = "enabled_linters" diff --git a/scripts/website/expand_templates/thanks.go b/scripts/website/expand_templates/thanks.go index 66ee8511c6e8..a3a0035cf60c 100644 --- a/scripts/website/expand_templates/thanks.go +++ b/scripts/website/expand_templates/thanks.go @@ -99,6 +99,9 @@ func extractInfo(lc *linter.Config) authorInfo { case "misspell": return authorInfo{Author: "client9", Host: hostGitHub} + case "fatcontext": + return authorInfo{Author: "Crocmagnon", Host: hostGitHub} + default: if strings.HasPrefix(lc.OriginalURL, "https://pkg.go.dev/") { return authorInfo{Author: "golang", Host: hostGitHub}