Skip to content

Commit 39c5fd1

Browse files
authored
feat: add sloglint linter (#4133)
1 parent cf93cf5 commit 39c5fd1

15 files changed

+157
-0
lines changed

.golangci.reference.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1799,6 +1799,20 @@ linters-settings:
17991799
packages:
18001800
- github.com/jmoiron/sqlx
18011801

1802+
sloglint:
1803+
# Enforce using key-value pairs only (incompatible with attr-only).
1804+
# Default: false
1805+
kv-only: true
1806+
# Enforce using attributes only (incompatible with kv-only).
1807+
# Default: false
1808+
attr-only: true
1809+
# Enforce using constants instead of raw keys.
1810+
# Default: false
1811+
no-raw-keys: true
1812+
# Enforce putting arguments on separate lines.
1813+
# Default: false
1814+
args-on-sep-lines: true
1815+
18021816
staticcheck:
18031817
# Deprecated: use the global `run.go` instead.
18041818
go: "1.15"
@@ -2295,6 +2309,7 @@ linters:
22952309
- revive
22962310
- rowserrcheck
22972311
- scopelint
2312+
- sloglint
22982313
- sqlclosecheck
22992314
- staticcheck
23002315
- structcheck
@@ -2413,6 +2428,7 @@ linters:
24132428
- revive
24142429
- rowserrcheck
24152430
- scopelint
2431+
- sloglint
24162432
- sqlclosecheck
24172433
- staticcheck
24182434
- structcheck

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ require (
119119
github.com/yeya24/promlinter v0.2.0
120120
github.com/ykadowak/zerologlint v0.1.3
121121
gitlab.com/bosi/decorder v0.4.1
122+
go-simpler.org/sloglint v0.1.2
122123
go.tmz.dev/musttag v0.7.2
123124
golang.org/x/exp v0.0.0-20230510235704-dd950f8aeaea
124125
golang.org/x/tools v0.14.0

go.sum

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/config/linters_settings.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,12 @@ var defaultLintersSettings = LintersSettings{
113113
Ignore: "",
114114
Qualified: false,
115115
},
116+
SlogLint: SlogLintSettings{
117+
KVOnly: false,
118+
AttrOnly: false,
119+
NoRawKeys: false,
120+
ArgsOnSepLines: false,
121+
},
116122
TagAlign: TagAlignSettings{
117123
Align: true,
118124
Sort: true,
@@ -222,6 +228,7 @@ type LintersSettings struct {
222228
Reassign ReassignSettings
223229
Revive ReviveSettings
224230
RowsErrCheck RowsErrCheckSettings
231+
SlogLint SlogLintSettings
225232
Staticcheck StaticCheckSettings
226233
Structcheck StructCheckSettings
227234
Stylecheck StaticCheckSettings
@@ -717,6 +724,13 @@ type RowsErrCheckSettings struct {
717724
Packages []string
718725
}
719726

727+
type SlogLintSettings struct {
728+
KVOnly bool `mapstructure:"kv-only"`
729+
AttrOnly bool `mapstructure:"attr-only"`
730+
NoRawKeys bool `mapstructure:"no-raw-keys"`
731+
ArgsOnSepLines bool `mapstructure:"args-on-sep-lines"`
732+
}
733+
720734
type StaticCheckSettings struct {
721735
// Deprecated: use the global `run.go` instead.
722736
GoVersion string `mapstructure:"go"`

pkg/golinters/sloglint.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package golinters
2+
3+
import (
4+
"go-simpler.org/sloglint"
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 NewSlogLint(settings *config.SlogLintSettings) *goanalysis.Linter {
12+
var opts *sloglint.Options
13+
if settings != nil {
14+
opts = &sloglint.Options{
15+
KVOnly: settings.KVOnly,
16+
AttrOnly: settings.AttrOnly,
17+
NoRawKeys: settings.NoRawKeys,
18+
ArgsOnSepLines: settings.ArgsOnSepLines,
19+
}
20+
}
21+
22+
a := sloglint.New(opts)
23+
24+
return goanalysis.
25+
NewLinter(a.Name, a.Doc, []*analysis.Analyzer{a}, nil).
26+
WithLoadMode(goanalysis.LoadModeTypesInfo)
27+
}

pkg/lint/lintersdb/manager.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
127127
reassignCfg *config.ReassignSettings
128128
reviveCfg *config.ReviveSettings
129129
rowserrcheckCfg *config.RowsErrCheckSettings
130+
sloglintCfg *config.SlogLintSettings
130131
staticcheckCfg *config.StaticCheckSettings
131132
structcheckCfg *config.StructCheckSettings
132133
stylecheckCfg *config.StaticCheckSettings
@@ -208,6 +209,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
208209
reassignCfg = &m.cfg.LintersSettings.Reassign
209210
reviveCfg = &m.cfg.LintersSettings.Revive
210211
rowserrcheckCfg = &m.cfg.LintersSettings.RowsErrCheck
212+
sloglintCfg = &m.cfg.LintersSettings.SlogLint
211213
staticcheckCfg = &m.cfg.LintersSettings.Staticcheck
212214
structcheckCfg = &m.cfg.LintersSettings.Structcheck
213215
stylecheckCfg = &m.cfg.LintersSettings.Stylecheck
@@ -750,6 +752,12 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
750752
WithPresets(linter.PresetBugs, linter.PresetSQL).
751753
WithURL("https://github.com/jingyugao/rowserrcheck"),
752754

755+
linter.NewConfig(golinters.NewSlogLint(sloglintCfg)).
756+
WithSince("v1.55.0").
757+
WithLoadForGoAnalysis().
758+
WithPresets(linter.PresetStyle, linter.PresetFormatting).
759+
WithURL("https://github.com/go-simpler/sloglint"),
760+
753761
linter.NewConfig(golinters.NewScopelint()).
754762
WithSince("v1.12.0").
755763
WithPresets(linter.PresetBugs).
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
linters-settings:
2+
sloglint:
3+
args-on-sep-lines: true
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
linters-settings:
2+
sloglint:
3+
attr-only: true
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
linters-settings:
2+
sloglint:
3+
kv-only: true
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
linters-settings:
2+
sloglint:
3+
no-raw-keys: true

test/testdata/sloglint.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//go:build go1.21
2+
3+
//golangcitest:args -Esloglint
4+
package testdata
5+
6+
import "log/slog"
7+
8+
func test() {
9+
slog.Info("msg", "foo", 1, "bar", 2)
10+
slog.Info("msg", slog.Int("foo", 1), slog.Int("bar", 2))
11+
12+
slog.Info("msg", "foo", 1, slog.Int("bar", 2)) // want `key-value pairs and attributes should not be mixed`
13+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//go:build go1.21
2+
3+
//golangcitest:args -Esloglint
4+
//golangcitest:config_path testdata/configs/sloglint_args_on_sep_lines.yml
5+
package testdata
6+
7+
import "log/slog"
8+
9+
func test() {
10+
slog.Info("msg", "foo", 1)
11+
slog.Info("msg",
12+
"foo", 1,
13+
"bar", 2,
14+
)
15+
16+
slog.Info("msg", "foo", 1, "bar", 2) // want `arguments should be put on separate lines`
17+
}

test/testdata/sloglint_attr_only.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//go:build go1.21
2+
3+
//golangcitest:args -Esloglint
4+
//golangcitest:config_path testdata/configs/sloglint_attr_only.yml
5+
package testdata
6+
7+
import "log/slog"
8+
9+
func test() {
10+
slog.Info("msg", slog.Int("foo", 1), slog.Int("bar", 2))
11+
12+
slog.Info("msg", "foo", 1, "bar", 2) // want `key-value pairs should not be used`
13+
}

test/testdata/sloglint_kv_only.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//go:build go1.21
2+
3+
//golangcitest:args -Esloglint
4+
//golangcitest:config_path testdata/configs/sloglint_kv_only.yml
5+
package testdata
6+
7+
import "log/slog"
8+
9+
func test() {
10+
slog.Info("msg", "foo", 1, "bar", 2)
11+
12+
slog.Info("msg", slog.Int("foo", 1), slog.Int("bar", 2)) // want `attributes should not be used`
13+
}

test/testdata/sloglint_no_raw_keys.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//go:build go1.21
2+
3+
//golangcitest:args -Esloglint
4+
//golangcitest:config_path testdata/configs/sloglint_no_raw_keys.yml
5+
package testdata
6+
7+
import "log/slog"
8+
9+
const foo = "foo"
10+
11+
func Foo(value int) slog.Attr {
12+
return slog.Int("foo", value)
13+
}
14+
15+
func test() {
16+
slog.Info("msg", foo, 1)
17+
slog.Info("msg", Foo(1))
18+
19+
slog.Info("msg", "foo", 1) // want `raw keys should not be used`
20+
slog.Info("msg", slog.Int("foo", 1)) // want `raw keys should not be used`
21+
}

0 commit comments

Comments
 (0)