From da2eea5c9888b2b3adcade8c4b0657703c91da00 Mon Sep 17 00:00:00 2001 From: voloshina Date: Sat, 2 Aug 2025 13:37:12 +0300 Subject: [PATCH] feat: add linter gocheckerrbeforeuse Signed-off-by: voloshina --- .golangci.next.reference.yml | 8 ++++++ go.mod | 1 + go.sum | 2 ++ jsonschema/golangci.next.jsonschema.json | 1 + pkg/config/linters_settings.go | 5 ++++ .../gocheckerrbeforeuse.go | 13 ++++++++++ .../gocheckerrbeforeuse_test.go | 11 ++++++++ .../gocheckerrbeforeuse/testdata/custom.yml | 6 +++++ .../testdata/gocheckerrbeforeuse.go | 25 +++++++++++++++++++ .../testdata/gocheckerrbeforeuse_custom.go | 17 +++++++++++++ pkg/lint/lintersdb/builder_linter.go | 5 ++++ 11 files changed, 94 insertions(+) create mode 100644 pkg/golinters/gocheckerrbeforeuse/gocheckerrbeforeuse.go create mode 100644 pkg/golinters/gocheckerrbeforeuse/gocheckerrbeforeuse_test.go create mode 100644 pkg/golinters/gocheckerrbeforeuse/testdata/custom.yml create mode 100644 pkg/golinters/gocheckerrbeforeuse/testdata/gocheckerrbeforeuse.go create mode 100644 pkg/golinters/gocheckerrbeforeuse/testdata/gocheckerrbeforeuse_custom.go diff --git a/.golangci.next.reference.yml b/.golangci.next.reference.yml index 44ce5c4a9db8..c4a357b19677 100644 --- a/.golangci.next.reference.yml +++ b/.golangci.next.reference.yml @@ -52,6 +52,7 @@ linters: - funlen - ginkgolinter - gocheckcompilerdirectives + - gocheckerrbeforeuse - gochecknoglobals - gochecknoinits - gochecksumtype @@ -163,6 +164,7 @@ linters: - funlen - ginkgolinter - gocheckcompilerdirectives + - gocheckerrbeforeuse - gochecknoglobals - gochecknoinits - gochecksumtype @@ -657,6 +659,12 @@ linters: # Default: false force-assertion-description: true + gocheckerrbeforeuse: + # Maximum allowable distance between receiving an error and handling it. + # Value must always be greater than or equal to 1. + # Default: 1 + max-allowed-distance: 1 + gochecksumtype: # Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed. # Default: true diff --git a/go.mod b/go.mod index 788c13b6d9f3..f5c17b75b189 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( github.com/BurntSushi/toml v1.5.0 github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 github.com/OpenPeeDeeP/depguard/v2 v2.2.1 + github.com/T-Sh/go-check-err-before-use v1.0.0 github.com/alecthomas/chroma/v2 v2.20.0 github.com/alecthomas/go-check-sumtype v0.3.1 github.com/alexkohler/nakedret/v2 v2.0.6 diff --git a/go.sum b/go.sum index afd7617733b4..bbc395e61630 100644 --- a/go.sum +++ b/go.sum @@ -63,6 +63,8 @@ github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7r github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/OpenPeeDeeP/depguard/v2 v2.2.1 h1:vckeWVESWp6Qog7UZSARNqfu/cZqvki8zsuj3piCMx4= github.com/OpenPeeDeeP/depguard/v2 v2.2.1/go.mod h1:q4DKzC4UcVaAvcfd41CZh0PWpGgzrVxUYBlgKNGquUo= +github.com/T-Sh/go-check-err-before-use v1.0.0 h1:2vDkov9YRHgY5gmstsAZaxDOy1SshdagiRl6tSw7m+c= +github.com/T-Sh/go-check-err-before-use v1.0.0/go.mod h1:CT+c5BL1iXg+h5ZqJ1JK6HqsaZ1RLZP5faj0swvenXc= github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0= github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/chroma/v2 v2.20.0 h1:sfIHpxPyR07/Oylvmcai3X/exDlE8+FA820NTz+9sGw= diff --git a/jsonschema/golangci.next.jsonschema.json b/jsonschema/golangci.next.jsonschema.json index 9221df3feb96..a134f4fb821c 100644 --- a/jsonschema/golangci.next.jsonschema.json +++ b/jsonschema/golangci.next.jsonschema.json @@ -788,6 +788,7 @@ "funlen", "ginkgolinter", "gocheckcompilerdirectives", + "gocheckerrbeforeuse", "gochecknoglobals", "gochecknoinits", "gochecksumtype", diff --git a/pkg/config/linters_settings.go b/pkg/config/linters_settings.go index 567416d977de..6f2989529ad7 100644 --- a/pkg/config/linters_settings.go +++ b/pkg/config/linters_settings.go @@ -238,6 +238,7 @@ type LintersSettings struct { Funlen FunlenSettings `mapstructure:"funlen"` GinkgoLinter GinkgoLinterSettings `mapstructure:"ginkgolinter"` Gocognit GocognitSettings `mapstructure:"gocognit"` + GoCheckErrBeforeUse GoCheckErrBeforeUseSettings `mapstructure:"gocheckerrbeforeuse"` GoChecksumType GoChecksumTypeSettings `mapstructure:"gochecksumtype"` Goconst GoConstSettings `mapstructure:"goconst"` Gocritic GoCriticSettings `mapstructure:"gocritic"` @@ -478,6 +479,10 @@ type GinkgoLinterSettings struct { ForceAssertionDescription bool `mapstructure:"force-assertion-description"` } +type GoCheckErrBeforeUseSettings struct { + MaxAllowedDistance int `mapstructure:"max-allowed-distance"` +} + type GoChecksumTypeSettings struct { DefaultSignifiesExhaustive bool `mapstructure:"default-signifies-exhaustive"` IncludeSharedInterfaces bool `mapstructure:"include-shared-interfaces"` diff --git a/pkg/golinters/gocheckerrbeforeuse/gocheckerrbeforeuse.go b/pkg/golinters/gocheckerrbeforeuse/gocheckerrbeforeuse.go new file mode 100644 index 000000000000..195b5f3da101 --- /dev/null +++ b/pkg/golinters/gocheckerrbeforeuse/gocheckerrbeforeuse.go @@ -0,0 +1,13 @@ +package gocheckerrbeforeuse + +import ( + "github.com/T-Sh/go-check-err-before-use/pkg/analyzer" + "github.com/golangci/golangci-lint/v2/pkg/config" + "github.com/golangci/golangci-lint/v2/pkg/goanalysis" +) + +func New(settings *config.GoCheckErrBeforeUseSettings) *goanalysis.Linter { + analyzerSettings := analyzer.Settings{Distance: settings.MaxAllowedDistance} + + return goanalysis.NewLinterFromAnalyzer(analyzer.NewAnalyzer(analyzerSettings)) +} diff --git a/pkg/golinters/gocheckerrbeforeuse/gocheckerrbeforeuse_test.go b/pkg/golinters/gocheckerrbeforeuse/gocheckerrbeforeuse_test.go new file mode 100644 index 000000000000..0aae7c155005 --- /dev/null +++ b/pkg/golinters/gocheckerrbeforeuse/gocheckerrbeforeuse_test.go @@ -0,0 +1,11 @@ +package gocheckerrbeforeuse + +import ( + "testing" + + "github.com/golangci/golangci-lint/v2/test/testshared/integration" +) + +func TestFromTestdata(t *testing.T) { + integration.RunTestdata(t) +} diff --git a/pkg/golinters/gocheckerrbeforeuse/testdata/custom.yml b/pkg/golinters/gocheckerrbeforeuse/testdata/custom.yml new file mode 100644 index 000000000000..6123e45b3df8 --- /dev/null +++ b/pkg/golinters/gocheckerrbeforeuse/testdata/custom.yml @@ -0,0 +1,6 @@ +version: "2" + +linters: + settings: + gocheckerrbeforeuse: + max-allowed-distance: 2 diff --git a/pkg/golinters/gocheckerrbeforeuse/testdata/gocheckerrbeforeuse.go b/pkg/golinters/gocheckerrbeforeuse/testdata/gocheckerrbeforeuse.go new file mode 100644 index 000000000000..cd81f201177b --- /dev/null +++ b/pkg/golinters/gocheckerrbeforeuse/testdata/gocheckerrbeforeuse.go @@ -0,0 +1,25 @@ +//golangcitest:args -Egocheckerrbeforeuse +package testdata + +func returns2Values() (int, error) { + return 0, nil +} + +func Negative() { + i, err := returns2Values() // want "error must be checked right after receiving" + + print(i) + + if err != nil { + return + } +} + +func Positive() { + i, err := returns2Values() + if err != nil { + return + } + + print(i) +} diff --git a/pkg/golinters/gocheckerrbeforeuse/testdata/gocheckerrbeforeuse_custom.go b/pkg/golinters/gocheckerrbeforeuse/testdata/gocheckerrbeforeuse_custom.go new file mode 100644 index 000000000000..300d681faa21 --- /dev/null +++ b/pkg/golinters/gocheckerrbeforeuse/testdata/gocheckerrbeforeuse_custom.go @@ -0,0 +1,17 @@ +//golangcitest:args -Egocheckerrbeforeuse +//golangcitest:config_path testdata/custom.yml +package testdata + +func returns2Values() (int, error) { + return 0, nil +} + +func PositiveWithCustomDistance() { + i, err := returns2Values() + + print(i) + + if err != nil { + return + } +} diff --git a/pkg/lint/lintersdb/builder_linter.go b/pkg/lint/lintersdb/builder_linter.go index c64d498e4198..fcb781e46947 100644 --- a/pkg/lint/lintersdb/builder_linter.go +++ b/pkg/lint/lintersdb/builder_linter.go @@ -36,6 +36,7 @@ import ( "github.com/golangci/golangci-lint/v2/pkg/golinters/gci" "github.com/golangci/golangci-lint/v2/pkg/golinters/ginkgolinter" "github.com/golangci/golangci-lint/v2/pkg/golinters/gocheckcompilerdirectives" + "github.com/golangci/golangci-lint/v2/pkg/golinters/gocheckerrbeforeuse" "github.com/golangci/golangci-lint/v2/pkg/golinters/gochecknoglobals" "github.com/golangci/golangci-lint/v2/pkg/golinters/gochecknoinits" "github.com/golangci/golangci-lint/v2/pkg/golinters/gochecksumtype" @@ -299,6 +300,10 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) { WithSince("v1.51.0"). WithURL("https://github.com/leighmcculloch/gocheckcompilerdirectives"), + linter.NewConfig(gocheckerrbeforeuse.New(&cfg.Linters.Settings.GoCheckErrBeforeUse)). + WithSince("v2.5.0"). + WithURL("https://github.com/T-Sh/go-check-err-before-use"), + linter.NewConfig(gochecknoglobals.New()). WithSince("v1.12.0"). WithLoadForGoAnalysis().