Skip to content

Commit 63b2fe0

Browse files
sashamelentyevldez
andauthored
feat: add interfacebloat (#3024)
Co-authored-by: Fernandez Ludovic <[email protected]>
1 parent 1bb23af commit 63b2fe0

File tree

7 files changed

+175
-0
lines changed

7 files changed

+175
-0
lines changed

Diff for: .golangci.reference.yml

+7
Original file line numberDiff line numberDiff line change
@@ -1074,6 +1074,11 @@ linters-settings:
10741074
- pkg: knative.dev/serving/pkg/apis/(\w+)/(v[\w\d]+)
10751075
alias: $1$2
10761076

1077+
interfacebloat:
1078+
# The maximum number of methods allowed for an interface.
1079+
# Default: 10
1080+
max: 5
1081+
10771082
ireturn:
10781083
# ireturn allows using `allow` and `reject` settings at the same time.
10791084
# Both settings are lists of the keywords and regular expressions matched to interface or package names.
@@ -1923,6 +1928,7 @@ linters:
19231928
- ifshort
19241929
- importas
19251930
- ineffassign
1931+
- interfacebloat
19261932
- interfacer
19271933
- ireturn
19281934
- lll
@@ -2025,6 +2031,7 @@ linters:
20252031
- ifshort
20262032
- importas
20272033
- ineffassign
2034+
- interfacebloat
20282035
- interfacer
20292036
- ireturn
20302037
- lll

Diff for: go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ require (
7474
github.com/ryancurrah/gomodguard v1.2.4
7575
github.com/ryanrolds/sqlclosecheck v0.3.0
7676
github.com/sanposhiho/wastedassign/v2 v2.0.6
77+
github.com/sashamelentyev/interfacebloat v1.1.0
7778
github.com/sashamelentyev/usestdlibvars v1.13.0
7879
github.com/securego/gosec/v2 v2.13.1
7980
github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c

Diff for: go.sum

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: pkg/config/linters_settings.go

+5
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ type LintersSettings struct {
151151
Grouper GrouperSettings
152152
Ifshort IfshortSettings
153153
ImportAs ImportAsSettings
154+
InterfaceBloat InterfaceBloatSettings
154155
Ireturn IreturnSettings
155156
Lll LllSettings
156157
MaintIdx MaintIdxSettings
@@ -454,6 +455,10 @@ type ImportAsAlias struct {
454455
Alias string
455456
}
456457

458+
type InterfaceBloatSettings struct {
459+
Max int `mapstructure:"max"`
460+
}
461+
457462
type IreturnSettings struct {
458463
Allow []string `mapstructure:"allow"`
459464
Reject []string `mapstructure:"reject"`

Diff for: pkg/golinters/interfacebloat.go

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package golinters
2+
3+
import (
4+
"github.com/sashamelentyev/interfacebloat/pkg/analyzer"
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 NewInterfaceBloat(settings *config.InterfaceBloatSettings) *goanalysis.Linter {
12+
a := analyzer.New()
13+
14+
cfgMap := make(map[string]map[string]interface{})
15+
if settings != nil {
16+
cfgMap[a.Name] = map[string]interface{}{
17+
analyzer.InterfaceMaxMethodsFlag: settings.Max,
18+
}
19+
}
20+
21+
return goanalysis.NewLinter(
22+
a.Name,
23+
a.Doc,
24+
[]*analysis.Analyzer{a},
25+
nil,
26+
).WithLoadMode(goanalysis.LoadModeSyntax)
27+
}

Diff for: pkg/lint/lintersdb/manager.go

+7
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
137137
grouperCfg *config.GrouperSettings
138138
ifshortCfg *config.IfshortSettings
139139
importAsCfg *config.ImportAsSettings
140+
interfaceBloatCfg *config.InterfaceBloatSettings
140141
ireturnCfg *config.IreturnSettings
141142
lllCfg *config.LllSettings
142143
maintIdxCfg *config.MaintIdxSettings
@@ -209,6 +210,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
209210
grouperCfg = &m.cfg.LintersSettings.Grouper
210211
ifshortCfg = &m.cfg.LintersSettings.Ifshort
211212
importAsCfg = &m.cfg.LintersSettings.ImportAs
213+
interfaceBloatCfg = &m.cfg.LintersSettings.InterfaceBloat
212214
ireturnCfg = &m.cfg.LintersSettings.Ireturn
213215
lllCfg = &m.cfg.LintersSettings.Lll
214216
maintIdxCfg = &m.cfg.LintersSettings.MaintIdx
@@ -557,6 +559,11 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
557559
WithPresets(linter.PresetUnused).
558560
WithURL("https://github.com/gordonklaus/ineffassign"),
559561

562+
linter.NewConfig(golinters.NewInterfaceBloat(interfaceBloatCfg)).
563+
WithSince("v1.49.0").
564+
WithPresets(linter.PresetStyle).
565+
WithURL("https://github.com/sashamelentyev/interfacebloat"),
566+
560567
linter.NewConfig(golinters.NewInterfacer()).
561568
WithSince("v1.0.0").
562569
WithLoadForGoAnalysis().

Diff for: test/testdata/interfacebloat.go

+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
//golangcitest:args -Einterfacebloat
2+
package testdata
3+
4+
import "time"
5+
6+
type InterfaceBloatExample01 interface { // want "the interface has more than 10 methods: 11"
7+
a01() time.Duration
8+
a02()
9+
a03()
10+
a04()
11+
a05()
12+
a06()
13+
a07()
14+
a08()
15+
a09()
16+
a10()
17+
a11()
18+
}
19+
20+
func InterfaceBloatExample02() {
21+
var _ interface { // want "the interface has more than 10 methods: 11"
22+
a01() time.Duration
23+
a02()
24+
a03()
25+
a04()
26+
a05()
27+
a06()
28+
a07()
29+
a08()
30+
a09()
31+
a10()
32+
a11()
33+
}
34+
}
35+
36+
func InterfaceBloatExample03() interface { // want "the interface has more than 10 methods: 11"
37+
a01() time.Duration
38+
a02()
39+
a03()
40+
a04()
41+
a05()
42+
a06()
43+
a07()
44+
a08()
45+
a09()
46+
a10()
47+
a11()
48+
} {
49+
return nil
50+
}
51+
52+
type InterfaceBloatExample04 struct {
53+
Foo interface { // want "the interface has more than 10 methods: 11"
54+
a01() time.Duration
55+
a02()
56+
a03()
57+
a04()
58+
a05()
59+
a06()
60+
a07()
61+
a08()
62+
a09()
63+
a10()
64+
a11()
65+
}
66+
}
67+
68+
type InterfaceBloatSmall01 interface {
69+
a01() time.Duration
70+
a02()
71+
a03()
72+
a04()
73+
a05()
74+
}
75+
76+
type InterfaceBloatSmall02 interface {
77+
a06()
78+
a07()
79+
a08()
80+
a09()
81+
a10()
82+
a11()
83+
}
84+
85+
type InterfaceBloatExample05 interface {
86+
InterfaceBloatSmall01
87+
InterfaceBloatSmall02
88+
}
89+
90+
type InterfaceBloatExample06 interface {
91+
interface { // want "the interface has more than 10 methods: 11"
92+
a01() time.Duration
93+
a02()
94+
a03()
95+
a04()
96+
a05()
97+
a06()
98+
a07()
99+
a08()
100+
a09()
101+
a10()
102+
a11()
103+
}
104+
}
105+
106+
type InterfaceBloatTypeGeneric interface {
107+
~uint8 | ~uint16 | ~uint32 | ~uint64 | uint |
108+
~int8 | ~int16 | ~int32 | ~int64 | int |
109+
~float32 | ~float64 |
110+
~string
111+
}
112+
113+
func InterfaceBloatExampleNoProblem() interface {
114+
a01() time.Duration
115+
a02()
116+
a03()
117+
a04()
118+
a05()
119+
a06()
120+
a07()
121+
a08()
122+
a09()
123+
a10()
124+
} {
125+
return nil
126+
}

0 commit comments

Comments
 (0)