
noctx finds function calls without context.Context.
Passing context.Context enables library user to cancel request, getting trace information and so on.
noctx helps you to identify code that could be rewritten to use the context.Context.
go vet is a Go standard tool for analyzing source code.
- Install noctx.
$ go install github.com/sonatard/noctx/cmd/noctx@latest
- Execute noctx
$ go vet -vettool=`which noctx` main.go
./main.go:6:11: net/http.Get must not be called
golangci-lint is a fast Go linters runner.
-
Install golangci-lint.
golangci-lint - Install
-
Setup .golangci.yml
# Add noctx to enable linters.
linters:
enable:
- noctx
# Or enable-all is true.
linters:
default: all
disable:
- xxx # Add unused linter to disable linters.
- Execute noctx
# Use .golangci.yml
$ golangci-lint run
# Only execute noctx
golangci-lint run --enable-only noctx
|
// net/http |
|
"net/http.Get": "must not be called. use net/http.NewRequestWithContext and (*net/http.Client).Do(*http.Request)", |
|
"net/http.Head": "must not be called. use net/http.NewRequestWithContext and (*net/http.Client).Do(*http.Request)", |
|
"net/http.Post": "must not be called. use net/http.NewRequestWithContext and (*net/http.Client).Do(*http.Request)", |
|
"net/http.PostForm": "must not be called. use net/http.NewRequestWithContext and (*net/http.Client).Do(*http.Request)", |
|
"(*net/http.Client).Get": "must not be called. use (*net/http.Client).Do(*http.Request)", |
|
"(*net/http.Client).Head": "must not be called. use (*net/http.Client).Do(*http.Request)", |
|
"(*net/http.Client).Post": "must not be called. use (*net/http.Client).Do(*http.Request)", |
|
"(*net/http.Client).PostForm": "must not be called. use (*net/http.Client).Do(*http.Request)", |
|
"net/http.NewRequest": "must not be called. use net/http.NewRequestWithContext", |
|
http.Get(url) // want `net/http\.Get must not be called. use net/http\.NewRequestWithContext and \(\*net/http.Client\)\.Do\(\*http.Request\)` |
|
req, _ := http.NewRequest(http.MethodPost, url, nil) // want `net/http\.NewRequest must not be called. use net/http\.NewRequestWithContext` |
|
// net |
|
"net.Listen": "must not be called. use (*net.ListenConfig).Listen", |
|
"net.ListenPacket": "must not be called. use (*net.ListenConfig).ListenPacket", |
|
"net.Dial": "must not be called. use (*net.Dialer).DialContext", |
|
"net.DialTimeout": "must not be called. use (*net.Dialer).DialContext with (*net.Dialer).Timeout", |
|
"net.LookupCNAME": "must not be called. use (*net.Resolver).LookupCNAME with a context", |
|
"net.LookupHost": "must not be called. use (*net.Resolver).LookupHost with a context", |
|
"net.LookupIP": "must not be called. use (*net.Resolver).LookupIPAddr with a context", |
|
"net.LookupPort": "must not be called. use (*net.Resolver).LookupPort with a context", |
|
"net.LookupSRV": "must not be called. use (*net.Resolver).LookupSRV with a context", |
|
"net.LookupMX": "must not be called. use (*net.Resolver).LookupMX with a context", |
|
"net.LookupNS": "must not be called. use (*net.Resolver).LookupNS with a context", |
|
"net.LookupTXT": "must not be called. use (*net.Resolver).LookupTXT with a context", |
|
"net.LookupAddr": "must not be called. use (*net.Resolver).LookupAddr with a context", |
|
net.Listen("tcp", "localhost:8080") // want `net\.Listen must not be called. use \(\*net\.ListenConfig\)\.Listen` |
|
// database/sql |
|
"(*database/sql.DB).Begin": "must not be called. use (*database/sql.DB).BeginTx", |
|
"(*database/sql.DB).Exec": "must not be called. use (*database/sql.DB).ExecContext", |
|
"(*database/sql.DB).Ping": "must not be called. use (*database/sql.DB).PingContext", |
|
"(*database/sql.DB).Prepare": "must not be called. use (*database/sql.DB).PrepareContext", |
|
"(*database/sql.DB).Query": "must not be called. use (*database/sql.DB).QueryContext", |
|
"(*database/sql.DB).QueryRow": "must not be called. use (*database/sql.DB).QueryRowContext", |
|
"(*database/sql.Tx).Exec": "must not be called. use (*database/sql.Tx).ExecContext", |
|
"(*database/sql.Tx).Prepare": "must not be called. use (*database/sql.Tx).PrepareContext", |
|
"(*database/sql.Tx).Query": "must not be called. use (*database/sql.Tx).QueryContext", |
|
"(*database/sql.Tx).QueryRow": "must not be called. use (*database/sql.Tx).QueryRowContext", |
|
"(*database/sql.Tx).Stmt": "must not be called. use (*database/sql.Tx).StmtContext", |
|
"(*database/sql.Stmt).Exec": "must not be called. use (*database/sql.Conn).ExecContext", |
|
"(*database/sql.Stmt).Query": "must not be called. use (*database/sql.Conn).QueryContext", |
|
"(*database/sql.Stmt).QueryRow": "must not be called. use (*database/sql.Conn).QueryRowContext", |
|
db.Exec("select * from testdata") // want `\(\*database/sql\.DB\)\.Exec must not be called. use \(\*database/sql\.DB\)\.ExecContext` |
|
// crypto/tls dialer |
|
"crypto/tls.Dial": "must not be called. use (*crypto/tls.Dialer).DialContext", |
|
"crypto/tls.DialWithDialer": "must not be called. use (*crypto/tls.Dialer).DialContext with NetDialer", |
|
"(*crypto/tls.Conn).Handshake": "must not be called. use (*crypto/tls.Conn).HandshakeContext", |
|
tls.Dial("tcp", "localhost:8080", tlsConfig) // want `crypto/tls\.Dial must not be called. use \(\*crypto/tls\.Dialer\)\.DialContext` |
|
// exec |
|
"os/exec.Command": "must not be called. use os/exec.CommandContext", |
|
exec.Command("ls", "-l") // want `os/exec.Command must not be called. use os/exec.CommandContext` |