Add thelper linter (#1541)

This commit is contained in:
Aleksey Bakin 2020-12-13 16:54:26 +03:00 committed by GitHub
parent d32798769c
commit 0370d3adea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 122 additions and 0 deletions

View File

@ -300,6 +300,17 @@ linters-settings:
testpackage: testpackage:
# regexp pattern to skip files # regexp pattern to skip files
skip-regexp: (export|internal)_test\.go skip-regexp: (export|internal)_test\.go
thelper:
# The following configurations enable all checks. It can be omitted because all checks are enabled by default.
# You can enable only required checks deleting unnecessary checks.
test:
first: true
name: true
begin: true
benchmark:
first: true
name: true
begin: true
unparam: unparam:
# Inspect exported functions, default is false. Set to true if no external program/library imports your code. # Inspect exported functions, default is false. Set to true if no external program/library imports your code.
# XXX: if you enable this setting, unparam will report a lot of false-positives in text editors: # XXX: if you enable this setting, unparam will report a lot of false-positives in text editors:

1
go.mod
View File

@ -30,6 +30,7 @@ require (
github.com/jgautheron/goconst v0.0.0-20201117150253-ccae5bf973f3 github.com/jgautheron/goconst v0.0.0-20201117150253-ccae5bf973f3
github.com/jingyugao/rowserrcheck v0.0.0-20191204022205-72ab7603b68a github.com/jingyugao/rowserrcheck v0.0.0-20191204022205-72ab7603b68a
github.com/jirfag/go-printf-func-name v0.0.0-20191110105641-45db9963cdd3 github.com/jirfag/go-printf-func-name v0.0.0-20191110105641-45db9963cdd3
github.com/kulti/thelper v0.1.0
github.com/kunwardeep/paralleltest v1.0.2 github.com/kunwardeep/paralleltest v1.0.2
github.com/kyoh86/exportloopref v0.1.8 github.com/kyoh86/exportloopref v0.1.8
github.com/maratori/testpackage v1.0.1 github.com/maratori/testpackage v1.0.1

9
go.sum generated
View File

@ -149,6 +149,7 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.3 h1:x95R7cp+rSeeqAMI2knLtQ0DKlaBhv2NrtrOvafPHRo= github.com/google/go-cmp v0.5.3 h1:x95R7cp+rSeeqAMI2knLtQ0DKlaBhv2NrtrOvafPHRo=
@ -168,8 +169,12 @@ github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.m
github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE=
github.com/gostaticanalysis/analysisutil v0.1.0 h1:E4c8Y1EQURbBEAHoXc/jBTK7Np14ArT8NPUiSFOl9yc= github.com/gostaticanalysis/analysisutil v0.1.0 h1:E4c8Y1EQURbBEAHoXc/jBTK7Np14ArT8NPUiSFOl9yc=
github.com/gostaticanalysis/analysisutil v0.1.0/go.mod h1:dMhHRU9KTiDcuLGdy87/2gTR8WruwYZrKdRq9m1O6uw= github.com/gostaticanalysis/analysisutil v0.1.0/go.mod h1:dMhHRU9KTiDcuLGdy87/2gTR8WruwYZrKdRq9m1O6uw=
github.com/gostaticanalysis/analysisutil v0.4.1 h1:/7clKqrVfiVwiBQLM0Uke4KvXnO6JcCTS7HwF2D6wG8=
github.com/gostaticanalysis/analysisutil v0.4.1/go.mod h1:18U/DLpRgIUd459wGxVHE0fRgmo1UgHDcbw7F5idXu0=
github.com/gostaticanalysis/comment v1.3.0 h1:wTVgynbFu8/nz6SGgywA0TcyIoAVsYc7ai/Zp5xNGlw= github.com/gostaticanalysis/comment v1.3.0 h1:wTVgynbFu8/nz6SGgywA0TcyIoAVsYc7ai/Zp5xNGlw=
github.com/gostaticanalysis/comment v1.3.0/go.mod h1:xMicKDx7XRXYdVwY9f9wQpDJVnqWxw9wCauCMKp+IBI= github.com/gostaticanalysis/comment v1.3.0/go.mod h1:xMicKDx7XRXYdVwY9f9wQpDJVnqWxw9wCauCMKp+IBI=
github.com/gostaticanalysis/comment v1.4.1 h1:xHopR5L2lRz6OsjH4R2HG5wRhW9ySl3FsHIvi5pcXwc=
github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= 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/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= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
@ -225,6 +230,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kulti/thelper v0.1.0 h1:ig1EW6yhDiRNN3dplbhdsW2gTvbxTz9i4q5Rr/tRfpk=
github.com/kulti/thelper v0.1.0/go.mod h1:vMu2Cizjy/grP+jmsvOFDx1kYP6+PD1lqg4Yu5exl2U=
github.com/kunwardeep/paralleltest v1.0.2 h1:/jJRv0TiqPoEy/Y8dQxCFJhD56uS/pnvtatgTZBHokU= github.com/kunwardeep/paralleltest v1.0.2 h1:/jJRv0TiqPoEy/Y8dQxCFJhD56uS/pnvtatgTZBHokU=
github.com/kunwardeep/paralleltest v1.0.2/go.mod h1:ZPqNm1fVHPllh5LPVujzbVz1JN2GhLxSfY+oqUsvG30= github.com/kunwardeep/paralleltest v1.0.2/go.mod h1:ZPqNm1fVHPllh5LPVujzbVz1JN2GhLxSfY+oqUsvG30=
github.com/kyoh86/exportloopref v0.1.8 h1:5Ry/at+eFdkX9Vsdw3qU4YkvGtzuVfzT4X7S77LoN/M= github.com/kyoh86/exportloopref v0.1.8 h1:5Ry/at+eFdkX9Vsdw3qU4YkvGtzuVfzT4X7S77LoN/M=
@ -558,11 +565,13 @@ golang.org/x/tools v0.0.0-20200625211823-6506e20df31f/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20200625211823-6506e20df31f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200625211823-6506e20df31f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200812195022-5ae4c3c160a0/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200812195022-5ae4c3c160a0/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200831203904-5a2aa26beb65/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20200831203904-5a2aa26beb65/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
golang.org/x/tools v0.0.0-20201002184944-ecd9fd270d5d/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201002184944-ecd9fd270d5d/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
golang.org/x/tools v0.0.0-20201007032633-0806396f153e/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201007032633-0806396f153e/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
golang.org/x/tools v0.0.0-20201011145850-ed2f50202694/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201011145850-ed2f50202694/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
golang.org/x/tools v0.0.0-20201114224030-61ea331ec02b/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201118003311-bd56c0adb394 h1:O3VD5Fds21mB1WVRTbkiz/HTXESx6Jql5ucPZi69oiM= golang.org/x/tools v0.0.0-20201118003311-bd56c0adb394 h1:O3VD5Fds21mB1WVRTbkiz/HTXESx6Jql5ucPZi69oiM=
golang.org/x/tools v0.0.0-20201118003311-bd56c0adb394/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201118003311-bd56c0adb394/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201121010211-780cb80bd7fb h1:z5+u0pkAUPUWd3taoTialQ2JAMo4Wo1Z3L25U4ZV9r0= golang.org/x/tools v0.0.0-20201121010211-780cb80bd7fb h1:z5+u0pkAUPUWd3taoTialQ2JAMo4Wo1Z3L25U4ZV9r0=

View File

@ -267,6 +267,7 @@ type LintersSettings struct {
Gofumpt GofumptSettings Gofumpt GofumptSettings
ErrorLint ErrorLintSettings ErrorLint ErrorLintSettings
Makezero MakezeroSettings Makezero MakezeroSettings
Thelper ThelperSettings
Custom map[string]CustomLinterSettings Custom map[string]CustomLinterSettings
} }
@ -391,6 +392,19 @@ type MakezeroSettings struct {
Always bool Always bool
} }
type ThelperSettings struct {
Test struct {
First bool `mapstructure:"first"`
Name bool `mapstructure:"name"`
Begin bool `mapstructure:"begin"`
} `mapstructure:"test"`
Benchmark struct {
First bool `mapstructure:"first"`
Name bool `mapstructure:"name"`
Begin bool `mapstructure:"begin"`
} `mapstructure:"benchmark"`
}
var defaultLintersSettings = LintersSettings{ var defaultLintersSettings = LintersSettings{
Lll: LllSettings{ Lll: LllSettings{
LineLength: 120, LineLength: 120,

51
pkg/golinters/thelper.go Normal file
View File

@ -0,0 +1,51 @@
package golinters
import (
"strings"
"github.com/kulti/thelper/pkg/analyzer"
"golang.org/x/tools/go/analysis"
"github.com/golangci/golangci-lint/pkg/config"
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
)
func NewThelper(cfg *config.ThelperSettings) *goanalysis.Linter {
a := analyzer.NewAnalyzer()
cfgMap := map[string]map[string]interface{}{}
if cfg != nil {
var opts []string
if cfg.Test.Name {
opts = append(opts, "t_name")
}
if cfg.Test.Begin {
opts = append(opts, "t_begin")
}
if cfg.Test.First {
opts = append(opts, "t_first")
}
if cfg.Benchmark.Name {
opts = append(opts, "b_name")
}
if cfg.Benchmark.Begin {
opts = append(opts, "b_begin")
}
if cfg.Benchmark.First {
opts = append(opts, "b_first")
}
cfgMap[a.Name] = map[string]interface{}{
"checks": strings.Join(opts, ","),
}
}
return goanalysis.NewLinter(
"thelper",
"thelper detects golang test helpers without t.Helper() call and checks the consistency of test helpers",
[]*analysis.Analyzer{a},
cfgMap,
).WithLoadMode(goanalysis.LoadModeTypesInfo)
}

View File

@ -91,11 +91,13 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
var testpackageCfg *config.TestpackageSettings var testpackageCfg *config.TestpackageSettings
var exhaustiveCfg *config.ExhaustiveSettings var exhaustiveCfg *config.ExhaustiveSettings
var errorlintCfg *config.ErrorLintSettings var errorlintCfg *config.ErrorLintSettings
var thelperCfg *config.ThelperSettings
if m.cfg != nil { if m.cfg != nil {
govetCfg = &m.cfg.LintersSettings.Govet govetCfg = &m.cfg.LintersSettings.Govet
testpackageCfg = &m.cfg.LintersSettings.Testpackage testpackageCfg = &m.cfg.LintersSettings.Testpackage
exhaustiveCfg = &m.cfg.LintersSettings.Exhaustive exhaustiveCfg = &m.cfg.LintersSettings.Exhaustive
errorlintCfg = &m.cfg.LintersSettings.ErrorLint errorlintCfg = &m.cfg.LintersSettings.ErrorLint
thelperCfg = &m.cfg.LintersSettings.Thelper
} }
const megacheckName = "megacheck" const megacheckName = "megacheck"
lcs := []*linter.Config{ lcs := []*linter.Config{
@ -313,6 +315,10 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
WithPresets(linter.PresetStyle). WithPresets(linter.PresetStyle).
WithLoadForGoAnalysis(). WithLoadForGoAnalysis().
WithURL("https://github.com/tomarrell/wrapcheck"), WithURL("https://github.com/tomarrell/wrapcheck"),
linter.NewConfig(golinters.NewThelper(thelperCfg)).
WithPresets(linter.PresetStyle).
WithLoadForGoAnalysis().
WithURL("https://github.com/kulti/thelper"),
linter.NewConfig(golinters.NewTparallel()). linter.NewConfig(golinters.NewTparallel()).
WithPresets(linter.PresetStyle). WithPresets(linter.PresetStyle).
WithLoadForGoAnalysis(). WithLoadForGoAnalysis().

30
test/testdata/thelper.go vendored Normal file
View File

@ -0,0 +1,30 @@
//args: -Ethelper
package testdata
import "testing"
func thelperWithHelperAfterAssignment(t *testing.T) { // ERROR "test helper function should start from t.Helper()"
_ = 0
t.Helper()
}
func thelperWithNotFirst(s string, t *testing.T, i int) { // ERROR "parameter \*testing.T should be the first"
t.Helper()
}
func thelperWithIncorrectName(o *testing.T) { // ERROR "parameter \*testing.T should have name t"
o.Helper()
}
func bhelperWithHelperAfterAssignment(b *testing.B) { // ERROR "test helper function should start from b.Helper()"
_ = 0
b.Helper()
}
func bhelperWithNotFirst(s string, b *testing.B, i int) { // ERROR "parameter \*testing.B should be the first"
b.Helper()
}
func bhelperWithIncorrectName(o *testing.B) { // ERROR "parameter \*testing.B should have name b"
o.Helper()
}