Skip to content

Commit 0640d3f

Browse files
authored
Add UseTesting linter (#5170)
1 parent d74f1ae commit 0640d3f

15 files changed

+307
-2
lines changed

.golangci.next.reference.yml

+34
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ linters:
114114
- unparam
115115
- unused
116116
- usestdlibvars
117+
- usetesting
117118
- varnamelen
118119
- wastedassign
119120
- whitespace
@@ -230,6 +231,7 @@ linters:
230231
- unparam
231232
- unused
232233
- usestdlibvars
234+
- usetesting
233235
- varnamelen
234236
- wastedassign
235237
- whitespace
@@ -3533,6 +3535,38 @@ linters-settings:
35333535
# Default: false
35343536
constant-kind: true
35353537

3538+
usetesting:
3539+
# Enable/disable `os.CreateTemp("", ...)` detections.
3540+
# Default: true
3541+
os-create-temp: false
3542+
3543+
# Enable/disable `os.MkdirTemp()` detections.
3544+
# Default: true
3545+
os-mkdir-temp: false
3546+
3547+
# Enable/disable `os.Setenv()` detections.
3548+
# Default: false
3549+
os-setenv: true
3550+
3551+
# Enable/disable `os.TempDir()` detections.
3552+
# Default: false
3553+
os-temp-dir: true
3554+
3555+
# Enable/disable `os.Chdir()` detections.
3556+
# Disabled if Go < 1.24.
3557+
# Default: true
3558+
os-chdir: false
3559+
3560+
# Enable/disable `context.Background()` detections.
3561+
# Disabled if Go < 1.24.
3562+
# Default: true
3563+
context-background: false
3564+
3565+
# Enable/disable `context.TODO()` detections.
3566+
# Disabled if Go < 1.24.
3567+
# Default: true
3568+
context-todo: false
3569+
35363570
unconvert:
35373571
# Remove conversions that force intermediate rounding.
35383572
# Default: false

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ require (
6868
github.com/lasiar/canonicalheader v1.1.2
6969
github.com/ldez/gomoddirectives v0.2.4
7070
github.com/ldez/tagliatelle v0.6.0
71+
github.com/ldez/usetesting v0.2.0
7172
github.com/leonklingele/grouper v1.1.2
7273
github.com/macabu/inamedparam v0.1.3
7374
github.com/maratori/testableexamples v1.0.0

go.sum

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

jsonschema/golangci.next.jsonschema.json

+35
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,7 @@
428428
"unparam",
429429
"unused",
430430
"usestdlibvars",
431+
"usetesting",
431432
"varnamelen",
432433
"wastedassign",
433434
"whitespace",
@@ -3325,6 +3326,40 @@
33253326
}
33263327
}
33273328
},
3329+
"usetesting": {
3330+
"type": "object",
3331+
"additionalProperties": false,
3332+
"properties": {
3333+
"context-background": {
3334+
"type": "boolean",
3335+
"default": true
3336+
},
3337+
"context-todo": {
3338+
"type": "boolean",
3339+
"default": true
3340+
},
3341+
"os-chdir": {
3342+
"type": "boolean",
3343+
"default": true
3344+
},
3345+
"os-mkdir-temp": {
3346+
"type": "boolean",
3347+
"default": true
3348+
},
3349+
"os-setenv": {
3350+
"type": "boolean",
3351+
"default": false
3352+
},
3353+
"os-create-temp": {
3354+
"type": "boolean",
3355+
"default": true
3356+
},
3357+
"os-temp-dir": {
3358+
"type": "boolean",
3359+
"default": false
3360+
}
3361+
}
3362+
},
33283363
"unconvert": {
33293364
"type": "object",
33303365
"additionalProperties": false,

pkg/config/linters_settings.go

+20
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,15 @@ var defaultLintersSettings = LintersSettings{
179179
HTTPMethod: true,
180180
HTTPStatusCode: true,
181181
},
182+
UseTesting: UseTestingSettings{
183+
ContextBackground: true,
184+
ContextTodo: true,
185+
OSChdir: true,
186+
OSMkdirTemp: true,
187+
OSSetenv: false,
188+
OSTempDir: false,
189+
OSCreateTemp: true,
190+
},
182191
Varnamelen: VarnamelenSettings{
183192
MaxDistance: 5,
184193
MinNameLength: 3,
@@ -278,6 +287,7 @@ type LintersSettings struct {
278287
Unparam UnparamSettings
279288
Unused UnusedSettings
280289
UseStdlibVars UseStdlibVarsSettings
290+
UseTesting UseTestingSettings
281291
Varnamelen VarnamelenSettings
282292
Whitespace WhitespaceSettings
283293
Wrapcheck WrapcheckSettings
@@ -959,6 +969,16 @@ type UseStdlibVarsSettings struct {
959969
SyslogPriority bool `mapstructure:"syslog-priority"` // Deprecated
960970
}
961971

972+
type UseTestingSettings struct {
973+
ContextBackground bool `mapstructure:"context-background"`
974+
ContextTodo bool `mapstructure:"context-todo"`
975+
OSChdir bool `mapstructure:"os-chdir"`
976+
OSMkdirTemp bool `mapstructure:"os-mkdir-temp"`
977+
OSSetenv bool `mapstructure:"os-setenv"`
978+
OSTempDir bool `mapstructure:"os-temp-dir"`
979+
OSCreateTemp bool `mapstructure:"os-create-temp"`
980+
}
981+
962982
type UnconvertSettings struct {
963983
FastMath bool `mapstructure:"fast-math"`
964984
Safe bool `mapstructure:"safe"`
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//golangcitest:args -Eusetesting
2+
package testdata
3+
4+
import (
5+
"os"
6+
"testing"
7+
)
8+
9+
func Test_osMkdirTemp(t *testing.T) {
10+
os.MkdirTemp("", "") // want `os\.MkdirTemp\(\) could be replaced by t\.TempDir\(\) in .+`
11+
}
12+
13+
func Test_osSetenv(t *testing.T) {
14+
os.Setenv("", "")
15+
}
16+
17+
func Test_osTempDir(t *testing.T) {
18+
os.TempDir()
19+
}
20+
21+
func Test_osCreateTemp(t *testing.T) {
22+
os.CreateTemp("", "") // want `os\.CreateTemp\("", \.\.\.\) could be replaced by os\.CreateTemp\(t\.TempDir\(\), \.\.\.\) in .+`
23+
os.CreateTemp("", "xx") // want `os\.CreateTemp\("", \.\.\.\) could be replaced by os\.CreateTemp\(t\.TempDir\(\), \.\.\.\) in .+`
24+
os.CreateTemp(os.TempDir(), "xx")
25+
os.CreateTemp(t.TempDir(), "xx")
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//golangcitest:args -Eusetesting
2+
//golangcitest:config_path testdata/usetesting_configuration.yml
3+
package testdata
4+
5+
import (
6+
"os"
7+
"testing"
8+
)
9+
10+
func Test_osMkdirTemp(t *testing.T) {
11+
os.MkdirTemp("", "")
12+
}
13+
14+
func Test_osTempDir(t *testing.T) {
15+
os.TempDir() // want `os\.TempDir\(\) could be replaced by t\.TempDir\(\) in .+`
16+
}
17+
18+
func Test_osSetenv(t *testing.T) {
19+
os.Setenv("", "") // want `os\.Setenv\(\) could be replaced by t\.Setenv\(\) in .+`
20+
}
21+
22+
func Test_osCreateTemp(t *testing.T) {
23+
os.CreateTemp("", "")
24+
os.CreateTemp("", "xx")
25+
os.CreateTemp(os.TempDir(), "xx") // want `os\.TempDir\(\) could be replaced by t\.TempDir\(\) in .+`
26+
os.CreateTemp(t.TempDir(), "xx")
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
linters-settings:
2+
usetesting:
3+
os-create-temp: false
4+
os-mkdir-temp: false
5+
os-setenv: true
6+
os-temp-dir: true
7+
os-chdir: false
8+
context-background: false
9+
context-todo: false
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//go:build go1.24
2+
3+
//golangcitest:args -Eusetesting
4+
package testdata
5+
6+
import (
7+
"context"
8+
"os"
9+
"testing"
10+
)
11+
12+
func Test_contextBackground(t *testing.T) {
13+
context.Background() // want `context\.Background\(\) could be replaced by t\.Context\(\) in .+`
14+
}
15+
16+
func Test_contextTODO(t *testing.T) {
17+
context.TODO() // want `context\.TODO\(\) could be replaced by t\.Context\(\) in .+`
18+
}
19+
20+
func Test_osChdir(t *testing.T) {
21+
os.Chdir("") // want `os\.Chdir\(\) could be replaced by t\.Chdir\(\) in .+`
22+
}
23+
24+
func Test_osMkdirTemp(t *testing.T) {
25+
os.MkdirTemp("", "") // want `os\.MkdirTemp\(\) could be replaced by t\.TempDir\(\) in .+`
26+
}
27+
28+
func Test_osSetenv(t *testing.T) {
29+
os.Setenv("", "")
30+
}
31+
32+
func Test_osTempDir(t *testing.T) {
33+
os.TempDir()
34+
}
35+
36+
func Test_osCreateTemp(t *testing.T) {
37+
os.CreateTemp("", "") // want `os\.CreateTemp\("", \.\.\.\) could be replaced by os\.CreateTemp\(t\.TempDir\(\), \.\.\.\) in .+`
38+
os.CreateTemp("", "xx") // want `os\.CreateTemp\("", \.\.\.\) could be replaced by os\.CreateTemp\(t\.TempDir\(\), \.\.\.\) in .+`
39+
os.CreateTemp(os.TempDir(), "xx")
40+
os.CreateTemp(t.TempDir(), "xx")
41+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
//go:build go1.24
2+
3+
//golangcitest:args -Eusetesting
4+
//golangcitest:config_path testdata/usetesting_go124_configuration.yml
5+
package testdata
6+
7+
import (
8+
"context"
9+
"os"
10+
"testing"
11+
)
12+
13+
func Test_contextBackground(t *testing.T) {
14+
context.Background()
15+
}
16+
17+
func Test_contextTODO(t *testing.T) {
18+
context.TODO()
19+
}
20+
21+
func Test_osChdir(t *testing.T) {
22+
os.Chdir("")
23+
}
24+
25+
func Test_osMkdirTemp(t *testing.T) {
26+
os.MkdirTemp("", "")
27+
}
28+
29+
func Test_osSetenv(t *testing.T) {
30+
os.Setenv("", "") // want `os\.Setenv\(\) could be replaced by t\.Setenv\(\) in .+`
31+
}
32+
33+
func Test_osTempDir(t *testing.T) {
34+
os.TempDir() // want `os\.TempDir\(\) could be replaced by t\.TempDir\(\) in .+`
35+
}
36+
37+
func Test_osCreateTemp(t *testing.T) {
38+
os.CreateTemp("", "")
39+
os.CreateTemp("", "xx")
40+
os.CreateTemp(os.TempDir(), "xx") // want `os\.TempDir\(\) could be replaced by t\.TempDir\(\) in .+`
41+
os.CreateTemp(t.TempDir(), "xx")
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
linters-settings:
2+
usetesting:
3+
os-create-temp: false
4+
os-mkdir-temp: false
5+
os-setenv: true
6+
os-temp-dir: true
7+
os-chdir: false
8+
context-background: false
9+
context-todo: false
+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package usetesting
2+
3+
import (
4+
"github.com/ldez/usetesting"
5+
"golang.org/x/tools/go/analysis"
6+
7+
"github.com/golangci/golangci-lint/pkg/config"
8+
"github.com/golangci/golangci-lint/pkg/goanalysis"
9+
)
10+
11+
func New(settings *config.UseTestingSettings) *goanalysis.Linter {
12+
a := usetesting.NewAnalyzer()
13+
14+
cfg := make(map[string]map[string]any)
15+
if settings != nil {
16+
cfg[a.Name] = map[string]any{
17+
"contextbackground": settings.ContextBackground,
18+
"contexttodo": settings.ContextTodo,
19+
"oschdir": settings.OSChdir,
20+
"osmkdirtemp": settings.OSMkdirTemp,
21+
"ossetenv": settings.OSSetenv,
22+
"ostempdir": settings.OSTempDir,
23+
"oscreatetemp": settings.OSCreateTemp,
24+
}
25+
}
26+
27+
return goanalysis.NewLinter(
28+
a.Name,
29+
a.Doc,
30+
[]*analysis.Analyzer{a},
31+
cfg,
32+
).WithLoadMode(goanalysis.LoadModeTypesInfo)
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package usetesting
2+
3+
import (
4+
"testing"
5+
6+
"github.com/golangci/golangci-lint/test/testshared/integration"
7+
)
8+
9+
func TestFromTestdata(t *testing.T) {
10+
integration.RunTestdata(t)
11+
}

pkg/lint/linter/config.go

+10-2
Original file line numberDiff line numberDiff line change
@@ -164,12 +164,20 @@ func (lc *Config) WithNoopFallback(cfg *config.Config, cond func(cfg *config.Con
164164
}
165165

166166
func IsGoLowerThanGo122() func(cfg *config.Config) error {
167+
return isGoLowerThanGo("1.22")
168+
}
169+
170+
func IsGoLowerThanGo124() func(cfg *config.Config) error {
171+
return isGoLowerThanGo("1.24")
172+
}
173+
174+
func isGoLowerThanGo(v string) func(cfg *config.Config) error {
167175
return func(cfg *config.Config) error {
168-
if cfg == nil || config.IsGoGreaterThanOrEqual(cfg.Run.Go, "1.22") {
176+
if cfg == nil || config.IsGoGreaterThanOrEqual(cfg.Run.Go, v) {
169177
return nil
170178
}
171179

172-
return fmt.Errorf("this linter is disabled because the Go version (%s) of your project is lower than Go 1.22", cfg.Run.Go)
180+
return fmt.Errorf("this linter is disabled because the Go version (%s) of your project is lower than Go %s", cfg.Run.Go, v)
173181
}
174182
}
175183

0 commit comments

Comments
 (0)