From 37acb73d942d877e56283f4670b3a2bce225d675 Mon Sep 17 00:00:00 2001 From: sonatard Date: Sun, 7 Jun 2020 01:15:00 +0900 Subject: [PATCH 1/4] Add test/testdata/noctx.go --- test/testdata/noctx.go | 134 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 test/testdata/noctx.go diff --git a/test/testdata/noctx.go b/test/testdata/noctx.go new file mode 100644 index 000000000000..e91a4c9c1692 --- /dev/null +++ b/test/testdata/noctx.go @@ -0,0 +1,134 @@ +//args: -Enoctx +package testdata + +import ( + "context" + "net/http" +) + +var newRequestPkg = http.NewRequest + +func main() { + const url = "http://example.com" + cli := &http.Client{} + + ctx := context.Background() + http.Get(url) // ERROR "net/http\.Get must not be called" + _ = http.Get // OK + f := http.Get // OK + f(url) // ERROR "net/http\.Get must not be called" + + http.Head(url) // ERROR "net/http\.Head must not be called" + http.Post(url, "", nil) // ERROR "net/http\.Post must not be called" + http.PostForm(url, nil) // ERROR "net/http\.PostForm must not be called" + + cli.Get(url) // ERROR "\(\*net/http\.Client\)\.Get must not be called" + _ = cli.Get // OK + m := cli.Get // OK + m(url) // ERROR "\(\*net/http\.Client\)\.Get must not be called" + + cli.Head(url) // ERROR "\(\*net/http\.Client\)\.Head must not be called" + cli.Post(url, "", nil) // ERROR "\(\*net/http\.Client\)\.Post must not be called" + cli.PostForm(url, nil) // ERROR "\(\*net/http\.Client\)\.PostForm must not be called" + + req, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR "should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext" + cli.Do(req) + + req2, _ := http.NewRequestWithContext(ctx, http.MethodPost, url, nil) // OK + cli.Do(req2) + + req3, _ := http.NewRequest(http.MethodPost, url, nil) // OK + req3 = req3.WithContext(ctx) + cli.Do(req3) + + f2 := func(req *http.Request, ctx context.Context) *http.Request { + return req + } + req4, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR "should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext" + req4 = f2(req4, ctx) + + req41, _ := http.NewRequest(http.MethodPost, url, nil) // OK + req41 = req41.WithContext(ctx) + req41 = f2(req41, ctx) + + newRequest := http.NewRequest + req5, _ := newRequest(http.MethodPost, url, nil) // ERROR "should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext" + cli.Do(req5) + + req51, _ := newRequest(http.MethodPost, url, nil) // OK + req51 = req51.WithContext(ctx) + cli.Do(req51) + + req52, _ := newRequestPkg(http.MethodPost, url, nil) // ERROR "should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext" + cli.Do(req52) + + type MyRequest = http.Request + f3 := func(req *MyRequest, ctx context.Context) *MyRequest { + return req + } + req6, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR "should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext" + req6 = f3(req6, ctx) + + req61, _ := http.NewRequest(http.MethodPost, url, nil) // OK + req61 = req61.WithContext(ctx) + req61 = f3(req61, ctx) + + type MyRequest2 http.Request + f4 := func(req *MyRequest2, ctx context.Context) *MyRequest2 { + return req + } + req7, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR "should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext" + req71 := MyRequest2(*req7) + f4(&req71, ctx) + + req72, _ := http.NewRequest(http.MethodPost, url, nil) // OK + req72 = req72.WithContext(ctx) + req73 := MyRequest2(*req7) + f4(&req73, ctx) + + req8, _ := func() (*http.Request, error) { + return http.NewRequest(http.MethodPost, url, nil) // ERROR "should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext" + }() + cli.Do(req8) + + req82, _ := func() (*http.Request, error) { + req82, _ := http.NewRequest(http.MethodPost, url, nil) // OK + req82 = req82.WithContext(ctx) + return req82, nil + }() + cli.Do(req82) + + f5 := func(req, req2 *http.Request, ctx context.Context) (*http.Request, *http.Request) { + return req, req2 + } + req9, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR "should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext" + req9, _ = f5(req9, req9, ctx) + + req91, _ := http.NewRequest(http.MethodPost, url, nil) // OK + req91 = req91.WithContext(ctx) + req9, _ = f5(req91, req91, ctx) + + req10, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR "should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext" + req11, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR "should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext" + req10, req11 = f5(req10, req11, ctx) + + req101, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR "should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext" + req111, _ := http.NewRequest(http.MethodPost, url, nil) // OK + req111 = req111.WithContext(ctx) + req101, req111 = f5(req101, req111, ctx) + + func() (*http.Request, *http.Request) { + req12, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR "should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext" + req13, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR "should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext" + return req12, req13 + }() + + func() (*http.Request, *http.Request) { + req14, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR "should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext" + req15, _ := http.NewRequest(http.MethodPost, url, nil) // OK + req15 = req15.WithContext(ctx) + + return req14, req15 + }() +} + From ff96867766dda3fe0dd448e7d152c55bd0c79438 Mon Sep 17 00:00:00 2001 From: sonatard Date: Sun, 7 Jun 2020 01:59:53 +0900 Subject: [PATCH 2/4] Add noctx --- .golangci.yml | 1 + go.mod | 1 + go.sum | 12 ++++++------ pkg/golinters/noctx.go | 21 +++++++++++++++++++++ pkg/lint/lintersdb/manager.go | 4 ++++ test/testdata/noctx.go | 2 +- 6 files changed, 34 insertions(+), 7 deletions(-) create mode 100644 pkg/golinters/noctx.go diff --git a/.golangci.yml b/.golangci.yml index a592fecf0c38..f52c0f51ace4 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -91,6 +91,7 @@ linters: - lll - misspell - nakedret + - noctx - nolintlint - rowserrcheck - scopelint diff --git a/go.mod b/go.mod index 1ece970944f9..f2985033158b 100644 --- a/go.mod +++ b/go.mod @@ -40,6 +40,7 @@ require ( github.com/securego/gosec/v2 v2.3.0 github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada // v2.19.8 github.com/sirupsen/logrus v1.6.0 + github.com/sonatard/noctx v0.0.1 github.com/sourcegraph/go-diff v0.5.3 github.com/spf13/cobra v1.0.0 github.com/spf13/pflag v1.0.5 diff --git a/go.sum b/go.sum index f03bb03e2cc8..f733133a44a9 100644 --- a/go.sum +++ b/go.sum @@ -159,6 +159,8 @@ github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoA github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3 h1:JVnpOZS+qxli+rgVl98ILOXVNbW+kb5wcxeGx8ShUIw= github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= +github.com/gostaticanalysis/analysisutil v0.0.3 h1:iwp+5/UAyzQSFgQ4uR2sni99sJ8Eo9DEacKWM5pekIg= +github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= @@ -329,8 +331,8 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1 github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/sourcegraph/go-diff v0.5.2 h1:aREwkyV8nKvCkMW0129XBB4+ZmE/zyLkdZU569ylqmQ= -github.com/sourcegraph/go-diff v0.5.2/go.mod h1:v9JDtjCE4HHHCZGId75rg8gkKKa98RVjBcBGsVmMmak= +github.com/sonatard/noctx v0.0.1 h1:VC1Qhl6Oxx9vvWo3UDgrGXYCeKCe3Wbw7qAWL6FrmTY= +github.com/sonatard/noctx v0.0.1/go.mod h1:9D2D/EoULe8Yy2joDHJj7bv3sZoq9AaSb8B4lqBjiZI= github.com/sourcegraph/go-diff v0.5.3 h1:lhIKJ2nXLZZ+AfbHpYxTn0pXpNTTui0DX7DO3xeb1Zs= github.com/sourcegraph/go-diff v0.5.3/go.mod h1:v9JDtjCE4HHHCZGId75rg8gkKKa98RVjBcBGsVmMmak= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -415,6 +417,7 @@ golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -505,16 +508,13 @@ golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200117220505-0cba7a3a9ee9/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200321224714-0d839f3cf2ed/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200331202046-9d5940d49312/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200414032229-332987a829c3/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200422022333-3d57cf2e726e h1:3Dzrrxi54Io7Aoyb0PYLsI47K2TxkRQg+cqUn+m04do= golang.org/x/tools v0.0.0-20200422022333-3d57cf2e726e/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200502202811-ed308ab3e770 h1:M9Fif0OxNji8w+HvmhVQ8KJtiZOsjU9RgslJGhn95XE= -golang.org/x/tools v0.0.0-20200502202811-ed308ab3e770 h1:M9Fif0OxNji8w+HvmhVQ8KJtiZOsjU9RgslJGhn95XE= -golang.org/x/tools v0.0.0-20200502202811-ed308ab3e770 h1:M9Fif0OxNji8w+HvmhVQ8KJtiZOsjU9RgslJGhn95XE= -golang.org/x/tools v0.0.0-20200502202811-ed308ab3e770/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200519015757-0d0afa43d58a h1:gILuVKC+ZPD6g/tj6zBOdnOH1ZHI0zZ86+KLMogc6/s= golang.org/x/tools v0.0.0-20200519015757-0d0afa43d58a/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= diff --git a/pkg/golinters/noctx.go b/pkg/golinters/noctx.go new file mode 100644 index 000000000000..b5c4a4be240b --- /dev/null +++ b/pkg/golinters/noctx.go @@ -0,0 +1,21 @@ +package golinters + +import ( + "github.com/sonatard/noctx" + "golang.org/x/tools/go/analysis" + + "github.com/golangci/golangci-lint/pkg/golinters/goanalysis" +) + +func NewNoctx() *goanalysis.Linter { + analyzers := []*analysis.Analyzer{ + noctx.Analyzer, + } + + return goanalysis.NewLinter( + "noctx", + "noctx finds sending http request without context.Context", + analyzers, + nil, + ).WithLoadMode(goanalysis.LoadModeTypesInfo) +} diff --git a/pkg/lint/lintersdb/manager.go b/pkg/lint/lintersdb/manager.go index 893f5aafc7e3..04a7dbe9c7d9 100644 --- a/pkg/lint/lintersdb/manager.go +++ b/pkg/lint/lintersdb/manager.go @@ -104,6 +104,10 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config { WithLoadForGoAnalysis(). WithPresets(linter.PresetPerformance, linter.PresetBugs). WithURL("https://github.com/timakin/bodyclose"), + linter.NewConfig(golinters.NewNoctx()). + WithLoadForGoAnalysis(). + WithPresets(linter.PresetPerformance, linter.PresetBugs). + WithURL("https://github.com/sonatard/noctx"), linter.NewConfig(golinters.NewErrcheck()). WithLoadForGoAnalysis(). WithPresets(linter.PresetBugs). diff --git a/test/testdata/noctx.go b/test/testdata/noctx.go index e91a4c9c1692..e78b25010dcb 100644 --- a/test/testdata/noctx.go +++ b/test/testdata/noctx.go @@ -8,7 +8,7 @@ import ( var newRequestPkg = http.NewRequest -func main() { +func Noctx() { const url = "http://example.com" cli := &http.Client{} From df28c053993f1c4dc1424fb7f75863d73ef99358 Mon Sep 17 00:00:00 2001 From: sonatard Date: Sun, 7 Jun 2020 02:11:04 +0900 Subject: [PATCH 3/4] Change --max-same-issues=100 in testOneSource --- test/linters_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/linters_test.go b/test/linters_test.go index ac57f4942ac0..bc8fbc5b7590 100644 --- a/test/linters_test.go +++ b/test/linters_test.go @@ -110,7 +110,7 @@ func testOneSource(t *testing.T, sourcePath string) { "--print-issued-lines=false", "--print-linter-name=false", "--out-format=line-number", - "--max-same-issues=10", + "--max-same-issues=100", } rc := extractRunContextFromComments(t, sourcePath) From d48fbda2265ac0f3380deb67c27e4131a6a33225 Mon Sep 17 00:00:00 2001 From: sonatard Date: Sun, 7 Jun 2020 02:21:40 +0900 Subject: [PATCH 4/4] Fix .golangci.yml --- .golangci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.golangci.yml b/.golangci.yml index f52c0f51ace4..3d9c7b405fc6 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -91,7 +91,6 @@ linters: - lll - misspell - nakedret - - noctx - nolintlint - rowserrcheck - scopelint @@ -115,6 +114,7 @@ linters: # - goerr113 # - maligned # - nestif + # - noctx (TODO: enable after next release; current release at time of writing is v1.27) # - prealloc # - testpackage # - wsl