From f771ef0bc27c461b3a503a053b4ca904170aeb34 Mon Sep 17 00:00:00 2001 From: Alwx Date: Fri, 23 May 2025 14:04:29 +0300 Subject: [PATCH 1/5] add noinlineerr linter --- .golangci.next.reference.yml | 2 + jsonschema/golangci.next.jsonschema.json | 1 + pkg/golinters/noinlineerr/noinlineerr.go | 18 +++++++ .../noinlineerr_integration_test.go | 11 ++++ .../noinlineerr/testdata/noinlineerr.go | 52 +++++++++++++++++++ pkg/lint/lintersdb/builder_linter.go | 6 +++ 6 files changed, 90 insertions(+) create mode 100644 pkg/golinters/noinlineerr/noinlineerr.go create mode 100644 pkg/golinters/noinlineerr/noinlineerr_integration_test.go create mode 100644 pkg/golinters/noinlineerr/testdata/noinlineerr.go diff --git a/.golangci.next.reference.yml b/.golangci.next.reference.yml index 0e8609212c6b..abc9c060efbe 100644 --- a/.golangci.next.reference.yml +++ b/.golangci.next.reference.yml @@ -91,6 +91,7 @@ linters: - nilnil - nlreturn - noctx + - noinlineerr - nolintlint - nonamedreturns - nosprintfhostport @@ -200,6 +201,7 @@ linters: - nilnil - nlreturn - noctx + - noinlineerr - nolintlint - nonamedreturns - nosprintfhostport diff --git a/jsonschema/golangci.next.jsonschema.json b/jsonschema/golangci.next.jsonschema.json index 70fa57bdad74..a12cb912b569 100644 --- a/jsonschema/golangci.next.jsonschema.json +++ b/jsonschema/golangci.next.jsonschema.json @@ -794,6 +794,7 @@ "nilnil", "nlreturn", "noctx", + "noinlineerr", "nolintlint", "nonamedreturns", "nosprintfhostport", diff --git a/pkg/golinters/noinlineerr/noinlineerr.go b/pkg/golinters/noinlineerr/noinlineerr.go new file mode 100644 index 000000000000..2772ab98fc61 --- /dev/null +++ b/pkg/golinters/noinlineerr/noinlineerr.go @@ -0,0 +1,18 @@ +package noinlineerr + +import ( + "github.com/AlwxSin/noinlineerr" + "golang.org/x/tools/go/analysis" + + "github.com/golangci/golangci-lint/v2/pkg/goanalysis" +) + +func New() *goanalysis.Linter { + analyzer := noinlineerr.NewAnalyzer() + return goanalysis.NewLinter( + analyzer.Name, + analyzer.Doc, + []*analysis.Analyzer{analyzer}, + nil, + ).WithLoadMode(goanalysis.LoadModeTypesInfo) +} diff --git a/pkg/golinters/noinlineerr/noinlineerr_integration_test.go b/pkg/golinters/noinlineerr/noinlineerr_integration_test.go new file mode 100644 index 000000000000..3ca6fcd5b23f --- /dev/null +++ b/pkg/golinters/noinlineerr/noinlineerr_integration_test.go @@ -0,0 +1,11 @@ +package noinlineerr + +import ( + "testing" + + "github.com/golangci/golangci-lint/v2/test/testshared/integration" +) + +func TestFromTestdata(t *testing.T) { + integration.RunTestdata(t) +} diff --git a/pkg/golinters/noinlineerr/testdata/noinlineerr.go b/pkg/golinters/noinlineerr/testdata/noinlineerr.go new file mode 100644 index 000000000000..27991f4d5cfa --- /dev/null +++ b/pkg/golinters/noinlineerr/testdata/noinlineerr.go @@ -0,0 +1,52 @@ +//golangcitest:args -Enoinlineerr +package testdata + +func doSomething() error { + return nil +} + +func doSmthManyArgs(a, b, c, d int) error { + return nil +} + +func doSmthMultipleReturn() (bool, error) { + return false, nil +} + +func valid() error { + err := doSomething() // ok + if err != nil { + return err + } + + err = doSmthManyArgs(0, 0, 0, 0) // ok + if err != nil { + return err + } + + _, err = doSmthMultipleReturn() // ok + if err != nil { + return err + } + return nil +} + +func invalid() error { + if err := doSomething(); err != nil { // want "avoid inline error handling using `if err := ...; err != nil; use plain assignment `err := ..." + return err + } + + if err := doSmthManyArgs(0, // want "avoid inline error handling using `if err := ...; err != nil; use plain assignment `err := ..." + 0, + 0, + 0, + ); err != nil { + return err + } + + if _, err := doSmthMultipleReturn(); err != nil { // want "avoid inline error handling using `if err := ...; err != nil; use plain assignment `err := ..." + _ = false + return err + } + return nil +} diff --git a/pkg/lint/lintersdb/builder_linter.go b/pkg/lint/lintersdb/builder_linter.go index 48a64375f53c..bd7d3ef49743 100644 --- a/pkg/lint/lintersdb/builder_linter.go +++ b/pkg/lint/lintersdb/builder_linter.go @@ -79,6 +79,7 @@ import ( "github.com/golangci/golangci-lint/v2/pkg/golinters/nilnil" "github.com/golangci/golangci-lint/v2/pkg/golinters/nlreturn" "github.com/golangci/golangci-lint/v2/pkg/golinters/noctx" + "github.com/golangci/golangci-lint/v2/pkg/golinters/noinlineerr" "github.com/golangci/golangci-lint/v2/pkg/golinters/nolintlint" "github.com/golangci/golangci-lint/v2/pkg/golinters/nonamedreturns" "github.com/golangci/golangci-lint/v2/pkg/golinters/nosprintfhostport" @@ -511,6 +512,11 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) { WithLoadForGoAnalysis(). WithURL("https://github.com/sonatard/noctx"), + linter.NewConfig(noinlineerr.New()). + WithSince("v2.2.80"). + WithLoadForGoAnalysis(). + WithURL("https://github.com/AlwxSin/noinlineerr"), + linter.NewConfig(nonamedreturns.New(&cfg.Linters.Settings.NoNamedReturns)). WithSince("v1.46.0"). WithLoadForGoAnalysis(). From 4ef093f63d3ac3993bd15ab15f30c4abc3547a46 Mon Sep 17 00:00:00 2001 From: Alwx Date: Fri, 23 May 2025 15:49:03 +0300 Subject: [PATCH 2/5] add stdlib to noinilineerr tests --- pkg/golinters/noinlineerr/testdata/noinlineerr.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/pkg/golinters/noinlineerr/testdata/noinlineerr.go b/pkg/golinters/noinlineerr/testdata/noinlineerr.go index 27991f4d5cfa..90e78f3e171b 100644 --- a/pkg/golinters/noinlineerr/testdata/noinlineerr.go +++ b/pkg/golinters/noinlineerr/testdata/noinlineerr.go @@ -1,6 +1,8 @@ //golangcitest:args -Enoinlineerr package testdata +import "fmt" + func doSomething() error { return nil } @@ -24,9 +26,9 @@ func valid() error { return err } - _, err = doSmthMultipleReturn() // ok + ok, err := doSmthMultipleReturn() // ok if err != nil { - return err + return fmt.Errorf("%b; %w", ok, err) } return nil } @@ -44,9 +46,8 @@ func invalid() error { return err } - if _, err := doSmthMultipleReturn(); err != nil { // want "avoid inline error handling using `if err := ...; err != nil; use plain assignment `err := ..." - _ = false - return err + if ok, err := doSmthMultipleReturn(); err != nil { // want "avoid inline error handling using `if err := ...; err != nil; use plain assignment `err := ..." + return fmt.Errorf("%b; %w", ok, err) } return nil } From 6cc71f05e83429710e7b06db8b6bfccff93f3b16 Mon Sep 17 00:00:00 2001 From: Alwx Date: Fri, 23 May 2025 15:53:59 +0300 Subject: [PATCH 3/5] fix SinceVersion for noinlineerr linter --- pkg/lint/lintersdb/builder_linter.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/lint/lintersdb/builder_linter.go b/pkg/lint/lintersdb/builder_linter.go index bd7d3ef49743..734aab63cd1c 100644 --- a/pkg/lint/lintersdb/builder_linter.go +++ b/pkg/lint/lintersdb/builder_linter.go @@ -513,7 +513,7 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) { WithURL("https://github.com/sonatard/noctx"), linter.NewConfig(noinlineerr.New()). - WithSince("v2.2.80"). + WithSince("v2.2.0"). WithLoadForGoAnalysis(). WithURL("https://github.com/AlwxSin/noinlineerr"), From c8f8c3996505aa6d66e12216dc21e13ececf9137 Mon Sep 17 00:00:00 2001 From: Alwx Date: Mon, 26 May 2025 20:16:15 +0300 Subject: [PATCH 4/5] bump noinlineerr v1.0.3; add fix tests --- go.mod | 1 + go.sum | 2 + .../noinlineerr_integration_test.go | 8 +++ .../testdata/fix/in/noinlineerr.go | 59 +++++++++++++++++++ .../testdata/fix/out/noinlineerr.go | 59 +++++++++++++++++++ .../noinlineerr/testdata/noinlineerr.go | 48 ++++++++++++--- 6 files changed, 170 insertions(+), 7 deletions(-) create mode 100644 pkg/golinters/noinlineerr/testdata/fix/in/noinlineerr.go create mode 100644 pkg/golinters/noinlineerr/testdata/fix/out/noinlineerr.go diff --git a/go.mod b/go.mod index cf3c581a5fba..6f084bed2675 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( 4d63.com/gochecknoglobals v0.2.2 github.com/4meepo/tagalign v1.4.2 github.com/Abirdcfly/dupword v0.1.6 + github.com/AlwxSin/noinlineerr v1.0.3 github.com/Antonboom/errname v1.1.0 github.com/Antonboom/nilnil v1.1.0 github.com/Antonboom/testifylint v1.6.1 diff --git a/go.sum b/go.sum index 55ffdf91c2e4..0a4e0d2587b0 100644 --- a/go.sum +++ b/go.sum @@ -41,6 +41,8 @@ github.com/4meepo/tagalign v1.4.2 h1:0hcLHPGMjDyM1gHG58cS73aQF8J4TdVR96TZViorO9E github.com/4meepo/tagalign v1.4.2/go.mod h1:+p4aMyFM+ra7nb41CnFG6aSDXqRxU/w1VQqScKqDARI= github.com/Abirdcfly/dupword v0.1.6 h1:qeL6u0442RPRe3mcaLcbaCi2/Y/hOcdtw6DE9odjz9c= github.com/Abirdcfly/dupword v0.1.6/go.mod h1:s+BFMuL/I4YSiFv29snqyjwzDp4b65W2Kvy+PKzZ6cw= +github.com/AlwxSin/noinlineerr v1.0.3 h1:9b5edChzzwX30BuBci13LHVZHF5q7hW9qtrs+wJdDog= +github.com/AlwxSin/noinlineerr v1.0.3/go.mod h1:+QgkkoYrMH7RHvcdxdlI7vYYEdgeoFOVjU9sUhw/rQc= github.com/Antonboom/errname v1.1.0 h1:A+ucvdpMwlo/myWrkHEUEBWc/xuXdud23S8tmTb/oAE= github.com/Antonboom/errname v1.1.0/go.mod h1:O1NMrzgUcVBGIfi3xlVuvX8Q/VP/73sseCaAppfjqZw= github.com/Antonboom/nilnil v1.1.0 h1:jGxJxjgYS3VUUtOTNk8Z1icwT5ESpLH/426fjmQG+ng= diff --git a/pkg/golinters/noinlineerr/noinlineerr_integration_test.go b/pkg/golinters/noinlineerr/noinlineerr_integration_test.go index 3ca6fcd5b23f..3b14450932a1 100644 --- a/pkg/golinters/noinlineerr/noinlineerr_integration_test.go +++ b/pkg/golinters/noinlineerr/noinlineerr_integration_test.go @@ -9,3 +9,11 @@ import ( func TestFromTestdata(t *testing.T) { integration.RunTestdata(t) } + +func TestFix(t *testing.T) { + integration.RunFix(t) +} + +func TestFixPathPrefix(t *testing.T) { + integration.RunFixPathPrefix(t) +} diff --git a/pkg/golinters/noinlineerr/testdata/fix/in/noinlineerr.go b/pkg/golinters/noinlineerr/testdata/fix/in/noinlineerr.go new file mode 100644 index 000000000000..62c90bd98017 --- /dev/null +++ b/pkg/golinters/noinlineerr/testdata/fix/in/noinlineerr.go @@ -0,0 +1,59 @@ +//golangcitest:args -Enoinlineerr +//golangcitest:expected_exitcode 0 +package testdata + +type MyAliasErr error + +type MyCustomError struct{} + +func (mc *MyCustomError) Error() string { + return "error" +} + +func doSomething() error { + return nil +} + +func doSmthManyArgs(a, b, c, d int) error { + return nil +} + +func doSmthMultipleReturn() (bool, error) { + return false, nil +} + +func doMyAliasErr() MyAliasErr { + return nil +} + +func doMyCustomErr() *MyCustomError { + return &MyCustomError{} +} + +func invalid() error { + err := doSomething() + if err != nil { + return err + } + + err = doSmthManyArgs(0, + 0, + 0, + 0, + ) + if err != nil { + return err + } + + err = doMyAliasErr() + if err != nil { + return err + } + + err = doMyCustomErr() + if err != nil { + return err + } + + return nil +} diff --git a/pkg/golinters/noinlineerr/testdata/fix/out/noinlineerr.go b/pkg/golinters/noinlineerr/testdata/fix/out/noinlineerr.go new file mode 100644 index 000000000000..62c90bd98017 --- /dev/null +++ b/pkg/golinters/noinlineerr/testdata/fix/out/noinlineerr.go @@ -0,0 +1,59 @@ +//golangcitest:args -Enoinlineerr +//golangcitest:expected_exitcode 0 +package testdata + +type MyAliasErr error + +type MyCustomError struct{} + +func (mc *MyCustomError) Error() string { + return "error" +} + +func doSomething() error { + return nil +} + +func doSmthManyArgs(a, b, c, d int) error { + return nil +} + +func doSmthMultipleReturn() (bool, error) { + return false, nil +} + +func doMyAliasErr() MyAliasErr { + return nil +} + +func doMyCustomErr() *MyCustomError { + return &MyCustomError{} +} + +func invalid() error { + err := doSomething() + if err != nil { + return err + } + + err = doSmthManyArgs(0, + 0, + 0, + 0, + ) + if err != nil { + return err + } + + err = doMyAliasErr() + if err != nil { + return err + } + + err = doMyCustomErr() + if err != nil { + return err + } + + return nil +} diff --git a/pkg/golinters/noinlineerr/testdata/noinlineerr.go b/pkg/golinters/noinlineerr/testdata/noinlineerr.go index 90e78f3e171b..3bf739b7d1c3 100644 --- a/pkg/golinters/noinlineerr/testdata/noinlineerr.go +++ b/pkg/golinters/noinlineerr/testdata/noinlineerr.go @@ -1,7 +1,18 @@ //golangcitest:args -Enoinlineerr package testdata -import "fmt" +import ( + "fmt" + "strconv" +) + +type MyAliasErr error + +type MyCustomError struct {} + +func (mc *MyCustomError) Error() string { + return "error" +} func doSomething() error { return nil @@ -15,6 +26,14 @@ func doSmthMultipleReturn() (bool, error) { return false, nil } +func doMyAliasErr() MyAliasErr { + return nil +} + +func doMyCustomErr() *MyCustomError { + return &MyCustomError{} +} + func valid() error { err := doSomething() // ok if err != nil { @@ -26,19 +45,24 @@ func valid() error { return err } - ok, err := doSmthMultipleReturn() // ok + _, err = doSmthMultipleReturn() // ok if err != nil { - return fmt.Errorf("%b; %w", ok, err) + return err } + + if ok, _ := strconv.ParseBool("1"); ok { + fmt.Println("ok") + } + return nil } func invalid() error { - if err := doSomething(); err != nil { // want "avoid inline error handling using `if err := ...; err != nil; use plain assignment `err := ..." + if err := doSomething(); err != nil { // want "avoid inline error handling using `if err := ...; err != nil`; use plain assignment `err := ...`" return err } - if err := doSmthManyArgs(0, // want "avoid inline error handling using `if err := ...; err != nil; use plain assignment `err := ..." + if err := doSmthManyArgs(0, // want "avoid inline error handling using `if err := ...; err != nil`; use plain assignment `err := ...`" 0, 0, 0, @@ -46,8 +70,18 @@ func invalid() error { return err } - if ok, err := doSmthMultipleReturn(); err != nil { // want "avoid inline error handling using `if err := ...; err != nil; use plain assignment `err := ..." - return fmt.Errorf("%b; %w", ok, err) + if _, err := doSmthMultipleReturn(); err != nil { // want "avoid inline error handling using `if err := ...; err != nil`; use plain assignment `err := ...`" + _ = false + return err + } + + if err := doMyAliasErr(); err != nil { // want "avoid inline error handling using `if err := ...; err != nil`; use plain assignment `err := ...`" + return err } + + if err := doMyCustomErr(); err != nil { // want "avoid inline error handling using `if err := ...; err != nil`; use plain assignment `err := ...`" + return err + } + return nil } From 973d9878f0da3848b92d4ae528ad1d03b30b42f0 Mon Sep 17 00:00:00 2001 From: Fernandez Ludovic Date: Thu, 29 May 2025 15:00:22 +0200 Subject: [PATCH 5/5] review --- pkg/golinters/noinlineerr/noinlineerr.go | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/pkg/golinters/noinlineerr/noinlineerr.go b/pkg/golinters/noinlineerr/noinlineerr.go index 2772ab98fc61..4f9f82eb4d0c 100644 --- a/pkg/golinters/noinlineerr/noinlineerr.go +++ b/pkg/golinters/noinlineerr/noinlineerr.go @@ -2,17 +2,12 @@ package noinlineerr import ( "github.com/AlwxSin/noinlineerr" - "golang.org/x/tools/go/analysis" "github.com/golangci/golangci-lint/v2/pkg/goanalysis" ) func New() *goanalysis.Linter { - analyzer := noinlineerr.NewAnalyzer() - return goanalysis.NewLinter( - analyzer.Name, - analyzer.Doc, - []*analysis.Analyzer{analyzer}, - nil, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) + return goanalysis. + NewLinterFromAnalyzer(noinlineerr.NewAnalyzer()). + WithLoadMode(goanalysis.LoadModeTypesInfo) }