feat: add sloglint
linter (#4133)
This commit is contained in:
parent
cf93cf57dd
commit
39c5fd10ae
@ -1799,6 +1799,20 @@ linters-settings:
|
||||
packages:
|
||||
- github.com/jmoiron/sqlx
|
||||
|
||||
sloglint:
|
||||
# Enforce using key-value pairs only (incompatible with attr-only).
|
||||
# Default: false
|
||||
kv-only: true
|
||||
# Enforce using attributes only (incompatible with kv-only).
|
||||
# Default: false
|
||||
attr-only: true
|
||||
# Enforce using constants instead of raw keys.
|
||||
# Default: false
|
||||
no-raw-keys: true
|
||||
# Enforce putting arguments on separate lines.
|
||||
# Default: false
|
||||
args-on-sep-lines: true
|
||||
|
||||
staticcheck:
|
||||
# Deprecated: use the global `run.go` instead.
|
||||
go: "1.15"
|
||||
@ -2295,6 +2309,7 @@ linters:
|
||||
- revive
|
||||
- rowserrcheck
|
||||
- scopelint
|
||||
- sloglint
|
||||
- sqlclosecheck
|
||||
- staticcheck
|
||||
- structcheck
|
||||
@ -2413,6 +2428,7 @@ linters:
|
||||
- revive
|
||||
- rowserrcheck
|
||||
- scopelint
|
||||
- sloglint
|
||||
- sqlclosecheck
|
||||
- staticcheck
|
||||
- structcheck
|
||||
|
1
go.mod
1
go.mod
@ -119,6 +119,7 @@ require (
|
||||
github.com/yeya24/promlinter v0.2.0
|
||||
github.com/ykadowak/zerologlint v0.1.3
|
||||
gitlab.com/bosi/decorder v0.4.1
|
||||
go-simpler.org/sloglint v0.1.2
|
||||
go.tmz.dev/musttag v0.7.2
|
||||
golang.org/x/exp v0.0.0-20230510235704-dd950f8aeaea
|
||||
golang.org/x/tools v0.14.0
|
||||
|
2
go.sum
generated
2
go.sum
generated
@ -587,6 +587,8 @@ github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQ
|
||||
gitlab.com/bosi/decorder v0.4.1 h1:VdsdfxhstabyhZovHafFw+9eJ6eU0d2CkFNJcZz/NU4=
|
||||
gitlab.com/bosi/decorder v0.4.1/go.mod h1:jecSqWUew6Yle1pCr2eLWTensJMmsxHsBwt+PVbkAqA=
|
||||
go-simpler.org/assert v0.6.0 h1:QxSrXa4oRuo/1eHMXSBFHKvJIpWABayzKldqZyugG7E=
|
||||
go-simpler.org/sloglint v0.1.2 h1:IjdhF8NPxyn0Ckn2+fuIof7ntSnVUAqBFcQRrnG9AiM=
|
||||
go-simpler.org/sloglint v0.1.2/go.mod h1:2LL+QImPfTslD5muNPydAEYmpXIj6o/WYcqnJjLi4o4=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
|
@ -113,6 +113,12 @@ var defaultLintersSettings = LintersSettings{
|
||||
Ignore: "",
|
||||
Qualified: false,
|
||||
},
|
||||
SlogLint: SlogLintSettings{
|
||||
KVOnly: false,
|
||||
AttrOnly: false,
|
||||
NoRawKeys: false,
|
||||
ArgsOnSepLines: false,
|
||||
},
|
||||
TagAlign: TagAlignSettings{
|
||||
Align: true,
|
||||
Sort: true,
|
||||
@ -222,6 +228,7 @@ type LintersSettings struct {
|
||||
Reassign ReassignSettings
|
||||
Revive ReviveSettings
|
||||
RowsErrCheck RowsErrCheckSettings
|
||||
SlogLint SlogLintSettings
|
||||
Staticcheck StaticCheckSettings
|
||||
Structcheck StructCheckSettings
|
||||
Stylecheck StaticCheckSettings
|
||||
@ -717,6 +724,13 @@ type RowsErrCheckSettings struct {
|
||||
Packages []string
|
||||
}
|
||||
|
||||
type SlogLintSettings struct {
|
||||
KVOnly bool `mapstructure:"kv-only"`
|
||||
AttrOnly bool `mapstructure:"attr-only"`
|
||||
NoRawKeys bool `mapstructure:"no-raw-keys"`
|
||||
ArgsOnSepLines bool `mapstructure:"args-on-sep-lines"`
|
||||
}
|
||||
|
||||
type StaticCheckSettings struct {
|
||||
// Deprecated: use the global `run.go` instead.
|
||||
GoVersion string `mapstructure:"go"`
|
||||
|
27
pkg/golinters/sloglint.go
Normal file
27
pkg/golinters/sloglint.go
Normal file
@ -0,0 +1,27 @@
|
||||
package golinters
|
||||
|
||||
import (
|
||||
"go-simpler.org/sloglint"
|
||||
"golang.org/x/tools/go/analysis"
|
||||
|
||||
"github.com/golangci/golangci-lint/pkg/config"
|
||||
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
|
||||
)
|
||||
|
||||
func NewSlogLint(settings *config.SlogLintSettings) *goanalysis.Linter {
|
||||
var opts *sloglint.Options
|
||||
if settings != nil {
|
||||
opts = &sloglint.Options{
|
||||
KVOnly: settings.KVOnly,
|
||||
AttrOnly: settings.AttrOnly,
|
||||
NoRawKeys: settings.NoRawKeys,
|
||||
ArgsOnSepLines: settings.ArgsOnSepLines,
|
||||
}
|
||||
}
|
||||
|
||||
a := sloglint.New(opts)
|
||||
|
||||
return goanalysis.
|
||||
NewLinter(a.Name, a.Doc, []*analysis.Analyzer{a}, nil).
|
||||
WithLoadMode(goanalysis.LoadModeTypesInfo)
|
||||
}
|
@ -127,6 +127,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
|
||||
reassignCfg *config.ReassignSettings
|
||||
reviveCfg *config.ReviveSettings
|
||||
rowserrcheckCfg *config.RowsErrCheckSettings
|
||||
sloglintCfg *config.SlogLintSettings
|
||||
staticcheckCfg *config.StaticCheckSettings
|
||||
structcheckCfg *config.StructCheckSettings
|
||||
stylecheckCfg *config.StaticCheckSettings
|
||||
@ -208,6 +209,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
|
||||
reassignCfg = &m.cfg.LintersSettings.Reassign
|
||||
reviveCfg = &m.cfg.LintersSettings.Revive
|
||||
rowserrcheckCfg = &m.cfg.LintersSettings.RowsErrCheck
|
||||
sloglintCfg = &m.cfg.LintersSettings.SlogLint
|
||||
staticcheckCfg = &m.cfg.LintersSettings.Staticcheck
|
||||
structcheckCfg = &m.cfg.LintersSettings.Structcheck
|
||||
stylecheckCfg = &m.cfg.LintersSettings.Stylecheck
|
||||
@ -750,6 +752,12 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
|
||||
WithPresets(linter.PresetBugs, linter.PresetSQL).
|
||||
WithURL("https://github.com/jingyugao/rowserrcheck"),
|
||||
|
||||
linter.NewConfig(golinters.NewSlogLint(sloglintCfg)).
|
||||
WithSince("v1.55.0").
|
||||
WithLoadForGoAnalysis().
|
||||
WithPresets(linter.PresetStyle, linter.PresetFormatting).
|
||||
WithURL("https://github.com/go-simpler/sloglint"),
|
||||
|
||||
linter.NewConfig(golinters.NewScopelint()).
|
||||
WithSince("v1.12.0").
|
||||
WithPresets(linter.PresetBugs).
|
||||
|
3
test/testdata/configs/sloglint_args_on_sep_lines.yml
vendored
Normal file
3
test/testdata/configs/sloglint_args_on_sep_lines.yml
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
linters-settings:
|
||||
sloglint:
|
||||
args-on-sep-lines: true
|
3
test/testdata/configs/sloglint_attr_only.yml
vendored
Normal file
3
test/testdata/configs/sloglint_attr_only.yml
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
linters-settings:
|
||||
sloglint:
|
||||
attr-only: true
|
3
test/testdata/configs/sloglint_kv_only.yml
vendored
Normal file
3
test/testdata/configs/sloglint_kv_only.yml
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
linters-settings:
|
||||
sloglint:
|
||||
kv-only: true
|
3
test/testdata/configs/sloglint_no_raw_keys.yml
vendored
Normal file
3
test/testdata/configs/sloglint_no_raw_keys.yml
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
linters-settings:
|
||||
sloglint:
|
||||
no-raw-keys: true
|
13
test/testdata/sloglint.go
vendored
Normal file
13
test/testdata/sloglint.go
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
//go:build go1.21
|
||||
|
||||
//golangcitest:args -Esloglint
|
||||
package testdata
|
||||
|
||||
import "log/slog"
|
||||
|
||||
func test() {
|
||||
slog.Info("msg", "foo", 1, "bar", 2)
|
||||
slog.Info("msg", slog.Int("foo", 1), slog.Int("bar", 2))
|
||||
|
||||
slog.Info("msg", "foo", 1, slog.Int("bar", 2)) // want `key-value pairs and attributes should not be mixed`
|
||||
}
|
17
test/testdata/sloglint_args_on_sep_lines.go
vendored
Normal file
17
test/testdata/sloglint_args_on_sep_lines.go
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
//go:build go1.21
|
||||
|
||||
//golangcitest:args -Esloglint
|
||||
//golangcitest:config_path testdata/configs/sloglint_args_on_sep_lines.yml
|
||||
package testdata
|
||||
|
||||
import "log/slog"
|
||||
|
||||
func test() {
|
||||
slog.Info("msg", "foo", 1)
|
||||
slog.Info("msg",
|
||||
"foo", 1,
|
||||
"bar", 2,
|
||||
)
|
||||
|
||||
slog.Info("msg", "foo", 1, "bar", 2) // want `arguments should be put on separate lines`
|
||||
}
|
13
test/testdata/sloglint_attr_only.go
vendored
Normal file
13
test/testdata/sloglint_attr_only.go
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
//go:build go1.21
|
||||
|
||||
//golangcitest:args -Esloglint
|
||||
//golangcitest:config_path testdata/configs/sloglint_attr_only.yml
|
||||
package testdata
|
||||
|
||||
import "log/slog"
|
||||
|
||||
func test() {
|
||||
slog.Info("msg", slog.Int("foo", 1), slog.Int("bar", 2))
|
||||
|
||||
slog.Info("msg", "foo", 1, "bar", 2) // want `key-value pairs should not be used`
|
||||
}
|
13
test/testdata/sloglint_kv_only.go
vendored
Normal file
13
test/testdata/sloglint_kv_only.go
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
//go:build go1.21
|
||||
|
||||
//golangcitest:args -Esloglint
|
||||
//golangcitest:config_path testdata/configs/sloglint_kv_only.yml
|
||||
package testdata
|
||||
|
||||
import "log/slog"
|
||||
|
||||
func test() {
|
||||
slog.Info("msg", "foo", 1, "bar", 2)
|
||||
|
||||
slog.Info("msg", slog.Int("foo", 1), slog.Int("bar", 2)) // want `attributes should not be used`
|
||||
}
|
21
test/testdata/sloglint_no_raw_keys.go
vendored
Normal file
21
test/testdata/sloglint_no_raw_keys.go
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
//go:build go1.21
|
||||
|
||||
//golangcitest:args -Esloglint
|
||||
//golangcitest:config_path testdata/configs/sloglint_no_raw_keys.yml
|
||||
package testdata
|
||||
|
||||
import "log/slog"
|
||||
|
||||
const foo = "foo"
|
||||
|
||||
func Foo(value int) slog.Attr {
|
||||
return slog.Int("foo", value)
|
||||
}
|
||||
|
||||
func test() {
|
||||
slog.Info("msg", foo, 1)
|
||||
slog.Info("msg", Foo(1))
|
||||
|
||||
slog.Info("msg", "foo", 1) // want `raw keys should not be used`
|
||||
slog.Info("msg", slog.Int("foo", 1)) // want `raw keys should not be used`
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user