diff --git a/.golangci.reference.yml b/.golangci.reference.yml index 4e9128df3306..9186cc00ebd7 100644 --- a/.golangci.reference.yml +++ b/.golangci.reference.yml @@ -1746,6 +1746,37 @@ linters-settings: # Default: true begin: false + uncalled: + # Disables all rules. + # Default: false + disabled-all: true + # Disables the given rules. + # Default: [] + disabled: + - context-cancel + # Enables specific rules, in combination with disable all. + # Default: [] + enabled: + - sql-rows-err + # Add or override default rules. + # Default: [] + rules: + # Check for missing context CancelFunc() calls. + - name: context-cancel + category: context + packages: + - context + methods: [] + results: + - type: .Context + pointer: false + - type: .CancelFunc + pointer: false + expect: + call: + args: [] + + usestdlibvars: # Suggest the use of http.MethodXX. # Default: true @@ -2052,6 +2083,7 @@ linters: - thelper - tparallel - typecheck + - uncalled - unconvert - unparam - unused @@ -2159,6 +2191,7 @@ linters: - thelper - tparallel - typecheck + - uncalled - unconvert - unparam - unused diff --git a/go.mod b/go.mod index 2b0b9e94034d..138f7af6bc89 100644 --- a/go.mod +++ b/go.mod @@ -93,6 +93,7 @@ require ( github.com/spf13/viper v1.12.0 github.com/ssgreg/nlreturn/v2 v2.2.1 github.com/stbenjam/no-sprintf-host-port v0.1.1 + github.com/stevenh/go-uncalled v0.8.1 github.com/stretchr/testify v1.8.1 github.com/tdakkota/asciicheck v0.1.1 github.com/tetafro/godot v1.4.11 @@ -162,6 +163,7 @@ require ( github.com/quasilyte/gogrep v0.0.0-20220828223005-86e4605de09f // indirect github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 // indirect github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect + github.com/rs/zerolog v1.28.0 // indirect github.com/sivchari/nosnakecase v1.7.0 github.com/spf13/afero v1.8.2 // indirect github.com/spf13/cast v1.5.0 // indirect diff --git a/go.sum b/go.sum index 679db26e9dbf..f7e670977dfe 100644 --- a/go.sum +++ b/go.sum @@ -102,6 +102,7 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cristalhq/acmd v0.8.1/go.mod h1:LG5oa43pE/BbxtfMoImHCQN++0Su7dzipdgBjMCBVDQ= @@ -172,6 +173,7 @@ github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b h1:khEcpUM4yFcxg4 github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -354,6 +356,7 @@ github.com/matoous/godox v0.0.0-20210227103229-6504466cf951/go.mod h1:1BELzlh859 github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= @@ -459,6 +462,9 @@ github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4l github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY= +github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryancurrah/gomodguard v1.2.4 h1:CpMSDKan0LtNGGhPrvupAoLeObRFjND8/tU1rEOtBp4= github.com/ryancurrah/gomodguard v1.2.4/go.mod h1:+Kem4VjWwvFpUJRJSwa16s1tBJe+vbv02+naTow2f6M= @@ -509,6 +515,10 @@ github.com/ssgreg/nlreturn/v2 v2.2.1 h1:X4XDI7jstt3ySqGU86YGAURbxw3oTDPK9sPEi6YE github.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I= github.com/stbenjam/no-sprintf-host-port v0.1.1 h1:tYugd/yrm1O0dV+ThCbaKZh195Dfm07ysF0U6JQXczc= github.com/stbenjam/no-sprintf-host-port v0.1.1/go.mod h1:TLhvtIvONRzdmkFiio4O8LHsN9N74I+PhRquPsxpL0I= +github.com/stevenh/go-uncalled v0.8.0 h1:avctwO9QTaMulHHfwuaYN9N21yrlgyGnSYPLmF1wXp8= +github.com/stevenh/go-uncalled v0.8.0/go.mod h1:susI8UKFPgJnpDU0zM7eLuI1x65Ha+YZGkg4h1Vpd0M= +github.com/stevenh/go-uncalled v0.8.1 h1:eSLB7XXbCweqfJn8WkwDaOnZR1f5Als1QDyIJlQZNsI= +github.com/stevenh/go-uncalled v0.8.1/go.mod h1:susI8UKFPgJnpDU0zM7eLuI1x65Ha+YZGkg4h1Vpd0M= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -757,6 +767,7 @@ golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211105183446-c75c47738b0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/pkg/config/linters_settings.go b/pkg/config/linters_settings.go index 412a6cc5d19b..bc5fcaf358cb 100644 --- a/pkg/config/linters_settings.go +++ b/pkg/config/linters_settings.go @@ -4,6 +4,7 @@ import ( "runtime" "github.com/pkg/errors" + "github.com/stevenh/go-uncalled/pkg/uncalled" ) var defaultLintersSettings = LintersSettings{ @@ -108,6 +109,12 @@ var defaultLintersSettings = LintersSettings{ SkipRegexp: `(export|internal)_test\.go`, AllowPackages: []string{"main"}, }, + Uncalled: UncalledSettings{ + DisableAll: false, + Enabled: nil, + Disabled: nil, + Rules: nil, + }, Unparam: UnparamSettings{ Algo: "cha", }, @@ -198,6 +205,7 @@ type LintersSettings struct { Tenv TenvSettings Testpackage TestpackageSettings Thelper ThelperSettings + Uncalled UncalledSettings Unparam UnparamSettings Unused StaticCheckSettings UseStdlibVars UseStdlibVarsSettings @@ -667,6 +675,8 @@ type UseStdlibVarsSettings struct { SyslogPriority bool `mapstructure:"syslog-priority"` } +type UncalledSettings = uncalled.Config + type UnparamSettings struct { CheckExported bool `mapstructure:"check-exported"` Algo string diff --git a/pkg/golinters/uncalled.go b/pkg/golinters/uncalled.go new file mode 100644 index 000000000000..aa004575fc12 --- /dev/null +++ b/pkg/golinters/uncalled.go @@ -0,0 +1,19 @@ +package golinters + +import ( + "github.com/stevenh/go-uncalled/pkg/uncalled" + "golang.org/x/tools/go/analysis" + + "github.com/golangci/golangci-lint/pkg/config" + "github.com/golangci/golangci-lint/pkg/golinters/goanalysis" +) + +func NewUncalled(settings *config.UncalledSettings) *goanalysis.Linter { + a := uncalled.NewAnalyzer(uncalled.ConfigOpt(settings)) + return goanalysis.NewLinter( + a.Name, + a.Doc, + []*analysis.Analyzer{a}, + nil, + ).WithLoadMode(goanalysis.LoadModeTypesInfo) +} diff --git a/pkg/lint/lintersdb/manager.go b/pkg/lint/lintersdb/manager.go index 353ca88dcd7b..76af37473ead 100644 --- a/pkg/lint/lintersdb/manager.go +++ b/pkg/lint/lintersdb/manager.go @@ -166,6 +166,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config { tenvCfg *config.TenvSettings testpackageCfg *config.TestpackageSettings thelperCfg *config.ThelperSettings + uncalledCfg *config.UncalledSettings unparamCfg *config.UnparamSettings unusedCfg *config.StaticCheckSettings usestdlibvars *config.UseStdlibVarsSettings @@ -242,6 +243,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config { tenvCfg = &m.cfg.LintersSettings.Tenv testpackageCfg = &m.cfg.LintersSettings.Testpackage thelperCfg = &m.cfg.LintersSettings.Thelper + uncalledCfg = &m.cfg.LintersSettings.Uncalled unparamCfg = &m.cfg.LintersSettings.Unparam unusedCfg = &m.cfg.LintersSettings.Unused varcheckCfg = &m.cfg.LintersSettings.Varcheck @@ -787,6 +789,12 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config { WithPresets(linter.PresetBugs). WithURL(""), + linter.NewConfig(golinters.NewUncalled(uncalledCfg)). + WithSince("v1.51.0"). + WithLoadForGoAnalysis(). + WithPresets(linter.PresetBugs, linter.PresetSQL). + WithURL("https://github.com/stevenh/go-uncalled"), + linter.NewConfig(golinters.NewUnconvert()). WithSince("v1.0.0"). WithLoadForGoAnalysis(). diff --git a/test/linters_test.go b/test/linters_test.go index 159e76c8bb56..2e54ea95a9e7 100644 --- a/test/linters_test.go +++ b/test/linters_test.go @@ -30,6 +30,7 @@ func TestTypecheck(t *testing.T) { func TestSourcesFromTestdataSubDir(t *testing.T) { subDirs := []string{ "loggercheck", + "uncalled", } for _, dir := range subDirs { diff --git a/test/testdata/uncalled/uncalled.go b/test/testdata/uncalled/uncalled.go new file mode 100644 index 000000000000..e71f7c180316 --- /dev/null +++ b/test/testdata/uncalled/uncalled.go @@ -0,0 +1,17 @@ +//golangcitest:args -Euncalled +package testdata + +import ( + "database/sql" +) + +func RowsErrNotChecked(db *sql.DB) { + rows, err := db.Query("select id from tb") // want "rows.Err\\(\\) must be called" + if err != nil { + // Handle error. + } + + for rows.Next() { + // Handle row. + } +}