Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add interfacebloat #3024

Merged
merged 4 commits into from Aug 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions .golangci.reference.yml
Expand Up @@ -1074,6 +1074,11 @@ linters-settings:
- pkg: knative.dev/serving/pkg/apis/(\w+)/(v[\w\d]+)
alias: $1$2

interfacebloat:
# The maximum number of methods allowed for an interface.
# Default: 10
max: 5

ireturn:
# ireturn allows using `allow` and `reject` settings at the same time.
# Both settings are lists of the keywords and regular expressions matched to interface or package names.
Expand Down Expand Up @@ -1923,6 +1928,7 @@ linters:
- ifshort
- importas
- ineffassign
- interfacebloat
- interfacer
- ireturn
- lll
Expand Down Expand Up @@ -2025,6 +2031,7 @@ linters:
- ifshort
- importas
- ineffassign
- interfacebloat
- interfacer
- ireturn
- lll
Expand Down
1 change: 1 addition & 0 deletions go.mod
Expand Up @@ -74,6 +74,7 @@ require (
github.com/ryancurrah/gomodguard v1.2.4
github.com/ryanrolds/sqlclosecheck v0.3.0
github.com/sanposhiho/wastedassign/v2 v2.0.6
github.com/sashamelentyev/interfacebloat v1.1.0
github.com/sashamelentyev/usestdlibvars v1.13.0
github.com/securego/gosec/v2 v2.13.1
github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c
Expand Down
2 changes: 2 additions & 0 deletions go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions pkg/config/linters_settings.go
Expand Up @@ -151,6 +151,7 @@ type LintersSettings struct {
Grouper GrouperSettings
Ifshort IfshortSettings
ImportAs ImportAsSettings
InterfaceBloat InterfaceBloatSettings
Ireturn IreturnSettings
Lll LllSettings
MaintIdx MaintIdxSettings
Expand Down Expand Up @@ -454,6 +455,10 @@ type ImportAsAlias struct {
Alias string
}

type InterfaceBloatSettings struct {
Max int `mapstructure:"max"`
}

type IreturnSettings struct {
Allow []string `mapstructure:"allow"`
Reject []string `mapstructure:"reject"`
Expand Down
27 changes: 27 additions & 0 deletions pkg/golinters/interfacebloat.go
@@ -0,0 +1,27 @@
package golinters

import (
"github.com/sashamelentyev/interfacebloat/pkg/analyzer"
"golang.org/x/tools/go/analysis"

"github.com/golangci/golangci-lint/pkg/config"
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
)

func NewInterfaceBloat(settings *config.InterfaceBloatSettings) *goanalysis.Linter {
a := analyzer.New()

cfgMap := make(map[string]map[string]interface{})
if settings != nil {
cfgMap[a.Name] = map[string]interface{}{
analyzer.InterfaceMaxMethodsFlag: settings.Max,
}
}

return goanalysis.NewLinter(
a.Name,
a.Doc,
[]*analysis.Analyzer{a},
nil,
).WithLoadMode(goanalysis.LoadModeSyntax)
}
7 changes: 7 additions & 0 deletions pkg/lint/lintersdb/manager.go
Expand Up @@ -137,6 +137,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
grouperCfg *config.GrouperSettings
ifshortCfg *config.IfshortSettings
importAsCfg *config.ImportAsSettings
interfaceBloatCfg *config.InterfaceBloatSettings
ireturnCfg *config.IreturnSettings
lllCfg *config.LllSettings
maintIdxCfg *config.MaintIdxSettings
Expand Down Expand Up @@ -209,6 +210,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
grouperCfg = &m.cfg.LintersSettings.Grouper
ifshortCfg = &m.cfg.LintersSettings.Ifshort
importAsCfg = &m.cfg.LintersSettings.ImportAs
interfaceBloatCfg = &m.cfg.LintersSettings.InterfaceBloat
ireturnCfg = &m.cfg.LintersSettings.Ireturn
lllCfg = &m.cfg.LintersSettings.Lll
maintIdxCfg = &m.cfg.LintersSettings.MaintIdx
Expand Down Expand Up @@ -557,6 +559,11 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
WithPresets(linter.PresetUnused).
WithURL("https://github.com/gordonklaus/ineffassign"),

linter.NewConfig(golinters.NewInterfaceBloat(interfaceBloatCfg)).
WithSince("v1.49.0").
WithPresets(linter.PresetStyle).
WithURL("https://github.com/sashamelentyev/interfacebloat"),

linter.NewConfig(golinters.NewInterfacer()).
WithSince("v1.0.0").
WithLoadForGoAnalysis().
Expand Down
126 changes: 126 additions & 0 deletions test/testdata/interfacebloat.go
@@ -0,0 +1,126 @@
//golangcitest:args -Einterfacebloat
package testdata

import "time"

type InterfaceBloatExample01 interface { // want "the interface has more than 10 methods: 11"
a01() time.Duration
a02()
a03()
a04()
a05()
a06()
a07()
a08()
a09()
a10()
a11()
}

func InterfaceBloatExample02() {
var _ interface { // want "the interface has more than 10 methods: 11"
a01() time.Duration
a02()
a03()
a04()
a05()
a06()
a07()
a08()
a09()
a10()
a11()
}
}

func InterfaceBloatExample03() interface { // want "the interface has more than 10 methods: 11"
a01() time.Duration
a02()
a03()
a04()
a05()
a06()
a07()
a08()
a09()
a10()
a11()
} {
return nil
}

type InterfaceBloatExample04 struct {
Foo interface { // want "the interface has more than 10 methods: 11"
a01() time.Duration
a02()
a03()
a04()
a05()
a06()
a07()
a08()
a09()
a10()
a11()
}
}

type InterfaceBloatSmall01 interface {
a01() time.Duration
a02()
a03()
a04()
a05()
}

type InterfaceBloatSmall02 interface {
a06()
a07()
a08()
a09()
a10()
a11()
}

type InterfaceBloatExample05 interface {
InterfaceBloatSmall01
InterfaceBloatSmall02
}

type InterfaceBloatExample06 interface {
interface { // want "the interface has more than 10 methods: 11"
a01() time.Duration
a02()
a03()
a04()
a05()
a06()
a07()
a08()
a09()
a10()
a11()
}
}

type InterfaceBloatTypeGeneric interface {
~uint8 | ~uint16 | ~uint32 | ~uint64 | uint |
~int8 | ~int16 | ~int32 | ~int64 | int |
~float32 | ~float64 |
~string
}

func InterfaceBloatExampleNoProblem() interface {
a01() time.Duration
a02()
a03()
a04()
a05()
a06()
a07()
a08()
a09()
a10()
} {
return nil
}