Skip to content

Commit

Permalink
feat: add musttag linter (#3386)
Browse files Browse the repository at this point in the history
Co-authored-by: Fernandez Ludovic <ldez@users.noreply.github.com>
  • Loading branch information
tmzane and ldez committed Jan 21, 2023
1 parent fb0866a commit 3cc6373
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 0 deletions.
13 changes: 13 additions & 0 deletions .golangci.reference.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1209,6 +1209,17 @@ linters-settings:
ignore-words:
- someword

musttag:
# A set of custom functions to check in addition to the builtin ones.
# Default: json, xml, gopkg.in/yaml.v3, BurntSushi/toml, mitchellh/mapstructure
functions:
# The full name of the function, including the package.
- name: github.com/jmoiron/sqlx.Get
# The struct tag whose presence should be ensured.
tag: db
# The position of the argument to check.
arg-pos: 1

nakedret:
# Make an issue if func has more lines of code than this setting, and it has naked returns.
# Default: 30
Expand Down Expand Up @@ -2037,6 +2048,7 @@ linters:
- makezero
- maligned
- misspell
- musttag
- nakedret
- nestif
- nilerr
Expand Down Expand Up @@ -2145,6 +2157,7 @@ linters:
- makezero
- maligned
- misspell
- musttag
- nakedret
- nestif
- nilerr
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ require (
github.com/jingyugao/rowserrcheck v1.1.1
github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af
github.com/julz/importas v0.1.0
github.com/junk1tm/musttag v0.4.1
github.com/kisielk/errcheck v1.6.3
github.com/kkHAIKE/contextcheck v1.1.3
github.com/kulti/thelper v0.6.3
Expand Down
2 changes: 2 additions & 0 deletions go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions pkg/config/linters_settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ type LintersSettings struct {
Makezero MakezeroSettings
Maligned MalignedSettings
Misspell MisspellSettings
MustTag MustTagSettings
Nakedret NakedretSettings
Nestif NestifSettings
NilNil NilNilSettings
Expand Down Expand Up @@ -538,6 +539,14 @@ type MisspellSettings struct {
IgnoreWords []string `mapstructure:"ignore-words"`
}

type MustTagSettings struct {
Functions []struct {
Name string `mapstructure:"name"`
Tag string `mapstructure:"tag"`
ArgPos int `mapstructure:"arg-pos"`
} `mapstructure:"functions"`
}

type NakedretSettings struct {
MaxFuncLines int `mapstructure:"max-func-lines"`
}
Expand Down
29 changes: 29 additions & 0 deletions pkg/golinters/musttag.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package golinters

import (
"github.com/junk1tm/musttag"
"golang.org/x/tools/go/analysis"

"github.com/golangci/golangci-lint/pkg/config"
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
)

func NewMustTag(setting *config.MustTagSettings) *goanalysis.Linter {
var funcs []musttag.Func

if setting != nil {
for _, fn := range setting.Functions {
funcs = append(funcs, musttag.Func{
Name: fn.Name,
Tag: fn.Tag,
ArgPos: fn.ArgPos,
})
}
}

a := musttag.New(funcs...)

return goanalysis.
NewLinter(a.Name, a.Doc, []*analysis.Analyzer{a}, nil).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
8 changes: 8 additions & 0 deletions pkg/lint/lintersdb/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
makezeroCfg *config.MakezeroSettings
malignedCfg *config.MalignedSettings
misspellCfg *config.MisspellSettings
musttagCfg *config.MustTagSettings
nakedretCfg *config.NakedretSettings
nestifCfg *config.NestifSettings
nilNilCfg *config.NilNilSettings
Expand Down Expand Up @@ -224,6 +225,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
makezeroCfg = &m.cfg.LintersSettings.Makezero
malignedCfg = &m.cfg.LintersSettings.Maligned
misspellCfg = &m.cfg.LintersSettings.Misspell
musttagCfg = &m.cfg.LintersSettings.MustTag
nakedretCfg = &m.cfg.LintersSettings.Nakedret
nestifCfg = &m.cfg.LintersSettings.Nestif
nilNilCfg = &m.cfg.LintersSettings.NilNil
Expand Down Expand Up @@ -632,6 +634,12 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
WithAutoFix().
WithURL("https://github.com/client9/misspell"),

linter.NewConfig(golinters.NewMustTag(musttagCfg)).
WithSince("v1.51.0").
WithLoadForGoAnalysis().
WithPresets(linter.PresetStyle, linter.PresetBugs).
WithURL("https://github.com/junk1tm/musttag"),

linter.NewConfig(golinters.NewNakedret(nakedretCfg)).
WithSince("v1.19.0").
WithPresets(linter.PresetStyle).
Expand Down
9 changes: 9 additions & 0 deletions test/testdata/configs/musttag.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
linters-settings:
musttag:
functions:
- name: encoding/asn1.Marshal
tag: asn1
arg-pos: 0
- name: encoding/asn1.Unmarshal
tag: asn1
arg-pos: 1
27 changes: 27 additions & 0 deletions test/testdata/musttag.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//golangcitest:args -Emusttag
package testdata

import (
"encoding/asn1"
"encoding/json"
)

// builtin functions:
func musttagJSON() {
var user struct { // want `exported fields should be annotated with the "json" tag`
Name string
Email string `json:"email"`
}
json.Marshal(user)
json.Unmarshal(nil, &user)
}

// custom functions from config:
func musttagASN1() {
var user struct {
Name string
Email string `asn1:"email"`
}
asn1.Marshal(user)
asn1.Unmarshal(nil, &user)
}
28 changes: 28 additions & 0 deletions test/testdata/musttag_custom.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//golangcitest:args -Emusttag
//golangcitest:config_path testdata/configs/musttag.yml
package testdata

import (
"encoding/asn1"
"encoding/json"
)

// builtin functions:
func musttagJSONCustom() {
var user struct { // want `exported fields should be annotated with the "json" tag`
Name string
Email string `json:"email"`
}
json.Marshal(user)
json.Unmarshal(nil, &user)
}

// custom functions from config:
func musttagASN1Custom() {
var user struct { // want `exported fields should be annotated with the "asn1" tag`
Name string
Email string `asn1:"email"`
}
asn1.Marshal(user)
asn1.Unmarshal(nil, &user)
}

0 comments on commit 3cc6373

Please sign in to comment.