From 46c3c7ebd5fd0e03f6d8ad22dc9e25a25928a7ba Mon Sep 17 00:00:00 2001 From: Leon Klingele Date: Wed, 19 Jan 2022 08:32:10 +0100 Subject: [PATCH 1/5] Add "grouper" linter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit grouper — a Go linter to analyze expression groups https://github.com/leonklingele/grouper --- .golangci.example.yml | 14 +++++++++++++ go.mod | 1 + go.sum | 2 ++ pkg/config/linters_settings.go | 16 +++++++++++++++ pkg/golinters/grouper.go | 37 ++++++++++++++++++++++++++++++++++ pkg/lint/lintersdb/manager.go | 7 +++++++ 6 files changed, 77 insertions(+) create mode 100644 pkg/golinters/grouper.go diff --git a/.golangci.example.yml b/.golangci.example.yml index ecc7a2449f75..10ffd439085f 100644 --- a/.golangci.example.yml +++ b/.golangci.example.yml @@ -806,6 +806,20 @@ linters-settings: - unusedresult - unusedwrite + grouper: + # const + const-require-single-const: false + const-require-grouping: false + # import + import-require-single-import: false + import-require-grouping: false + # type + type-require-single-type: false + type-require-grouping: false + # var + var-require-single-var: false + var-require-grouping: false + ifshort: # Maximum length of variable declaration measured in number of lines, after which linter won't suggest using short syntax. # Has higher priority than max-decl-chars. diff --git a/go.mod b/go.mod index 8b4f64a5e3ea..01a1286bffd4 100644 --- a/go.mod +++ b/go.mod @@ -50,6 +50,7 @@ require ( github.com/kyoh86/exportloopref v0.1.8 github.com/ldez/gomoddirectives v0.2.2 github.com/ldez/tagliatelle v0.3.0 + github.com/leonklingele/grouper v1.1.0 github.com/maratori/testpackage v1.0.1 github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 // v1.0 github.com/mattn/go-colorable v0.1.12 diff --git a/go.sum b/go.sum index 6e738b877cc1..fadae35e04d9 100644 --- a/go.sum +++ b/go.sum @@ -489,6 +489,8 @@ github.com/ldez/gomoddirectives v0.2.2 h1:p9/sXuNFArS2RLc+UpYZSI4KQwGMEDWC/LbtF5 github.com/ldez/gomoddirectives v0.2.2/go.mod h1:cpgBogWITnCfRq2qGoDkKMEVSaarhdBr6g8G04uz6d0= github.com/ldez/tagliatelle v0.3.0 h1:Aubm2ZsrsjIGFvdxemMPJaXrSJ5Cys6VWyTQFt9k2dI= github.com/ldez/tagliatelle v0.3.0/go.mod h1:8s6WJQwEYHbKZDsp/LjArytKOG8qaMrKQQ3mFukHs88= +github.com/leonklingele/grouper v1.1.0 h1:tC2y/ygPbMFSBOs3DcyaEMKnnwH7eYKzohOtRrf0SAg= +github.com/leonklingele/grouper v1.1.0/go.mod h1:uk3I3uDfi9B6PeUjsCKi6ndcf63Uy7snXgR4yDYQVDY= github.com/letsencrypt/pkcs11key/v4 v4.0.0/go.mod h1:EFUvBDay26dErnNb70Nd0/VW3tJiIbETBPTl9ATXQag= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= diff --git a/pkg/config/linters_settings.go b/pkg/config/linters_settings.go index 96f0e6153a55..adaeb86f25af 100644 --- a/pkg/config/linters_settings.go +++ b/pkg/config/linters_settings.go @@ -131,6 +131,7 @@ type LintersSettings struct { Gosec GoSecSettings Gosimple StaticCheckSettings Govet GovetSettings + Grouper GrouperSettings Ifshort IfshortSettings ImportAs ImportAsSettings Ireturn IreturnSettings @@ -376,6 +377,21 @@ func (cfg GovetSettings) Validate() error { return nil } +type GrouperSettings struct { + // const + ConstRequireSingleConst bool `mapstructure:"const-require-single-const"` + ConstRequireGrouping bool `mapstructure:"const-require-grouping"` + // import + ImportRequireSingleImport bool `mapstructure:"import-require-single-import"` + ImportRequireGrouping bool `mapstructure:"import-require-grouping"` + // type + TypeRequireSingleType bool `mapstructure:"type-require-single-type"` + TypeRequireGrouping bool `mapstructure:"type-require-grouping"` + // var + VarRequireSingleVar bool `mapstructure:"var-require-single-var"` + VarRequireGrouping bool `mapstructure:"var-require-grouping"` +} + type IfshortSettings struct { MaxDeclLines int `mapstructure:"max-decl-lines"` MaxDeclChars int `mapstructure:"max-decl-chars"` diff --git a/pkg/golinters/grouper.go b/pkg/golinters/grouper.go new file mode 100644 index 000000000000..6537791049dd --- /dev/null +++ b/pkg/golinters/grouper.go @@ -0,0 +1,37 @@ +package golinters + +import ( + "golang.org/x/tools/go/analysis" + + "github.com/golangci/golangci-lint/pkg/config" + "github.com/golangci/golangci-lint/pkg/golinters/goanalysis" + + grouper "github.com/leonklingele/grouper/pkg/analyzer" +) + +func NewGrouper(settings *config.GrouperSettings) *goanalysis.Linter { + linterCfg := map[string]map[string]interface{}{} + if settings != nil { + linterCfg["grouper"] = map[string]interface{}{ + // const + "const-require-single-const": settings.ConstRequireSingleConst, + "const-require-grouping": settings.ConstRequireGrouping, + // import + "import-require-single-import": settings.ImportRequireSingleImport, + "import-require-grouping": settings.ImportRequireGrouping, + // type + "type-require-single-type": settings.TypeRequireSingleType, + "type-require-grouping": settings.TypeRequireGrouping, + // var + "var-require-single-var": settings.VarRequireSingleVar, + "var-require-grouping": settings.VarRequireGrouping, + } + } + + return goanalysis.NewLinter( + "grouper", + "An analyzer to analyze expression groups.", + []*analysis.Analyzer{grouper.New()}, + linterCfg, + ).WithLoadMode(goanalysis.LoadModeSyntax) +} diff --git a/pkg/lint/lintersdb/manager.go b/pkg/lint/lintersdb/manager.go index f9a303aeb358..cf6a0f8d4b6f 100644 --- a/pkg/lint/lintersdb/manager.go +++ b/pkg/lint/lintersdb/manager.go @@ -112,6 +112,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config { var gosecCfg *config.GoSecSettings var gosimpleCfg *config.StaticCheckSettings var govetCfg *config.GovetSettings + var grouperCfg *config.GrouperSettings var ifshortCfg *config.IfshortSettings var importAsCfg *config.ImportAsSettings var ireturnCfg *config.IreturnSettings @@ -143,6 +144,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config { gosecCfg = &m.cfg.LintersSettings.Gosec gosimpleCfg = &m.cfg.LintersSettings.Gosimple govetCfg = &m.cfg.LintersSettings.Govet + grouperCfg = &m.cfg.LintersSettings.Grouper ifshortCfg = &m.cfg.LintersSettings.Ifshort importAsCfg = &m.cfg.LintersSettings.ImportAs ireturnCfg = &m.cfg.LintersSettings.Ireturn @@ -415,6 +417,11 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config { WithAlternativeNames("vet", "vetshadow"). WithURL("https://golang.org/cmd/vet/"), + linter.NewConfig(golinters.NewGrouper(grouperCfg)). + WithSince("v1.44.0"). + WithPresets(linter.PresetStyle). + WithURL("https://github.com/leonklingele/grouper"), + linter.NewConfig(golinters.NewIfshort(ifshortCfg)). WithSince("v1.36.0"). WithPresets(linter.PresetStyle). From 1384a4eca9c4626900863a3f0c2b9431092009e7 Mon Sep 17 00:00:00 2001 From: Leon Klingele Date: Thu, 20 Jan 2022 03:09:56 +0100 Subject: [PATCH 2/5] grouper: improve docs --- .golangci.example.yml | 39 +++++++++++++++++++++++----------- pkg/config/linters_settings.go | 8 +++---- pkg/golinters/grouper.go | 8 +++---- 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/.golangci.example.yml b/.golangci.example.yml index 10ffd439085f..6176e5bc9c2d 100644 --- a/.golangci.example.yml +++ b/.golangci.example.yml @@ -807,18 +807,33 @@ linters-settings: - unusedwrite grouper: - # const - const-require-single-const: false - const-require-grouping: false - # import - import-require-single-import: false - import-require-grouping: false - # type - type-require-single-type: false - type-require-grouping: false - # var - var-require-single-var: false - var-require-grouping: false + # Require the use of a single global 'const' declaration only. + # Default: false + const-require-single-const: true + # Require the use of grouped global 'const' declarations. + # Default: false + const-require-grouping: true + + # Require the use of a single 'import' declaration only. + # Default: false + import-require-single-import: true + # Require the use of grouped 'import' declarations. + # Default: false + import-require-grouping: true + + # Require the use of a single global 'type' declaration only. + # Default: false + type-require-single-type: true + # Require the use of grouped global 'type' declarations. + # Default: false + type-require-grouping: true + + # Require the use of a single global 'var' declaration only. + # Default: false + var-require-single-var: true + # Require the use of grouped global 'var' declarations. + # Default: false + var-require-grouping: true ifshort: # Maximum length of variable declaration measured in number of lines, after which linter won't suggest using short syntax. diff --git a/pkg/config/linters_settings.go b/pkg/config/linters_settings.go index adaeb86f25af..a27e3ebab246 100644 --- a/pkg/config/linters_settings.go +++ b/pkg/config/linters_settings.go @@ -378,16 +378,16 @@ func (cfg GovetSettings) Validate() error { } type GrouperSettings struct { - // const + // const analyzer options ConstRequireSingleConst bool `mapstructure:"const-require-single-const"` ConstRequireGrouping bool `mapstructure:"const-require-grouping"` - // import + // import analyzer options ImportRequireSingleImport bool `mapstructure:"import-require-single-import"` ImportRequireGrouping bool `mapstructure:"import-require-grouping"` - // type + // type analyzer options TypeRequireSingleType bool `mapstructure:"type-require-single-type"` TypeRequireGrouping bool `mapstructure:"type-require-grouping"` - // var + // var analyzer options VarRequireSingleVar bool `mapstructure:"var-require-single-var"` VarRequireGrouping bool `mapstructure:"var-require-grouping"` } diff --git a/pkg/golinters/grouper.go b/pkg/golinters/grouper.go index 6537791049dd..87f5a6a627df 100644 --- a/pkg/golinters/grouper.go +++ b/pkg/golinters/grouper.go @@ -13,16 +13,16 @@ func NewGrouper(settings *config.GrouperSettings) *goanalysis.Linter { linterCfg := map[string]map[string]interface{}{} if settings != nil { linterCfg["grouper"] = map[string]interface{}{ - // const + // const analyzer options "const-require-single-const": settings.ConstRequireSingleConst, "const-require-grouping": settings.ConstRequireGrouping, - // import + // import analyzer options "import-require-single-import": settings.ImportRequireSingleImport, "import-require-grouping": settings.ImportRequireGrouping, - // type + // type analyzer options "type-require-single-type": settings.TypeRequireSingleType, "type-require-grouping": settings.TypeRequireGrouping, - // var + // var analyzer options "var-require-single-var": settings.VarRequireSingleVar, "var-require-grouping": settings.VarRequireGrouping, } From 72d72874eaa42ad91199871824cefb3c40cbdc7b Mon Sep 17 00:00:00 2001 From: Leon Klingele Date: Thu, 20 Jan 2022 11:53:01 +0100 Subject: [PATCH 3/5] grouper: coding style updates --- pkg/config/linters_settings.go | 7 +++---- pkg/golinters/grouper.go | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/pkg/config/linters_settings.go b/pkg/config/linters_settings.go index a27e3ebab246..a3744b8e0ae5 100644 --- a/pkg/config/linters_settings.go +++ b/pkg/config/linters_settings.go @@ -378,16 +378,15 @@ func (cfg GovetSettings) Validate() error { } type GrouperSettings struct { - // const analyzer options ConstRequireSingleConst bool `mapstructure:"const-require-single-const"` ConstRequireGrouping bool `mapstructure:"const-require-grouping"` - // import analyzer options + ImportRequireSingleImport bool `mapstructure:"import-require-single-import"` ImportRequireGrouping bool `mapstructure:"import-require-grouping"` - // type analyzer options + TypeRequireSingleType bool `mapstructure:"type-require-single-type"` TypeRequireGrouping bool `mapstructure:"type-require-grouping"` - // var analyzer options + VarRequireSingleVar bool `mapstructure:"var-require-single-var"` VarRequireGrouping bool `mapstructure:"var-require-grouping"` } diff --git a/pkg/golinters/grouper.go b/pkg/golinters/grouper.go index 87f5a6a627df..974efd43c89c 100644 --- a/pkg/golinters/grouper.go +++ b/pkg/golinters/grouper.go @@ -13,16 +13,15 @@ func NewGrouper(settings *config.GrouperSettings) *goanalysis.Linter { linterCfg := map[string]map[string]interface{}{} if settings != nil { linterCfg["grouper"] = map[string]interface{}{ - // const analyzer options "const-require-single-const": settings.ConstRequireSingleConst, "const-require-grouping": settings.ConstRequireGrouping, - // import analyzer options + "import-require-single-import": settings.ImportRequireSingleImport, "import-require-grouping": settings.ImportRequireGrouping, - // type analyzer options + "type-require-single-type": settings.TypeRequireSingleType, "type-require-grouping": settings.TypeRequireGrouping, - // var analyzer options + "var-require-single-var": settings.VarRequireSingleVar, "var-require-grouping": settings.VarRequireGrouping, } From fbbfdefb15f4f87f737930a854289c972e9abe96 Mon Sep 17 00:00:00 2001 From: Leon Klingele Date: Thu, 20 Jan 2022 15:35:34 +0100 Subject: [PATCH 4/5] grouper: adjust import order style --- pkg/golinters/grouper.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkg/golinters/grouper.go b/pkg/golinters/grouper.go index 974efd43c89c..8dff62735911 100644 --- a/pkg/golinters/grouper.go +++ b/pkg/golinters/grouper.go @@ -1,12 +1,11 @@ package golinters import ( + grouper "github.com/leonklingele/grouper/pkg/analyzer" "golang.org/x/tools/go/analysis" "github.com/golangci/golangci-lint/pkg/config" "github.com/golangci/golangci-lint/pkg/golinters/goanalysis" - - grouper "github.com/leonklingele/grouper/pkg/analyzer" ) func NewGrouper(settings *config.GrouperSettings) *goanalysis.Linter { From 6b0798cf0232a5c875960833ad787654014b3fe0 Mon Sep 17 00:00:00 2001 From: Fernandez Ludovic Date: Tue, 25 Jan 2022 01:10:20 +0100 Subject: [PATCH 5/5] review --- pkg/config/linters_settings.go | 15 ++++++--------- pkg/golinters/grouper.go | 15 ++++++--------- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/pkg/config/linters_settings.go b/pkg/config/linters_settings.go index a3744b8e0ae5..7e97ad3c5575 100644 --- a/pkg/config/linters_settings.go +++ b/pkg/config/linters_settings.go @@ -378,17 +378,14 @@ func (cfg GovetSettings) Validate() error { } type GrouperSettings struct { - ConstRequireSingleConst bool `mapstructure:"const-require-single-const"` - ConstRequireGrouping bool `mapstructure:"const-require-grouping"` - + ConstRequireSingleConst bool `mapstructure:"const-require-single-const"` + ConstRequireGrouping bool `mapstructure:"const-require-grouping"` ImportRequireSingleImport bool `mapstructure:"import-require-single-import"` ImportRequireGrouping bool `mapstructure:"import-require-grouping"` - - TypeRequireSingleType bool `mapstructure:"type-require-single-type"` - TypeRequireGrouping bool `mapstructure:"type-require-grouping"` - - VarRequireSingleVar bool `mapstructure:"var-require-single-var"` - VarRequireGrouping bool `mapstructure:"var-require-grouping"` + TypeRequireSingleType bool `mapstructure:"type-require-single-type"` + TypeRequireGrouping bool `mapstructure:"type-require-grouping"` + VarRequireSingleVar bool `mapstructure:"var-require-single-var"` + VarRequireGrouping bool `mapstructure:"var-require-grouping"` } type IfshortSettings struct { diff --git a/pkg/golinters/grouper.go b/pkg/golinters/grouper.go index 8dff62735911..e8c1340e4b7e 100644 --- a/pkg/golinters/grouper.go +++ b/pkg/golinters/grouper.go @@ -12,17 +12,14 @@ func NewGrouper(settings *config.GrouperSettings) *goanalysis.Linter { linterCfg := map[string]map[string]interface{}{} if settings != nil { linterCfg["grouper"] = map[string]interface{}{ - "const-require-single-const": settings.ConstRequireSingleConst, - "const-require-grouping": settings.ConstRequireGrouping, - + "const-require-single-const": settings.ConstRequireSingleConst, + "const-require-grouping": settings.ConstRequireGrouping, "import-require-single-import": settings.ImportRequireSingleImport, "import-require-grouping": settings.ImportRequireGrouping, - - "type-require-single-type": settings.TypeRequireSingleType, - "type-require-grouping": settings.TypeRequireGrouping, - - "var-require-single-var": settings.VarRequireSingleVar, - "var-require-grouping": settings.VarRequireGrouping, + "type-require-single-type": settings.TypeRequireSingleType, + "type-require-grouping": settings.TypeRequireGrouping, + "var-require-single-var": settings.VarRequireSingleVar, + "var-require-grouping": settings.VarRequireGrouping, } }