New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Noctx #1179
Add Noctx #1179
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why have you decided to increase the limit? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change When "--max-same-issues=10" $ T=noctx.go make test_linters
GL_TEST_RUN=1 go test -v ./test -count 1 -run TestSourcesFromTestdataWithIssuesDir/noctx.go
=== RUN TestSourcesFromTestdataWithIssuesDir
=== RUN TestSourcesFromTestdataWithIssuesDir/noctx.go
=== PAUSE TestSourcesFromTestdataWithIssuesDir/noctx.go
=== CONT TestSourcesFromTestdataWithIssuesDir/noctx.go
--- FAIL: TestSourcesFromTestdataWithIssuesDir (1.28s)
linters_test.go:41: testdata/*.go
--- FAIL: TestSourcesFromTestdataWithIssuesDir/noctx.go (1.42s)
linters_test.go:142: [run --allow-parallel-runners --disable-all --print-issued-lines=false --print-linter-name=false --out-format=line-number --max-same-issues=10 -Enoctx --no-config testdata/noctx.go]
linters_test.go:37:
Error Trace: linters_test.go:37
linters_test.go:143
linters_test.go:57
Error: Received unexpected error:
noctx.go:34: missing error "should rewrite http.NewRequestWithContext or add \\(\\*Request\\).WithContext"
noctx.go:47: missing error "should rewrite http.NewRequestWithContext or add \\(\\*Request\\).WithContext"
noctx.go:69: missing error "should rewrite http.NewRequestWithContext or add \\(\\*Request\\).WithContext"
noctx.go:122: missing error "should rewrite http.NewRequestWithContext or add \\(\\*Request\\).WithContext"
Test: TestSourcesFromTestdataWithIssuesDir/noctx.go
FAIL
FAIL github.com/golangci/golangci-lint/test 3.172s
FAIL
make: *** [Makefile:38: test_linters] Error 1 |
||
} | ||
|
||
rc := extractRunContextFromComments(t, sourcePath) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
//args: -Enoctx | ||
package testdata | ||
|
||
import ( | ||
"context" | ||
"net/http" | ||
) | ||
|
||
var newRequestPkg = http.NewRequest | ||
|
||
func Noctx() { | ||
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 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the purpose of this function? There are few other similar introduced in this test file and I'm not sure I can grasp why. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. SSA is different for each test cases. These test cases are useful for finding bugs. If you don't need these tests for golangci-lint, I can remove them, leaving a simple test case for golangci-lint, since they are running in noctx repository. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm absolutely fine with the tests - I just wanted to understand why you decided to follow such an approach :) |
||
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) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does context have to be set in scope of the function where There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If context is set it in other scope, it will be difficult to migrate to http.NewRequestWithContext. WithContext should be run on the next line of NewRequest for compatibility of http.NewRequestWithContext function. |
||
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 | ||
}() | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why can't it be enabled now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The golangci-lint version is 1.27 in Github Actions.
Version 1.27 does not include
noctx
, test in CI is failed.https://github.com/golangci/golangci-lint/runs/745557992