Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tagliatelle linter #1906

Merged
merged 1 commit into from Apr 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 14 additions & 0 deletions .golangci.example.yml
Expand Up @@ -478,6 +478,20 @@ linters-settings:
retract-allow-no-explanation: false
# Forbid the use of the `exclude` directives. Default is false.
exclude-forbidden: false
tagliatelle:
# check the struck tag name case
case:
# use the struct field name to check the name of the struct tag
use-field-name: true
rules:
# any struct tag type can be used.
# support string case: `camel`, `pascal`, `kebab`, `snake`, `goCamel`, `goPascal`, `goKebab`, `goSnake`, `upper`, `lower`
json: camel
yaml: camel
xml: camel
bson: camel
avro: snake
mapstructure: kebab

# The custom section can be used to define linter plugins to be loaded at runtime. See README doc
# for more info.
Expand Down
1 change: 1 addition & 0 deletions go.mod
Expand Up @@ -43,6 +43,7 @@ require (
github.com/kunwardeep/paralleltest v1.0.2
github.com/kyoh86/exportloopref v0.1.8
github.com/ldez/gomoddirectives v0.2.1
github.com/ldez/tagliatelle v0.2.0
github.com/maratori/testpackage v1.0.1
github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 // v1.0
github.com/mattn/go-colorable v0.1.8
Expand Down
4 changes: 4 additions & 0 deletions go.sum

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

8 changes: 8 additions & 0 deletions pkg/config/config.go
Expand Up @@ -278,6 +278,7 @@ type LintersSettings struct {
ImportAs ImportAsSettings
GoModDirectives GoModDirectivesSettings
Promlinter PromlinterSettings
Tagliatelle TagliatelleSettings

Custom map[string]CustomLinterSettings
}
Expand Down Expand Up @@ -478,6 +479,13 @@ type GoModDirectivesSettings struct {
RetractAllowNoExplanation bool `mapstructure:"retract-allow-no-explanation"`
}

type TagliatelleSettings struct {
Case struct {
Rules map[string]string
UseFieldName bool `mapstructure:"use-field-name"`
}
}

var defaultLintersSettings = LintersSettings{
Lll: LllSettings{
LineLength: 120,
Expand Down
30 changes: 30 additions & 0 deletions pkg/golinters/tagliatelle.go
@@ -0,0 +1,30 @@
package golinters

import (
"github.com/ldez/tagliatelle"
"golang.org/x/tools/go/analysis"

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

func NewTagliatelle(settings *config.TagliatelleSettings) *goanalysis.Linter {
cfg := tagliatelle.Config{
Rules: map[string]string{
"json": "camel",
"yaml": "camel",
},
}

if settings != nil {
for k, v := range settings.Case.Rules {
cfg.Rules[k] = v
}
cfg.UseFieldName = settings.Case.UseFieldName
}

a := tagliatelle.New(cfg)

return goanalysis.NewLinter(a.Name, a.Doc, []*analysis.Analyzer{a}, nil).
WithLoadMode(goanalysis.LoadModeSyntax)
}
7 changes: 7 additions & 0 deletions pkg/lint/lintersdb/manager.go
Expand Up @@ -112,6 +112,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
var cyclopCfg *config.Cyclop
var importAsCfg *config.ImportAsSettings
var goModDirectivesCfg *config.GoModDirectivesSettings
var tagliatelleCfg *config.TagliatelleSettings

if m.cfg != nil {
govetCfg = &m.cfg.LintersSettings.Govet
Expand All @@ -126,6 +127,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
cyclopCfg = &m.cfg.LintersSettings.Cyclop
importAsCfg = &m.cfg.LintersSettings.ImportAs
goModDirectivesCfg = &m.cfg.LintersSettings.GoModDirectives
tagliatelleCfg = &m.cfg.LintersSettings.Tagliatelle
}

const megacheckName = "megacheck"
Expand Down Expand Up @@ -483,6 +485,11 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
WithSince("v1.40.0").
WithPresets(linter.PresetStyle).
WithURL("https://github.com/yeya24/promlinter"),
linter.NewConfig(golinters.NewTagliatelle(tagliatelleCfg)).
WithSince("v1.40.0").
WithPresets(linter.PresetStyle).
WithURL("https://github.com/ldez/tagliatelle"),

// nolintlint must be last because it looks at the results of all the previous linters for unused nolint directives
linter.NewConfig(golinters.NewNoLintLint()).
WithSince("v1.26.0").
Expand Down
33 changes: 33 additions & 0 deletions test/testdata/tagliatelle.go
@@ -0,0 +1,33 @@
//args: -Etagliatelle
package testdata

import "time"

type TglFoo struct {
ID string `json:"ID"` // ERROR `json\(camel\): got 'ID' want 'id'`
UserID string `json:"UserID"` // ERROR `json\(camel\): got 'UserID' want 'userId'`
Name string `json:"name"`
Value time.Duration `json:"value,omitempty"`
Bar TglBar `json:"bar"`
Bur `json:"bur"`
}

type TglBar struct {
Name string `json:"-"`
Value string `json:"value"`
CommonServiceFooItem *TglBir `json:"CommonServiceItem,omitempty"` // ERROR `json\(camel\): got 'CommonServiceItem' want 'commonServiceItem'`
}

type TglBir struct {
Name string `json:"-"`
Value string `json:"value"`
ReplaceAllowList []string `mapstructure:"replace-allow-list"`
}

type Bur struct {
Name string
Value string `yaml:"Value"` // ERROR `yaml\(camel\): got 'Value' want 'value'`
More string `json:"-"`
Also string `json:",omitempty"`
ReqPerS string `avro:"req_per_s"`
}