Skip to content

Commit a73a30e

Browse files
AdminBennildez
authored andcommitted
feat: add iotamixing linter
1 parent 2d4621c commit a73a30e

File tree

11 files changed

+186
-0
lines changed

11 files changed

+186
-0
lines changed

.golangci.next.reference.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ linters:
7575
- ineffassign
7676
- interfacebloat
7777
- intrange
78+
- iotamixing
7879
- ireturn
7980
- lll
8081
- loggercheck
@@ -186,6 +187,7 @@ linters:
186187
- ineffassign
187188
- interfacebloat
188189
- intrange
190+
- iotamixing
189191
- ireturn
190192
- lll
191193
- loggercheck
@@ -1883,6 +1885,11 @@ linters:
18831885
# Default: 10
18841886
max: 5
18851887

1888+
iotamixing:
1889+
# Whether to report individual consts rather than just the const block.
1890+
# Default: false
1891+
report-individual: true
1892+
18861893
ireturn:
18871894
# List of interfaces to allow.
18881895
# Lists of the keywords and regular expressions matched to interface or package names can be used.

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ require (
88
dev.gaijin.team/go/exhaustruct/v4 v4.0.0
99
github.com/4meepo/tagalign v1.4.3
1010
github.com/Abirdcfly/dupword v0.1.6
11+
github.com/AdminBenni/iota-mixing v0.0.5
1112
github.com/AlwxSin/noinlineerr v1.0.5
1213
github.com/Antonboom/errname v1.1.0
1314
github.com/Antonboom/nilnil v1.1.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.

jsonschema/golangci.next.jsonschema.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,7 @@
813813
"ineffassign",
814814
"interfacebloat",
815815
"intrange",
816+
"iotamixing",
816817
"ireturn",
817818
"lll",
818819
"loggercheck",
@@ -2429,6 +2430,17 @@
24292430
}
24302431
}
24312432
},
2433+
"iotamixingSettings": {
2434+
"type": "object",
2435+
"additionalProperties": false,
2436+
"properties": {
2437+
"report-individual": {
2438+
"description": "Whether to report individual consts rather than just the const block.",
2439+
"type": "boolean",
2440+
"default": false
2441+
}
2442+
}
2443+
},
24322444
"ireturnSettings": {
24332445
"type": "object",
24342446
"additionalProperties": false,
@@ -4589,6 +4601,9 @@
45894601
"ineffassign": {
45904602
"$ref": "#/definitions/settings/definitions/ineffassignSettings"
45914603
},
4604+
"iotamixing": {
4605+
"$ref": "#/definitions/settings/definitions/iotamixingSettings"
4606+
},
45924607
"ireturn": {
45934608
"$ref": "#/definitions/settings/definitions/ireturnSettings"
45944609
},

pkg/config/linters_settings.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ type LintersSettings struct {
256256
Inamedparam INamedParamSettings `mapstructure:"inamedparam"`
257257
Ineffassign IneffassignSettings `mapstructure:"ineffassign"`
258258
InterfaceBloat InterfaceBloatSettings `mapstructure:"interfacebloat"`
259+
IotaMixing IotaMixingSettings `mapstructure:"iotamixing"`
259260
Ireturn IreturnSettings `mapstructure:"ireturn"`
260261
Lll LllSettings `mapstructure:"lll"`
261262
LoggerCheck LoggerCheckSettings `mapstructure:"loggercheck"`
@@ -653,6 +654,10 @@ type InterfaceBloatSettings struct {
653654
Max int `mapstructure:"max"`
654655
}
655656

657+
type IotaMixingSettings struct {
658+
ReportIndividual bool `mapstructure:"report-individual"`
659+
}
660+
656661
type IreturnSettings struct {
657662
Allow []string `mapstructure:"allow"`
658663
Reject []string `mapstructure:"reject"`
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package iotamixing
2+
3+
import (
4+
"golang.org/x/tools/go/analysis"
5+
6+
"github.com/AdminBenni/iota-mixing/pkg/analyzer"
7+
"github.com/AdminBenni/iota-mixing/pkg/analyzer/flags"
8+
9+
"github.com/golangci/golangci-lint/v2/pkg/config"
10+
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
11+
)
12+
13+
func New(settings *config.IotaMixingSettings) *goanalysis.Linter {
14+
a := analyzer.GetIotaMixingAnalyzer()
15+
16+
flags.SetupFlags(&a.Flags)
17+
18+
cfg := map[string]map[string]any{}
19+
if settings != nil {
20+
cfg[a.Name] = map[string]any{flags.ReportIndividualFlagName: settings.ReportIndividual}
21+
}
22+
23+
return goanalysis.NewLinter(
24+
a.Name,
25+
a.Doc,
26+
[]*analysis.Analyzer{a},
27+
cfg,
28+
).WithLoadMode(goanalysis.LoadModeSyntax)
29+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package iotamixing
2+
3+
import (
4+
"testing"
5+
6+
"github.com/golangci/golangci-lint/v2/test/testshared/integration"
7+
)
8+
9+
func TestFromTestdata(t *testing.T) {
10+
integration.RunTestdata(t)
11+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//golangcitest:args -Eiotamixing
2+
//golangcitest:config_path testdata/iotamixing-report-individual.yml
3+
package testdata
4+
5+
import "fmt"
6+
7+
const (
8+
InvalidPerIndividualIotaDeclAboveAnything = "anything" // want "InvalidPerIndividualIotaDeclAboveAnything is a const with r-val in same const block as iota. keep iotas in separate const blocks"
9+
InvalidPerIndividualIotaDeclAboveNotZero = iota
10+
InvalidPerIndividualIotaDeclAboveNotOne
11+
InvalidPerIndividualIotaDeclAboveNotTwo
12+
)
13+
14+
const (
15+
InvalidPerIndividualIotaDeclBelowZero = iota
16+
InvalidPerIndividualIotaDeclBelowOne
17+
InvalidPerIndividualIotaDeclBelowTwo
18+
InvalidPerIndividualIotaDeclBelowAnything = "anything" // want "InvalidPerIndividualIotaDeclBelowAnything is a const with r-val in same const block as iota. keep iotas in separate const blocks"
19+
)
20+
21+
const (
22+
InvalidPerIndividualIotaDeclBetweenZero = iota
23+
InvalidPerIndividualIotaDeclBetweenOne
24+
InvalidPerIndividualIotaDeclBetweenAnything = "anything" // want "InvalidPerIndividualIotaDeclBetweenAnything is a const with r-val in same const block as iota. keep iotas in separate const blocks"
25+
InvalidPerIndividualIotaDeclBetweenNotTwo
26+
)
27+
28+
const (
29+
InvalidPerIndividualIotaDeclMultipleAbove = "above" // want "InvalidPerIndividualIotaDeclMultipleAbove is a const with r-val in same const block as iota. keep iotas in separate const blocks"
30+
InvalidPerIndividualIotaDeclMultipleNotZero = iota
31+
InvalidPerIndividualIotaDeclMultipleNotOne
32+
InvalidPerIndividualIotaDeclMultipleBetween = "between" // want "InvalidPerIndividualIotaDeclMultipleBetween is a const with r-val in same const block as iota. keep iotas in separate const blocks"
33+
InvalidPerIndividualIotaDeclMultipleNotTwo
34+
InvalidPerIndividualIotaDeclMultipleBelow = "below" // want "InvalidPerIndividualIotaDeclMultipleBelow is a const with r-val in same const block as iota. keep iotas in separate const blocks"
35+
)
36+
37+
const (
38+
ValidPerIndividualIotaZero = iota
39+
ValidPerIndividualIotaOne
40+
ValidPerIndividualIotaTwo
41+
)
42+
43+
const (
44+
ValidPerIndividualRegularSomething = "something"
45+
ValidPerIndividualRegularAnything = "anything"
46+
)
47+
48+
func _() {
49+
fmt.Println("using the std import so goland doesn't nuke it")
50+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
version: "2"
2+
3+
linters:
4+
settings:
5+
iotamixing:
6+
report-individual: true
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
//golangcitest:args -Eiotamixing
2+
package testdata
3+
4+
import "fmt"
5+
6+
// iota mixing in const block containing an iota and r-val declared above.
7+
const ( // want "iota mixing. keep iotas in separate blocks to consts with r-val"
8+
InvalidPerBlockIotaDeclAboveAnything = "anything"
9+
InvalidPerBlockIotaDeclAboveNotZero = iota
10+
InvalidPerBlockIotaDeclAboveNotOne
11+
InvalidPerBlockIotaDeclAboveNotTwo
12+
)
13+
14+
// iota mixing in const block containing an iota and r-val declared below.
15+
const ( // want "iota mixing. keep iotas in separate blocks to consts with r-val"
16+
InvalidPerBlockIotaDeclBelowZero = iota
17+
InvalidPerBlockIotaDeclBelowOne
18+
InvalidPerBlockIotaDeclBelowTwo
19+
InvalidPerBlockIotaDeclBelowAnything = "anything"
20+
)
21+
22+
// iota mixing in const block containing an iota and r-val declared between consts.
23+
const ( // want "iota mixing. keep iotas in separate blocks to consts with r-val"
24+
InvalidPerBlockIotaDeclBetweenZero = iota
25+
InvalidPerBlockIotaDeclBetweenOne
26+
InvalidPerBlockIotaDeclBetweenAnything = "anything"
27+
InvalidPerBlockIotaDeclBetweenNotTwo
28+
)
29+
30+
// iota mixing in const block containing an iota and r-vals declared above, between, and below consts.
31+
const ( // want "iota mixing. keep iotas in separate blocks to consts with r-val"
32+
InvalidPerBlockIotaDeclMultipleAbove = "above"
33+
InvalidPerBlockIotaDeclMultipleNotZero = iota
34+
InvalidPerBlockIotaDeclMultipleNotOne
35+
InvalidPerBlockIotaDeclMultipleBetween = "between"
36+
InvalidPerBlockIotaDeclMultipleNotTwo
37+
InvalidPerBlockIotaDeclMultipleBelow = "below"
38+
)
39+
40+
// no iota mixing in a const block containing an iota and no r-vals.
41+
const (
42+
ValidPerBlockIotaZero = iota
43+
ValidPerBlockIotaOne
44+
ValidPerBlockIotaTwo
45+
)
46+
47+
// no iota mixing in a const block containing r-vals and no iota.
48+
const (
49+
ValidPerBlockRegularSomething = "something"
50+
ValidPerBlockRegularAnything = "anything"
51+
)
52+
53+
func _() {
54+
fmt.Println("using the std import so goland doesn't nuke it")
55+
}

0 commit comments

Comments
 (0)