feat: add sloglint
linter (#4133)
This commit is contained in:
parent
cf93cf57dd
commit
39c5fd10ae
@ -1799,6 +1799,20 @@ linters-settings:
|
|||||||
packages:
|
packages:
|
||||||
- github.com/jmoiron/sqlx
|
- 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:
|
staticcheck:
|
||||||
# Deprecated: use the global `run.go` instead.
|
# Deprecated: use the global `run.go` instead.
|
||||||
go: "1.15"
|
go: "1.15"
|
||||||
@ -2295,6 +2309,7 @@ linters:
|
|||||||
- revive
|
- revive
|
||||||
- rowserrcheck
|
- rowserrcheck
|
||||||
- scopelint
|
- scopelint
|
||||||
|
- sloglint
|
||||||
- sqlclosecheck
|
- sqlclosecheck
|
||||||
- staticcheck
|
- staticcheck
|
||||||
- structcheck
|
- structcheck
|
||||||
@ -2413,6 +2428,7 @@ linters:
|
|||||||
- revive
|
- revive
|
||||||
- rowserrcheck
|
- rowserrcheck
|
||||||
- scopelint
|
- scopelint
|
||||||
|
- sloglint
|
||||||
- sqlclosecheck
|
- sqlclosecheck
|
||||||
- staticcheck
|
- staticcheck
|
||||||
- structcheck
|
- structcheck
|
||||||
|
1
go.mod
1
go.mod
@ -119,6 +119,7 @@ require (
|
|||||||
github.com/yeya24/promlinter v0.2.0
|
github.com/yeya24/promlinter v0.2.0
|
||||||
github.com/ykadowak/zerologlint v0.1.3
|
github.com/ykadowak/zerologlint v0.1.3
|
||||||
gitlab.com/bosi/decorder v0.4.1
|
gitlab.com/bosi/decorder v0.4.1
|
||||||
|
go-simpler.org/sloglint v0.1.2
|
||||||
go.tmz.dev/musttag v0.7.2
|
go.tmz.dev/musttag v0.7.2
|
||||||
golang.org/x/exp v0.0.0-20230510235704-dd950f8aeaea
|
golang.org/x/exp v0.0.0-20230510235704-dd950f8aeaea
|
||||||
golang.org/x/tools v0.14.0
|
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 h1:VdsdfxhstabyhZovHafFw+9eJ6eU0d2CkFNJcZz/NU4=
|
||||||
gitlab.com/bosi/decorder v0.4.1/go.mod h1:jecSqWUew6Yle1pCr2eLWTensJMmsxHsBwt+PVbkAqA=
|
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/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.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
|
@ -113,6 +113,12 @@ var defaultLintersSettings = LintersSettings{
|
|||||||
Ignore: "",
|
Ignore: "",
|
||||||
Qualified: false,
|
Qualified: false,
|
||||||
},
|
},
|
||||||
|
SlogLint: SlogLintSettings{
|
||||||
|
KVOnly: false,
|
||||||
|
AttrOnly: false,
|
||||||
|
NoRawKeys: false,
|
||||||
|
ArgsOnSepLines: false,
|
||||||
|
},
|
||||||
TagAlign: TagAlignSettings{
|
TagAlign: TagAlignSettings{
|
||||||
Align: true,
|
Align: true,
|
||||||
Sort: true,
|
Sort: true,
|
||||||
@ -222,6 +228,7 @@ type LintersSettings struct {
|
|||||||
Reassign ReassignSettings
|
Reassign ReassignSettings
|
||||||
Revive ReviveSettings
|
Revive ReviveSettings
|
||||||
RowsErrCheck RowsErrCheckSettings
|
RowsErrCheck RowsErrCheckSettings
|
||||||
|
SlogLint SlogLintSettings
|
||||||
Staticcheck StaticCheckSettings
|
Staticcheck StaticCheckSettings
|
||||||
Structcheck StructCheckSettings
|
Structcheck StructCheckSettings
|
||||||
Stylecheck StaticCheckSettings
|
Stylecheck StaticCheckSettings
|
||||||
@ -717,6 +724,13 @@ type RowsErrCheckSettings struct {
|
|||||||
Packages []string
|
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 {
|
type StaticCheckSettings struct {
|
||||||
// Deprecated: use the global `run.go` instead.
|
// Deprecated: use the global `run.go` instead.
|
||||||
GoVersion string `mapstructure:"go"`
|
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
|
reassignCfg *config.ReassignSettings
|
||||||
reviveCfg *config.ReviveSettings
|
reviveCfg *config.ReviveSettings
|
||||||
rowserrcheckCfg *config.RowsErrCheckSettings
|
rowserrcheckCfg *config.RowsErrCheckSettings
|
||||||
|
sloglintCfg *config.SlogLintSettings
|
||||||
staticcheckCfg *config.StaticCheckSettings
|
staticcheckCfg *config.StaticCheckSettings
|
||||||
structcheckCfg *config.StructCheckSettings
|
structcheckCfg *config.StructCheckSettings
|
||||||
stylecheckCfg *config.StaticCheckSettings
|
stylecheckCfg *config.StaticCheckSettings
|
||||||
@ -208,6 +209,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
|
|||||||
reassignCfg = &m.cfg.LintersSettings.Reassign
|
reassignCfg = &m.cfg.LintersSettings.Reassign
|
||||||
reviveCfg = &m.cfg.LintersSettings.Revive
|
reviveCfg = &m.cfg.LintersSettings.Revive
|
||||||
rowserrcheckCfg = &m.cfg.LintersSettings.RowsErrCheck
|
rowserrcheckCfg = &m.cfg.LintersSettings.RowsErrCheck
|
||||||
|
sloglintCfg = &m.cfg.LintersSettings.SlogLint
|
||||||
staticcheckCfg = &m.cfg.LintersSettings.Staticcheck
|
staticcheckCfg = &m.cfg.LintersSettings.Staticcheck
|
||||||
structcheckCfg = &m.cfg.LintersSettings.Structcheck
|
structcheckCfg = &m.cfg.LintersSettings.Structcheck
|
||||||
stylecheckCfg = &m.cfg.LintersSettings.Stylecheck
|
stylecheckCfg = &m.cfg.LintersSettings.Stylecheck
|
||||||
@ -750,6 +752,12 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
|
|||||||
WithPresets(linter.PresetBugs, linter.PresetSQL).
|
WithPresets(linter.PresetBugs, linter.PresetSQL).
|
||||||
WithURL("https://github.com/jingyugao/rowserrcheck"),
|
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()).
|
linter.NewConfig(golinters.NewScopelint()).
|
||||||
WithSince("v1.12.0").
|
WithSince("v1.12.0").
|
||||||
WithPresets(linter.PresetBugs).
|
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