From 4c856d98bff7a1df7415e555181f7a074551f94d Mon Sep 17 00:00:00 2001 From: yagipy Date: Sat, 25 Dec 2021 20:30:26 +0900 Subject: [PATCH 1/3] Support maintidx --- .golangci.example.yml | 4 + go.mod | 1 + go.sum | 2 + pkg/config/linters_settings.go | 5 + pkg/golinters/maintidx.go | 33 ++++ pkg/lint/lintersdb/manager.go | 8 + test/testdata/configs/maintidx_under_100.yml | 3 + test/testdata/maintidx.go | 196 ++++++++++++++++++ test/testdata/maintidx_under_100.go | 197 +++++++++++++++++++ 9 files changed, 449 insertions(+) create mode 100644 pkg/golinters/maintidx.go create mode 100644 test/testdata/configs/maintidx_under_100.yml create mode 100644 test/testdata/maintidx.go create mode 100644 test/testdata/maintidx_under_100.go diff --git a/.golangci.example.yml b/.golangci.example.yml index cdceb330e3b6..db7e61dda44a 100644 --- a/.golangci.example.yml +++ b/.golangci.example.yml @@ -1117,6 +1117,10 @@ linters-settings: force-short-decl-cuddling: false strict-append: true + maintidx: + # show functions with maintainability index < N only. + under: 20 + # The custom section can be used to define linter plugins to be loaded at runtime. # See README doc for more info. custom: diff --git a/go.mod b/go.mod index 342cafb7498d..7f898b16efeb 100644 --- a/go.mod +++ b/go.mod @@ -91,6 +91,7 @@ require ( github.com/ultraware/whitespace v0.0.4 github.com/uudashr/gocognit v1.0.5 github.com/valyala/quicktemplate v1.7.0 + github.com/yagipy/maintidx v1.0.0 github.com/yeya24/promlinter v0.1.0 gitlab.com/bosi/decorder v0.2.1 golang.org/x/tools v0.1.9-0.20211228192929-ee1ca4ffc4da diff --git a/go.sum b/go.sum index f244ce258d9d..fd76436046b5 100644 --- a/go.sum +++ b/go.sum @@ -798,6 +798,8 @@ github.com/viki-org/dnscache v0.0.0-20130720023526-c70c1f23c5d8/go.mod h1:dniwbG github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yagipy/maintidx v1.0.0 h1:h5NvIsCz+nRDapQ0exNv4aJ0yXSI0420omVANTv3GJM= +github.com/yagipy/maintidx v1.0.0/go.mod h1:0qNf/I/CCZXSMhsRsrEPDZ+DkekpKLXAJfsTACwgXLk= github.com/yeya24/promlinter v0.1.0 h1:goWULN0jH5Yajmu/K+v1xCqIREeB+48OiJ2uu2ssc7U= github.com/yeya24/promlinter v0.1.0/go.mod h1:rs5vtZzeBHqqMwXqFScncpCF6u06lezhZepno9AB1Oc= github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= diff --git a/pkg/config/linters_settings.go b/pkg/config/linters_settings.go index acace3075036..881a7fbcb9bc 100644 --- a/pkg/config/linters_settings.go +++ b/pkg/config/linters_settings.go @@ -128,6 +128,7 @@ type LintersSettings struct { ImportAs ImportAsSettings Ireturn IreturnSettings Lll LllSettings + MaintIdx MaintIdxSettings Makezero MakezeroSettings Maligned MalignedSettings Misspell MisspellSettings @@ -389,6 +390,10 @@ type LllSettings struct { TabWidth int `mapstructure:"tab-width"` } +type MaintIdxSettings struct { + Under int `mapstructure:"under"` +} + type MakezeroSettings struct { Always bool } diff --git a/pkg/golinters/maintidx.go b/pkg/golinters/maintidx.go new file mode 100644 index 000000000000..94ca94cebab5 --- /dev/null +++ b/pkg/golinters/maintidx.go @@ -0,0 +1,33 @@ +package golinters + +import ( + "github.com/yagipy/maintidx" + "golang.org/x/tools/go/analysis" + + "github.com/golangci/golangci-lint/pkg/config" + "github.com/golangci/golangci-lint/pkg/golinters/goanalysis" +) + +func NewMaintIdx(cfg *config.MaintIdxSettings) *goanalysis.Linter { + analyzer := maintidx.Analyzer + + cfgMap := map[string]map[string]interface{}{} + cfgMap[analyzer.Name] = map[string]interface{}{ + "under": 20, + } + + if cfg != nil { + cfgMap[analyzer.Name] = map[string]interface{}{ + "under": cfg.Under, + } + } + + return goanalysis.NewLinter( + analyzer.Name, + analyzer.Doc, + []*analysis.Analyzer{ + analyzer, + }, + cfgMap, + ).WithLoadMode(goanalysis.LoadModeSyntax) +} diff --git a/pkg/lint/lintersdb/manager.go b/pkg/lint/lintersdb/manager.go index db386a17d58d..78bc3e3dd69d 100644 --- a/pkg/lint/lintersdb/manager.go +++ b/pkg/lint/lintersdb/manager.go @@ -114,6 +114,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config { var ifshortCfg *config.IfshortSettings var importAsCfg *config.ImportAsSettings var ireturnCfg *config.IreturnSettings + var maintIdxCfg *config.MaintIdxSettings var nilNilCfg *config.NilNilSettings var nlreturnCfg *config.NlreturnSettings var predeclaredCfg *config.PredeclaredSettings @@ -143,6 +144,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config { ifshortCfg = &m.cfg.LintersSettings.Ifshort importAsCfg = &m.cfg.LintersSettings.ImportAs ireturnCfg = &m.cfg.LintersSettings.Ireturn + maintIdxCfg = &m.cfg.LintersSettings.MaintIdx nilNilCfg = &m.cfg.LintersSettings.NilNil nlreturnCfg = &m.cfg.LintersSettings.Nlreturn predeclaredCfg = &m.cfg.LintersSettings.Predeclared @@ -439,6 +441,12 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config { WithSince("v1.8.0"). WithPresets(linter.PresetStyle), + linter.NewConfig(golinters.NewMaintIdx()). + WithSince("v1.1.0"). + WithPresets(linter.PresetComplexity). + WithLoadForGoAnalysis(). + WithURL("https://github.com/yagipy/maintidx"), + linter.NewConfig(golinters.NewMakezero()). WithSince("v1.34.0"). WithPresets(linter.PresetStyle, linter.PresetBugs). diff --git a/test/testdata/configs/maintidx_under_100.yml b/test/testdata/configs/maintidx_under_100.yml new file mode 100644 index 000000000000..8d54963412e7 --- /dev/null +++ b/test/testdata/configs/maintidx_under_100.yml @@ -0,0 +1,3 @@ +linters-settings: + maintidx: + under: 100 diff --git a/test/testdata/maintidx.go b/test/testdata/maintidx.go new file mode 100644 index 000000000000..51f95235040c --- /dev/null +++ b/test/testdata/maintidx.go @@ -0,0 +1,196 @@ +//args: -Emaintidx +package testdata + +func over20() { +} + +func under20() { // ERROR "Function name: under20, Cyclomatic Complexity: 76, Halstead Volume: 1636.00, Maintainability Index: 17" + for true { + if false { + if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else { + n := 0 + switch n { + case 0: + case 1: + default: + } + } + } else if false { + if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else { + n := 0 + switch n { + case 0: + case 1: + default: + } + } + } else if false { + if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else { + n := 0 + switch n { + case 0: + case 1: + default: + } + } + } else if false { + if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else { + n := 0 + switch n { + case 0: + case 1: + default: + } + } + } else { + if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else { + n := 0 + switch n { + case 0: + case 1: + default: + } + } + } + } +} diff --git a/test/testdata/maintidx_under_100.go b/test/testdata/maintidx_under_100.go new file mode 100644 index 000000000000..ce80be08d667 --- /dev/null +++ b/test/testdata/maintidx_under_100.go @@ -0,0 +1,197 @@ +// args: -Emaintidx +// config_path: testdata/configs/maintidx_under_100.yml +package testdata + +func over20() { // ERROR "Function name: over20, Cyclomatic Complexity: 1, Halstead Volume: 8.00, Maintainability Index: 86" +} + +func under20() { // ERROR "Function name: under20, Cyclomatic Complexity: 76, Halstead Volume: 1636.00, Maintainability Index: 17" + for true { + if false { + if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else { + n := 0 + switch n { + case 0: + case 1: + default: + } + } + } else if false { + if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else { + n := 0 + switch n { + case 0: + case 1: + default: + } + } + } else if false { + if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else { + n := 0 + switch n { + case 0: + case 1: + default: + } + } + } else if false { + if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else { + n := 0 + switch n { + case 0: + case 1: + default: + } + } + } else { + if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else if false { + n := 0 + switch n { + case 0: + case 1: + default: + } + } else { + n := 0 + switch n { + case 0: + case 1: + default: + } + } + } + } +} From 43bbda487631c9cd7c76db3cbdc1112f2fa75d43 Mon Sep 17 00:00:00 2001 From: yagipy Date: Sat, 15 Jan 2022 23:21:16 +0900 Subject: [PATCH 2/3] fixup! Support maintidx --- .golangci.example.yml | 8 ++++---- pkg/lint/lintersdb/manager.go | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.golangci.example.yml b/.golangci.example.yml index db7e61dda44a..b07c63f86e2e 100644 --- a/.golangci.example.yml +++ b/.golangci.example.yml @@ -590,6 +590,10 @@ linters-settings: # tab width in spaces. Default to 1. tab-width: 1 + maintidx: + # show functions with maintainability index < N only. + under: 20 + makezero: # Allow only slices initialized with a length of zero. Default is false. always: false @@ -1117,10 +1121,6 @@ linters-settings: force-short-decl-cuddling: false strict-append: true - maintidx: - # show functions with maintainability index < N only. - under: 20 - # The custom section can be used to define linter plugins to be loaded at runtime. # See README doc for more info. custom: diff --git a/pkg/lint/lintersdb/manager.go b/pkg/lint/lintersdb/manager.go index 78bc3e3dd69d..c001e0704cc2 100644 --- a/pkg/lint/lintersdb/manager.go +++ b/pkg/lint/lintersdb/manager.go @@ -441,7 +441,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config { WithSince("v1.8.0"). WithPresets(linter.PresetStyle), - linter.NewConfig(golinters.NewMaintIdx()). + linter.NewConfig(golinters.NewMaintIdx(maintIdxCfg)). WithSince("v1.1.0"). WithPresets(linter.PresetComplexity). WithLoadForGoAnalysis(). From 8bd9d6b64101c4dbf4aaf36055335bcd35e6637f Mon Sep 17 00:00:00 2001 From: yagipy Date: Sun, 16 Jan 2022 13:31:30 +0900 Subject: [PATCH 3/3] fixup! fixup! Support maintidx --- .golangci.example.yml | 6 ++++-- pkg/config/linters_settings.go | 3 +++ pkg/golinters/maintidx.go | 5 ++--- pkg/lint/lintersdb/manager.go | 3 +-- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.golangci.example.yml b/.golangci.example.yml index b07c63f86e2e..df2af8e2525e 100644 --- a/.golangci.example.yml +++ b/.golangci.example.yml @@ -591,8 +591,10 @@ linters-settings: tab-width: 1 maintidx: - # show functions with maintainability index < N only. - under: 20 + # Show functions with maintainability index lower than N. + # A high index indicates better maintainability (it's kind of the opposite of complexity). + # default: 20 + under: 100 makezero: # Allow only slices initialized with a length of zero. Default is false. diff --git a/pkg/config/linters_settings.go b/pkg/config/linters_settings.go index 881a7fbcb9bc..e7f07db50aa4 100644 --- a/pkg/config/linters_settings.go +++ b/pkg/config/linters_settings.go @@ -51,6 +51,9 @@ var defaultLintersSettings = LintersSettings{ LineLength: 120, TabWidth: 1, }, + MaintIdx: MaintIdxSettings{ + Under: 20, + }, Nakedret: NakedretSettings{ MaxFuncLines: 30, }, diff --git a/pkg/golinters/maintidx.go b/pkg/golinters/maintidx.go index 94ca94cebab5..2b02b948f47e 100644 --- a/pkg/golinters/maintidx.go +++ b/pkg/golinters/maintidx.go @@ -11,9 +11,8 @@ import ( func NewMaintIdx(cfg *config.MaintIdxSettings) *goanalysis.Linter { analyzer := maintidx.Analyzer - cfgMap := map[string]map[string]interface{}{} - cfgMap[analyzer.Name] = map[string]interface{}{ - "under": 20, + cfgMap := map[string]map[string]interface{}{ + analyzer.Name: {"under": 20}, } if cfg != nil { diff --git a/pkg/lint/lintersdb/manager.go b/pkg/lint/lintersdb/manager.go index c001e0704cc2..28bf08056a9d 100644 --- a/pkg/lint/lintersdb/manager.go +++ b/pkg/lint/lintersdb/manager.go @@ -442,9 +442,8 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config { WithPresets(linter.PresetStyle), linter.NewConfig(golinters.NewMaintIdx(maintIdxCfg)). - WithSince("v1.1.0"). + WithSince("v1.44.0"). WithPresets(linter.PresetComplexity). - WithLoadForGoAnalysis(). WithURL("https://github.com/yagipy/maintidx"), linter.NewConfig(golinters.NewMakezero()).