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/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/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..4f9f82eb4d0c --- /dev/null +++ b/pkg/golinters/noinlineerr/noinlineerr.go @@ -0,0 +1,13 @@ +package noinlineerr + +import ( + "github.com/AlwxSin/noinlineerr" + + "github.com/golangci/golangci-lint/v2/pkg/goanalysis" +) + +func New() *goanalysis.Linter { + return goanalysis. + NewLinterFromAnalyzer(noinlineerr.NewAnalyzer()). + 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..3b14450932a1 --- /dev/null +++ b/pkg/golinters/noinlineerr/noinlineerr_integration_test.go @@ -0,0 +1,19 @@ +package noinlineerr + +import ( + "testing" + + "github.com/golangci/golangci-lint/v2/test/testshared/integration" +) + +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 new file mode 100644 index 000000000000..3bf739b7d1c3 --- /dev/null +++ b/pkg/golinters/noinlineerr/testdata/noinlineerr.go @@ -0,0 +1,87 @@ +//golangcitest:args -Enoinlineerr +package testdata + +import ( + "fmt" + "strconv" +) + +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 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 + } + + 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 := ...`" + 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 + } + + 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 +} diff --git a/pkg/lint/lintersdb/builder_linter.go b/pkg/lint/lintersdb/builder_linter.go index 48a64375f53c..734aab63cd1c 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.0"). + WithLoadForGoAnalysis(). + WithURL("https://github.com/AlwxSin/noinlineerr"), + linter.NewConfig(nonamedreturns.New(&cfg.Linters.Settings.NoNamedReturns)). WithSince("v1.46.0"). WithLoadForGoAnalysis().