Skip to content

Commit 71192ef

Browse files
committed
feat: add musttag linter
1 parent d03294f commit 71192ef

File tree

8 files changed

+111
-11
lines changed

8 files changed

+111
-11
lines changed

.golangci.reference.yml

+13
Original file line numberDiff line numberDiff line change
@@ -1190,6 +1190,17 @@ linters-settings:
11901190
ignore-words:
11911191
- someword
11921192

1193+
musttag:
1194+
# A set of custom functions to check in addition to the builtin ones.
1195+
# Default: []
1196+
functions:
1197+
# The full name of the function, including the package.
1198+
- name: github.com/jmoiron/sqlx.Get
1199+
# The struct tag whose presence should be ensured.
1200+
tag: db
1201+
# The position of the argument to check.
1202+
argpos: 1
1203+
11931204
nakedret:
11941205
# Make an issue if func has more lines of code than this setting, and it has naked returns.
11951206
# Default: 30
@@ -2012,6 +2023,7 @@ linters:
20122023
- makezero
20132024
- maligned
20142025
- misspell
2026+
- musttag
20152027
- nakedret
20162028
- nestif
20172029
- nilerr
@@ -2119,6 +2131,7 @@ linters:
21192131
- makezero
21202132
- maligned
21212133
- misspell
2134+
- musttag
21222135
- nakedret
21232136
- nestif
21242137
- nilerr

go.mod

+5-4
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ require (
5151
github.com/jingyugao/rowserrcheck v1.1.1
5252
github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af
5353
github.com/julz/importas v0.1.0
54+
github.com/junk1tm/musttag v0.4.1
5455
github.com/kisielk/errcheck v1.6.2
5556
github.com/kkHAIKE/contextcheck v1.1.2
5657
github.com/kulti/thelper v0.6.3
@@ -107,7 +108,7 @@ require (
107108
github.com/yagipy/maintidx v1.0.0
108109
github.com/yeya24/promlinter v0.2.0
109110
gitlab.com/bosi/decorder v0.2.3
110-
golang.org/x/tools v0.1.12
111+
golang.org/x/tools v0.3.0
111112
gopkg.in/yaml.v3 v3.0.1
112113
honnef.co/go/tools v0.3.3
113114
mvdan.cc/gofumpt v0.4.0
@@ -177,9 +178,9 @@ require (
177178
go.uber.org/zap v1.17.0 // indirect
178179
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect
179180
golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91 // indirect
180-
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
181-
golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde // indirect
182-
golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41 // indirect
181+
golang.org/x/mod v0.7.0 // indirect
182+
golang.org/x/sync v0.1.0 // indirect
183+
golang.org/x/sys v0.2.0 // indirect
183184
golang.org/x/text v0.3.7 // indirect
184185
google.golang.org/protobuf v1.28.0 // indirect
185186
gopkg.in/ini.v1 v1.67.0 // indirect

go.sum

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

pkg/config/linters_settings.go

+9
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ type LintersSettings struct {
178178
Makezero MakezeroSettings
179179
Maligned MalignedSettings
180180
Misspell MisspellSettings
181+
MustTag MustTagSettings
181182
Nakedret NakedretSettings
182183
Nestif NestifSettings
183184
NilNil NilNilSettings
@@ -530,6 +531,14 @@ type MisspellSettings struct {
530531
IgnoreWords []string `mapstructure:"ignore-words"`
531532
}
532533

534+
type MustTagSettings struct {
535+
Functions []struct {
536+
Name string `mapstructure:"name"`
537+
Tag string `mapstructure:"tag"`
538+
ArgPos int `mapstructure:"argpos"`
539+
} `mapstructure:"functions"`
540+
}
541+
533542
type NakedretSettings struct {
534543
MaxFuncLines int `mapstructure:"max-func-lines"`
535544
}

pkg/golinters/musttag.go

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package golinters
2+
3+
import (
4+
"github.com/junk1tm/musttag"
5+
"golang.org/x/tools/go/analysis"
6+
7+
"github.com/golangci/golangci-lint/pkg/config"
8+
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
9+
)
10+
11+
func NewMustTag(setting *config.MustTagSettings) *goanalysis.Linter {
12+
var funcs []musttag.Func
13+
if setting != nil {
14+
for _, fn := range setting.Functions {
15+
funcs = append(funcs, musttag.Func{
16+
Name: fn.Name,
17+
Tag: fn.Tag,
18+
ArgPos: fn.ArgPos,
19+
})
20+
}
21+
}
22+
23+
a := musttag.New(funcs...)
24+
25+
return goanalysis.
26+
NewLinter(a.Name, a.Doc, []*analysis.Analyzer{a}, nil).
27+
WithLoadMode(goanalysis.LoadModeTypesInfo)
28+
}

pkg/lint/lintersdb/manager.go

+8
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
146146
makezeroCfg *config.MakezeroSettings
147147
malignedCfg *config.MalignedSettings
148148
misspellCfg *config.MisspellSettings
149+
musttagCfg *config.MustTagSettings
149150
nakedretCfg *config.NakedretSettings
150151
nestifCfg *config.NestifSettings
151152
nilNilCfg *config.NilNilSettings
@@ -222,6 +223,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
222223
makezeroCfg = &m.cfg.LintersSettings.Makezero
223224
malignedCfg = &m.cfg.LintersSettings.Maligned
224225
misspellCfg = &m.cfg.LintersSettings.Misspell
226+
musttagCfg = &m.cfg.LintersSettings.MustTag
225227
nakedretCfg = &m.cfg.LintersSettings.Nakedret
226228
nestifCfg = &m.cfg.LintersSettings.Nestif
227229
nilNilCfg = &m.cfg.LintersSettings.NilNil
@@ -624,6 +626,12 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
624626
WithAutoFix().
625627
WithURL("https://github.com/client9/misspell"),
626628

629+
linter.NewConfig(golinters.NewMustTag(musttagCfg)).
630+
WithSince("v1.51.0").
631+
WithLoadForGoAnalysis().
632+
WithPresets(linter.PresetStyle, linter.PresetBugs).
633+
WithURL("https://github.com/junk1tm/musttag"),
634+
627635
linter.NewConfig(golinters.NewNakedret(nakedretCfg)).
628636
WithSince("v1.19.0").
629637
WithPresets(linter.PresetStyle).

test/testdata/configs/musttag.yml

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
linters-settings:
2+
musttag:
3+
functions:
4+
- name: encoding/asn1.Marshal
5+
tag: asn1
6+
argpos: 0
7+
- name: encoding/asn1.Unmarshal
8+
tag: asn1
9+
argpos: 1

test/testdata/musttag.go

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//golangcitest:args -Emusttag
2+
//golangcitest:config_path testdata/configs/musttag.yml
3+
package testdata
4+
5+
import (
6+
"encoding/asn1"
7+
"encoding/json"
8+
)
9+
10+
// builtin functions:
11+
func musttagJSON() {
12+
var user struct { // want `\Qexported fields should be annotated with the "json" tag`
13+
Name string
14+
Email string `json:"email"`
15+
}
16+
json.Marshal(user)
17+
json.Unmarshal(nil, &user)
18+
}
19+
20+
// custom functions from config:
21+
func musttagCustom() {
22+
var user struct { // want `\Qexported fields should be annotated with the "asn1" tag`
23+
Name string
24+
Email string `asn1:"email"`
25+
}
26+
asn1.Marshal(user)
27+
asn1.Unmarshal(nil, &user)
28+
}

0 commit comments

Comments
 (0)