Skip to content

Commit

Permalink
Add decorder linter (#2453)
Browse files Browse the repository at this point in the history
  • Loading branch information
bosix authored Jan 5, 2022
1 parent d209389 commit 63f150e
Show file tree
Hide file tree
Showing 9 changed files with 136 additions and 0 deletions.
21 changes: 21 additions & 0 deletions .golangci.example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,27 @@ linters-settings:
# should ignore tests (default false)
skip-tests: false

decorder:
# required order of type, const, var and func declarations inside a file
# default: types before constants before variables before functions
dec-order:
- type
- const
- var
- func

# if true, order of declarations is not checked at all
# default: true (disabled)
disable-dec-order-check: false

# if true, init func can be anywhere in file (must not be declared before all other functions)
# default: true (disabled)
disable-init-func-first-check: false

# if true, multiple global type, const and var declarations are allowed
# default: true (disabled)
disable-dec-num-check: false

dogsled:
# checks assignments with too many blank identifiers; default is 2
max-blank-identifiers: 2
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ require (
github.com/uudashr/gocognit v1.0.5
github.com/valyala/quicktemplate v1.7.0
github.com/yeya24/promlinter v0.1.0
gitlab.com/bosi/decorder v0.2.0
golang.org/x/tools v0.1.8
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
honnef.co/go/tools v0.2.2
Expand Down
4 changes: 4 additions & 0 deletions go.sum

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

14 changes: 14 additions & 0 deletions pkg/config/linters_settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ package config
import "github.com/pkg/errors"

var defaultLintersSettings = LintersSettings{
Decorder: DecorderSettings{
DecOrder: []string{"type", "const", "var", "func"},
DisableDecNumCheck: true,
DisableDecOrderCheck: true,
DisableInitFuncFirstCheck: true,
},
Dogsled: DogsledSettings{
MaxBlankIdentifiers: 2,
},
Expand Down Expand Up @@ -85,6 +91,7 @@ var defaultLintersSettings = LintersSettings{
type LintersSettings struct {
BiDiChk BiDiChkSettings
Cyclop Cyclop
Decorder DecorderSettings
Depguard DepGuardSettings
Dogsled DogsledSettings
Dupl DuplSettings
Expand Down Expand Up @@ -173,6 +180,13 @@ type DepGuardSettings struct {
PackagesWithErrorMessage map[string]string `mapstructure:"packages-with-error-message"`
}

type DecorderSettings struct {
DecOrder []string `mapstructure:"dec-order"`
DisableDecNumCheck bool `mapstructure:"disable-dec-num-check"`
DisableDecOrderCheck bool `mapstructure:"disable-dec-order-check"`
DisableInitFuncFirstCheck bool `mapstructure:"disable-init-func-first-check"`
}

type DogsledSettings struct {
MaxBlankIdentifiers int `mapstructure:"max-blank-identifiers"`
}
Expand Down
38 changes: 38 additions & 0 deletions pkg/golinters/decorder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package golinters

import (
"strings"

"gitlab.com/bosi/decorder"
"golang.org/x/tools/go/analysis"

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

func NewDecorder(settings *config.DecorderSettings) *goanalysis.Linter {
a := decorder.Analyzer

analyzers := []*analysis.Analyzer{a}

// disable all rules/checks by default
cfg := map[string]interface{}{
"disable-dec-num-check": true,
"disable-dec-order-check": true,
"disable-init-func-first-check": true,
}

if settings != nil {
cfg["dec-order"] = strings.Join(settings.DecOrder, ",")
cfg["disable-dec-num-check"] = settings.DisableDecNumCheck
cfg["disable-dec-order-check"] = settings.DisableDecOrderCheck
cfg["disable-init-func-first-check"] = settings.DisableInitFuncFirstCheck
}

return goanalysis.NewLinter(
a.Name,
a.Doc,
analyzers,
map[string]map[string]interface{}{a.Name: cfg},
).WithLoadMode(goanalysis.LoadModeSyntax)
}
7 changes: 7 additions & 0 deletions pkg/lint/lintersdb/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ func enableLinterConfigs(lcs []*linter.Config, isEnabled func(lc *linter.Config)
func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
var bidichkCfg *config.BiDiChkSettings
var cyclopCfg *config.Cyclop
var decorderCfg *config.DecorderSettings
var errchkjsonCfg *config.ErrChkJSONSettings
var errorlintCfg *config.ErrorLintSettings
var exhaustiveCfg *config.ExhaustiveSettings
Expand Down Expand Up @@ -131,6 +132,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
bidichkCfg = &m.cfg.LintersSettings.BiDiChk
cyclopCfg = &m.cfg.LintersSettings.Cyclop
errchkjsonCfg = &m.cfg.LintersSettings.ErrChkJSON
decorderCfg = &m.cfg.LintersSettings.Decorder
errorlintCfg = &m.cfg.LintersSettings.ErrorLint
exhaustiveCfg = &m.cfg.LintersSettings.Exhaustive
exhaustiveStructCfg = &m.cfg.LintersSettings.ExhaustiveStruct
Expand Down Expand Up @@ -189,6 +191,11 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
WithPresets(linter.PresetComplexity).
WithURL("https://github.com/bkielbasa/cyclop"),

linter.NewConfig(golinters.NewDecorder(decorderCfg)).
WithSince("v1.44.0").
WithPresets(linter.PresetFormatting, linter.PresetStyle).
WithURL("https://gitlab.com/bosi/decorder"),

linter.NewConfig(golinters.NewDeadcode()).
WithSince("v1.0.0").
WithLoadForGoAnalysis().
Expand Down
10 changes: 10 additions & 0 deletions test/testdata/configs/decorder.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
linters-settings:
decorder:
dec-order:
- type
- const
- var
- func
disable-dec-order-check: false
disable-init-func-first-check: false
disable-dec-num-check: false
21 changes: 21 additions & 0 deletions test/testdata/decorder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// args: -Edecorder
// config_path: testdata/configs/decorder.yml
package testdata

import "math"

const (
decoc = math.MaxInt64
decod = 1
)

var decoa = 1
var decob = 1 // ERROR "multiple \"var\" declarations are not allowed; use parentheses instead"

type decoe int // ERROR "type must not be placed after const"

func decof() {
const decog = 1
}

func init() {} // ERROR "init func must be the first function in file"
20 changes: 20 additions & 0 deletions test/testdata/decorder_default.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// args: -Edecorder
package testdata

import "math"

const (
decoh = math.MaxInt64
decoi = 1
)

var decoj = 1
var decok = 1

type decol int

func decom() {
const decon = 1
}

func init() {}

0 comments on commit 63f150e

Please sign in to comment.