mirror of
https://github.com/mgechev/revive.git
synced 2025-11-23 22:04:49 +02:00
refactor: rule configuration and error management (#1185)
* refactor: avoid running rule once configuration failed * refactor: remove deep-exit in lint/linter.go
This commit is contained in:
@@ -149,6 +149,12 @@ func GetLintingRules(config *lint.Config, extraRules []lint.Rule) ([]lint.Rule,
|
||||
continue // skip disabled rules
|
||||
}
|
||||
|
||||
if r, ok := r.(lint.ConfigurableRule); ok {
|
||||
if err := r.Configure(ruleConfig.Arguments); err != nil {
|
||||
return nil, fmt.Errorf("cannot configure rule: %s", name)
|
||||
}
|
||||
}
|
||||
|
||||
lintingRules = append(lintingRules, r)
|
||||
}
|
||||
|
||||
|
||||
@@ -10,10 +10,10 @@ import (
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
goversion "github.com/hashicorp/go-version"
|
||||
"golang.org/x/mod/modfile"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
// ReadFile defines an abstraction for reading files.
|
||||
@@ -101,20 +101,23 @@ func (l *Linter) Lint(packages [][]string, ruleSet []Rule, config Config) (<-cha
|
||||
perPkgVersions[n] = v
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(len(packages))
|
||||
var wg errgroup.Group
|
||||
for n := range packages {
|
||||
go func(pkg []string, gover *goversion.Version) {
|
||||
wg.Go(func() error {
|
||||
pkg := packages[n]
|
||||
gover := perPkgVersions[n]
|
||||
if err := l.lintPackage(pkg, gover, ruleSet, config, failures); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "error during linting: "+err.Error())
|
||||
os.Exit(1)
|
||||
return fmt.Errorf("error during linting: %w", err)
|
||||
}
|
||||
wg.Done()
|
||||
}(packages[n], perPkgVersions[n])
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
go func() {
|
||||
wg.Wait()
|
||||
err := wg.Wait()
|
||||
if err != nil {
|
||||
failures <- NewInternalFailure(err.Error())
|
||||
}
|
||||
close(failures)
|
||||
}()
|
||||
|
||||
|
||||
@@ -17,6 +17,11 @@ type Rule interface {
|
||||
Apply(*File, Arguments) []Failure
|
||||
}
|
||||
|
||||
// ConfigurableRule defines an abstract configurable rule interface.
|
||||
type ConfigurableRule interface {
|
||||
Configure(Arguments) error
|
||||
}
|
||||
|
||||
// ToFailurePosition returns the failure position.
|
||||
func ToFailurePosition(start, end token.Pos, file *File) FailurePosition {
|
||||
return FailurePosition{
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/mgechev/revive/lint"
|
||||
)
|
||||
@@ -37,18 +36,10 @@ type AddConstantRule struct {
|
||||
allowList allowList
|
||||
ignoreFunctions []*regexp.Regexp
|
||||
strLitLimit int
|
||||
|
||||
configureOnce sync.Once
|
||||
}
|
||||
|
||||
// Apply applies the rule to given file.
|
||||
func (r *AddConstantRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var configureErr error
|
||||
r.configureOnce.Do(func() { configureErr = r.configure(arguments) })
|
||||
if configureErr != nil {
|
||||
return newInternalFailureError(configureErr)
|
||||
}
|
||||
|
||||
func (r *AddConstantRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||
var failures []lint.Failure
|
||||
|
||||
onFailure := func(failure lint.Failure) {
|
||||
@@ -206,7 +197,10 @@ func (w *lintAddConstantRule) isStructTag(n *ast.BasicLit) bool {
|
||||
return ok
|
||||
}
|
||||
|
||||
func (r *AddConstantRule) configure(arguments lint.Arguments) error {
|
||||
// Configure validates the rule configuration, and configures the rule accordingly.
|
||||
//
|
||||
// Configuration implements the [lint.ConfigurableRule] interface.
|
||||
func (r *AddConstantRule) Configure(arguments lint.Arguments) error {
|
||||
r.strLitLimit = defaultStrLitLimit
|
||||
r.allowList = newAllowList()
|
||||
if len(arguments) == 0 {
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"sync"
|
||||
|
||||
"github.com/mgechev/revive/lint"
|
||||
)
|
||||
@@ -12,13 +11,14 @@ import (
|
||||
// ArgumentsLimitRule lints the number of arguments a function can receive.
|
||||
type ArgumentsLimitRule struct {
|
||||
max int
|
||||
|
||||
configureOnce sync.Once
|
||||
}
|
||||
|
||||
const defaultArgumentsLimit = 8
|
||||
|
||||
func (r *ArgumentsLimitRule) configure(arguments lint.Arguments) error {
|
||||
// Configure validates the rule configuration, and configures the rule accordingly.
|
||||
//
|
||||
// Configuration implements the [lint.ConfigurableRule] interface.
|
||||
func (r *ArgumentsLimitRule) Configure(arguments lint.Arguments) error {
|
||||
if len(arguments) < 1 {
|
||||
r.max = defaultArgumentsLimit
|
||||
return nil
|
||||
@@ -33,14 +33,7 @@ func (r *ArgumentsLimitRule) configure(arguments lint.Arguments) error {
|
||||
}
|
||||
|
||||
// Apply applies the rule to given file.
|
||||
func (r *ArgumentsLimitRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var configureErr error
|
||||
r.configureOnce.Do(func() { configureErr = r.configure(arguments) })
|
||||
|
||||
if configureErr != nil {
|
||||
return newInternalFailureError(configureErr)
|
||||
}
|
||||
|
||||
func (r *ArgumentsLimitRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||
var failures []lint.Failure
|
||||
|
||||
for _, decl := range file.AST.Decls {
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/mgechev/revive/lint"
|
||||
)
|
||||
@@ -12,13 +11,14 @@ import (
|
||||
// BannedCharsRule checks if a file contains banned characters.
|
||||
type BannedCharsRule struct {
|
||||
bannedCharList []string
|
||||
|
||||
configureOnce sync.Once
|
||||
}
|
||||
|
||||
const bannedCharsRuleName = "banned-characters"
|
||||
|
||||
func (r *BannedCharsRule) configure(arguments lint.Arguments) error {
|
||||
// Configure validates the rule configuration, and configures the rule accordingly.
|
||||
//
|
||||
// Configuration implements the [lint.ConfigurableRule] interface.
|
||||
func (r *BannedCharsRule) Configure(arguments lint.Arguments) error {
|
||||
if len(arguments) > 0 {
|
||||
err := checkNumberOfArguments(1, arguments, bannedCharsRuleName)
|
||||
if err != nil {
|
||||
@@ -35,14 +35,7 @@ func (r *BannedCharsRule) configure(arguments lint.Arguments) error {
|
||||
}
|
||||
|
||||
// Apply applied the rule to the given file.
|
||||
func (r *BannedCharsRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var configureErr error
|
||||
r.configureOnce.Do(func() { configureErr = r.configure(arguments) })
|
||||
|
||||
if configureErr != nil {
|
||||
return newInternalFailureError(configureErr)
|
||||
}
|
||||
|
||||
func (r *BannedCharsRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||
var failures []lint.Failure
|
||||
onFailure := func(failure lint.Failure) {
|
||||
failures = append(failures, failure)
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/token"
|
||||
"sync"
|
||||
|
||||
"github.com/mgechev/revive/lint"
|
||||
"golang.org/x/tools/go/ast/astutil"
|
||||
@@ -13,13 +12,14 @@ import (
|
||||
// CognitiveComplexityRule sets restriction for maximum cognitive complexity.
|
||||
type CognitiveComplexityRule struct {
|
||||
maxComplexity int
|
||||
|
||||
configureOnce sync.Once
|
||||
}
|
||||
|
||||
const defaultMaxCognitiveComplexity = 7
|
||||
|
||||
func (r *CognitiveComplexityRule) configure(arguments lint.Arguments) error {
|
||||
// Configure validates the rule configuration, and configures the rule accordingly.
|
||||
//
|
||||
// Configuration implements the [lint.ConfigurableRule] interface.
|
||||
func (r *CognitiveComplexityRule) Configure(arguments lint.Arguments) error {
|
||||
if len(arguments) < 1 {
|
||||
r.maxComplexity = defaultMaxCognitiveComplexity
|
||||
return nil
|
||||
@@ -35,14 +35,7 @@ func (r *CognitiveComplexityRule) configure(arguments lint.Arguments) error {
|
||||
}
|
||||
|
||||
// Apply applies the rule to given file.
|
||||
func (r *CognitiveComplexityRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var configureErr error
|
||||
r.configureOnce.Do(func() { configureErr = r.configure(arguments) })
|
||||
|
||||
if configureErr != nil {
|
||||
return newInternalFailureError(configureErr)
|
||||
}
|
||||
|
||||
func (r *CognitiveComplexityRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||
var failures []lint.Failure
|
||||
|
||||
linter := cognitiveComplexityLinter{
|
||||
|
||||
@@ -3,7 +3,6 @@ package rule
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/mgechev/revive/lint"
|
||||
)
|
||||
@@ -12,11 +11,12 @@ import (
|
||||
// the comment symbol( // ) and the start of the comment text
|
||||
type CommentSpacingsRule struct {
|
||||
allowList []string
|
||||
|
||||
configureOnce sync.Once
|
||||
}
|
||||
|
||||
func (r *CommentSpacingsRule) configure(arguments lint.Arguments) error {
|
||||
// Configure validates the rule configuration, and configures the rule accordingly.
|
||||
//
|
||||
// Configuration implements the [lint.ConfigurableRule] interface.
|
||||
func (r *CommentSpacingsRule) Configure(arguments lint.Arguments) error {
|
||||
r.allowList = []string{}
|
||||
for _, arg := range arguments {
|
||||
allow, ok := arg.(string) // Alt. non panicking version
|
||||
@@ -29,14 +29,7 @@ func (r *CommentSpacingsRule) configure(arguments lint.Arguments) error {
|
||||
}
|
||||
|
||||
// Apply the rule.
|
||||
func (r *CommentSpacingsRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var configureErr error
|
||||
r.configureOnce.Do(func() { configureErr = r.configure(arguments) })
|
||||
|
||||
if configureErr != nil {
|
||||
return newInternalFailureError(configureErr)
|
||||
}
|
||||
|
||||
func (r *CommentSpacingsRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||
var failures []lint.Failure
|
||||
|
||||
for _, cg := range file.AST.Comments {
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/mgechev/revive/lint"
|
||||
)
|
||||
@@ -12,13 +11,14 @@ import (
|
||||
// CommentsDensityRule enforces a minimum comment / code relation.
|
||||
type CommentsDensityRule struct {
|
||||
minimumCommentsDensity int64
|
||||
|
||||
configureOnce sync.Once
|
||||
}
|
||||
|
||||
const defaultMinimumCommentsPercentage = 0
|
||||
|
||||
func (r *CommentsDensityRule) configure(arguments lint.Arguments) error {
|
||||
// Configure validates the rule configuration, and configures the rule accordingly.
|
||||
//
|
||||
// Configuration implements the [lint.ConfigurableRule] interface.
|
||||
func (r *CommentsDensityRule) Configure(arguments lint.Arguments) error {
|
||||
if len(arguments) < 1 {
|
||||
r.minimumCommentsDensity = defaultMinimumCommentsPercentage
|
||||
return nil
|
||||
@@ -33,14 +33,7 @@ func (r *CommentsDensityRule) configure(arguments lint.Arguments) error {
|
||||
}
|
||||
|
||||
// Apply applies the rule to given file.
|
||||
func (r *CommentsDensityRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var configureErr error
|
||||
r.configureOnce.Do(func() { configureErr = r.configure(arguments) })
|
||||
|
||||
if configureErr != nil {
|
||||
return newInternalFailureError(configureErr)
|
||||
}
|
||||
|
||||
func (r *CommentsDensityRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||
commentsLines := countDocLines(file.AST.Comments)
|
||||
statementsCount := countStatements(file.AST)
|
||||
density := (float32(commentsLines) / float32(statementsCount+commentsLines)) * 100
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/mgechev/revive/lint"
|
||||
)
|
||||
@@ -12,19 +11,10 @@ import (
|
||||
// ContextAsArgumentRule suggests that `context.Context` should be the first argument of a function.
|
||||
type ContextAsArgumentRule struct {
|
||||
allowTypes map[string]struct{}
|
||||
|
||||
configureOnce sync.Once
|
||||
}
|
||||
|
||||
// Apply applies the rule to given file.
|
||||
func (r *ContextAsArgumentRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var configureErr error
|
||||
r.configureOnce.Do(func() { configureErr = r.configure(arguments) })
|
||||
|
||||
if configureErr != nil {
|
||||
return newInternalFailureError(configureErr)
|
||||
}
|
||||
|
||||
func (r *ContextAsArgumentRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||
var failures []lint.Failure
|
||||
for _, decl := range file.AST.Decls {
|
||||
fn, ok := decl.(*ast.FuncDecl)
|
||||
@@ -64,7 +54,10 @@ func (*ContextAsArgumentRule) Name() string {
|
||||
return "context-as-argument"
|
||||
}
|
||||
|
||||
func (r *ContextAsArgumentRule) configure(arguments lint.Arguments) error {
|
||||
// Configure validates the rule configuration, and configures the rule accordingly.
|
||||
//
|
||||
// Configuration implements the [lint.ConfigurableRule] interface.
|
||||
func (r *ContextAsArgumentRule) Configure(arguments lint.Arguments) error {
|
||||
types, err := r.getAllowTypesFromArguments(arguments)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/token"
|
||||
"sync"
|
||||
|
||||
"github.com/mgechev/revive/lint"
|
||||
)
|
||||
@@ -14,13 +13,14 @@ import (
|
||||
// CyclomaticRule sets restriction for maximum cyclomatic complexity.
|
||||
type CyclomaticRule struct {
|
||||
maxComplexity int
|
||||
|
||||
configureOnce sync.Once
|
||||
}
|
||||
|
||||
const defaultMaxCyclomaticComplexity = 10
|
||||
|
||||
func (r *CyclomaticRule) configure(arguments lint.Arguments) error {
|
||||
// Configure validates the rule configuration, and configures the rule accordingly.
|
||||
//
|
||||
// Configuration implements the [lint.ConfigurableRule] interface.
|
||||
func (r *CyclomaticRule) Configure(arguments lint.Arguments) error {
|
||||
if len(arguments) < 1 {
|
||||
r.maxComplexity = defaultMaxCyclomaticComplexity
|
||||
return nil
|
||||
@@ -35,14 +35,7 @@ func (r *CyclomaticRule) configure(arguments lint.Arguments) error {
|
||||
}
|
||||
|
||||
// Apply applies the rule to given file.
|
||||
func (r *CyclomaticRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var configureErr error
|
||||
r.configureOnce.Do(func() { configureErr = r.configure(arguments) })
|
||||
|
||||
if configureErr != nil {
|
||||
return newInternalFailureError(configureErr)
|
||||
}
|
||||
|
||||
func (r *CyclomaticRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||
var failures []lint.Failure
|
||||
for _, decl := range file.AST.Decls {
|
||||
fn, ok := decl.(*ast.FuncDecl)
|
||||
|
||||
@@ -3,7 +3,6 @@ package rule
|
||||
import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"sync"
|
||||
|
||||
"github.com/mgechev/revive/lint"
|
||||
)
|
||||
@@ -11,11 +10,12 @@ import (
|
||||
// DeferRule lints gotchas in defer statements.
|
||||
type DeferRule struct {
|
||||
allow map[string]bool
|
||||
|
||||
configureOnce sync.Once
|
||||
}
|
||||
|
||||
func (r *DeferRule) configure(arguments lint.Arguments) error {
|
||||
// Configure validates the rule configuration, and configures the rule accordingly.
|
||||
//
|
||||
// Configuration implements the [lint.ConfigurableRule] interface.
|
||||
func (r *DeferRule) Configure(arguments lint.Arguments) error {
|
||||
list, err := r.allowFromArgs(arguments)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -25,14 +25,7 @@ func (r *DeferRule) configure(arguments lint.Arguments) error {
|
||||
}
|
||||
|
||||
// Apply applies the rule to given file.
|
||||
func (r *DeferRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var configureErr error
|
||||
r.configureOnce.Do(func() { configureErr = r.configure(arguments) })
|
||||
|
||||
if configureErr != nil {
|
||||
return newInternalFailureError(configureErr)
|
||||
}
|
||||
|
||||
func (r *DeferRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||
var failures []lint.Failure
|
||||
onFailure := func(failure lint.Failure) {
|
||||
failures = append(failures, failure)
|
||||
|
||||
@@ -3,7 +3,6 @@ package rule
|
||||
import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"sync"
|
||||
|
||||
"github.com/mgechev/revive/lint"
|
||||
)
|
||||
@@ -11,19 +10,10 @@ import (
|
||||
// DotImportsRule forbids . imports.
|
||||
type DotImportsRule struct {
|
||||
allowedPackages allowPackages
|
||||
|
||||
configureOnce sync.Once
|
||||
}
|
||||
|
||||
// Apply applies the rule to given file.
|
||||
func (r *DotImportsRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var configureErr error
|
||||
r.configureOnce.Do(func() { configureErr = r.configure(arguments) })
|
||||
|
||||
if configureErr != nil {
|
||||
return newInternalFailureError(configureErr)
|
||||
}
|
||||
|
||||
func (r *DotImportsRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||
var failures []lint.Failure
|
||||
|
||||
fileAst := file.AST
|
||||
@@ -46,7 +36,10 @@ func (*DotImportsRule) Name() string {
|
||||
return "dot-imports"
|
||||
}
|
||||
|
||||
func (r *DotImportsRule) configure(arguments lint.Arguments) error {
|
||||
// Configure validates the rule configuration, and configures the rule accordingly.
|
||||
//
|
||||
// Configuration implements the [lint.ConfigurableRule] interface.
|
||||
func (r *DotImportsRule) Configure(arguments lint.Arguments) error {
|
||||
r.allowedPackages = allowPackages{}
|
||||
if len(arguments) == 0 {
|
||||
return nil
|
||||
|
||||
@@ -3,7 +3,6 @@ package rule
|
||||
import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"sync"
|
||||
|
||||
"github.com/mgechev/revive/lint"
|
||||
)
|
||||
@@ -40,11 +39,12 @@ func mapStyleFromString(s string) (enforceMapStyleType, error) {
|
||||
// EnforceMapStyleRule implements a rule to enforce `make(map[type]type)` over `map[type]type{}`.
|
||||
type EnforceMapStyleRule struct {
|
||||
enforceMapStyle enforceMapStyleType
|
||||
|
||||
configureOnce sync.Once
|
||||
}
|
||||
|
||||
func (r *EnforceMapStyleRule) configure(arguments lint.Arguments) error {
|
||||
// Configure validates the rule configuration, and configures the rule accordingly.
|
||||
//
|
||||
// Configuration implements the [lint.ConfigurableRule] interface.
|
||||
func (r *EnforceMapStyleRule) Configure(arguments lint.Arguments) error {
|
||||
if len(arguments) < 1 {
|
||||
r.enforceMapStyle = enforceMapStyleTypeAny
|
||||
return nil
|
||||
@@ -65,14 +65,7 @@ func (r *EnforceMapStyleRule) configure(arguments lint.Arguments) error {
|
||||
}
|
||||
|
||||
// Apply applies the rule to given file.
|
||||
func (r *EnforceMapStyleRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var configureErr error
|
||||
r.configureOnce.Do(func() { configureErr = r.configure(arguments) })
|
||||
|
||||
if configureErr != nil {
|
||||
return newInternalFailureError(configureErr)
|
||||
}
|
||||
|
||||
func (r *EnforceMapStyleRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||
if r.enforceMapStyle == enforceMapStyleTypeAny {
|
||||
// this linter is not configured
|
||||
return nil
|
||||
|
||||
@@ -3,7 +3,6 @@ package rule
|
||||
import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"sync"
|
||||
|
||||
"github.com/mgechev/revive/lint"
|
||||
)
|
||||
@@ -43,11 +42,12 @@ func repeatedArgTypeStyleFromString(s string) (enforceRepeatedArgTypeStyleType,
|
||||
type EnforceRepeatedArgTypeStyleRule struct {
|
||||
funcArgStyle enforceRepeatedArgTypeStyleType
|
||||
funcRetValStyle enforceRepeatedArgTypeStyleType
|
||||
|
||||
configureOnce sync.Once
|
||||
}
|
||||
|
||||
func (r *EnforceRepeatedArgTypeStyleRule) configure(arguments lint.Arguments) error {
|
||||
// Configure validates the rule configuration, and configures the rule accordingly.
|
||||
//
|
||||
// Configuration implements the [lint.ConfigurableRule] interface.
|
||||
func (r *EnforceRepeatedArgTypeStyleRule) Configure(arguments lint.Arguments) error {
|
||||
r.funcArgStyle = enforceRepeatedArgTypeStyleTypeAny
|
||||
r.funcRetValStyle = enforceRepeatedArgTypeStyleTypeAny
|
||||
|
||||
@@ -101,14 +101,7 @@ func (r *EnforceRepeatedArgTypeStyleRule) configure(arguments lint.Arguments) er
|
||||
}
|
||||
|
||||
// Apply applies the rule to a given file.
|
||||
func (r *EnforceRepeatedArgTypeStyleRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var configureErr error
|
||||
r.configureOnce.Do(func() { configureErr = r.configure(arguments) })
|
||||
|
||||
if configureErr != nil {
|
||||
return newInternalFailureError(configureErr)
|
||||
}
|
||||
|
||||
func (r *EnforceRepeatedArgTypeStyleRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||
if r.funcArgStyle == enforceRepeatedArgTypeStyleTypeAny && r.funcRetValStyle == enforceRepeatedArgTypeStyleTypeAny {
|
||||
// This linter is not configured, return no failures.
|
||||
return nil
|
||||
|
||||
@@ -3,7 +3,6 @@ package rule
|
||||
import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"sync"
|
||||
|
||||
"github.com/mgechev/revive/lint"
|
||||
)
|
||||
@@ -44,11 +43,12 @@ func sliceStyleFromString(s string) (enforceSliceStyleType, error) {
|
||||
// EnforceSliceStyleRule implements a rule to enforce `make([]type)` over `[]type{}`.
|
||||
type EnforceSliceStyleRule struct {
|
||||
enforceSliceStyle enforceSliceStyleType
|
||||
|
||||
configureOnce sync.Once
|
||||
}
|
||||
|
||||
func (r *EnforceSliceStyleRule) configure(arguments lint.Arguments) error {
|
||||
// Configure validates the rule configuration, and configures the rule accordingly.
|
||||
//
|
||||
// Configuration implements the [lint.ConfigurableRule] interface.
|
||||
func (r *EnforceSliceStyleRule) Configure(arguments lint.Arguments) error {
|
||||
if len(arguments) < 1 {
|
||||
r.enforceSliceStyle = enforceSliceStyleTypeAny
|
||||
return nil
|
||||
@@ -68,14 +68,7 @@ func (r *EnforceSliceStyleRule) configure(arguments lint.Arguments) error {
|
||||
}
|
||||
|
||||
// Apply applies the rule to given file.
|
||||
func (r *EnforceSliceStyleRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var configureErr error
|
||||
r.configureOnce.Do(func() { configureErr = r.configure(arguments) })
|
||||
|
||||
if configureErr != nil {
|
||||
return newInternalFailureError(configureErr)
|
||||
}
|
||||
|
||||
func (r *EnforceSliceStyleRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||
if r.enforceSliceStyle == enforceSliceStyleTypeAny {
|
||||
// this linter is not configured
|
||||
return nil
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"go/token"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
||||
@@ -16,11 +15,12 @@ import (
|
||||
// ErrorStringsRule lints error strings.
|
||||
type ErrorStringsRule struct {
|
||||
errorFunctions map[string]map[string]struct{}
|
||||
|
||||
configureOnce sync.Once
|
||||
}
|
||||
|
||||
func (r *ErrorStringsRule) configure(arguments lint.Arguments) error {
|
||||
// Configure validates the rule configuration, and configures the rule accordingly.
|
||||
//
|
||||
// Configuration implements the [lint.ConfigurableRule] interface.
|
||||
func (r *ErrorStringsRule) Configure(arguments lint.Arguments) error {
|
||||
r.errorFunctions = map[string]map[string]struct{}{
|
||||
"fmt": {
|
||||
"Errorf": {},
|
||||
@@ -53,14 +53,7 @@ func (r *ErrorStringsRule) configure(arguments lint.Arguments) error {
|
||||
}
|
||||
|
||||
// Apply applies the rule to given file.
|
||||
func (r *ErrorStringsRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var configureErr error
|
||||
r.configureOnce.Do(func() { configureErr = r.configure(arguments) })
|
||||
|
||||
if configureErr != nil {
|
||||
return newInternalFailureError(configureErr)
|
||||
}
|
||||
|
||||
func (r *ErrorStringsRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||
var failures []lint.Failure
|
||||
|
||||
fileAst := file.AST
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"go/ast"
|
||||
"go/token"
|
||||
"strings"
|
||||
"sync"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
||||
@@ -25,9 +24,11 @@ type disabledChecks struct {
|
||||
Var bool
|
||||
}
|
||||
|
||||
const checkNamePrivateReceivers = "privateReceivers"
|
||||
const checkNamePublicInterfaces = "publicInterfaces"
|
||||
const checkNameStuttering = "stuttering"
|
||||
const (
|
||||
checkNamePrivateReceivers = "privateReceivers"
|
||||
checkNamePublicInterfaces = "publicInterfaces"
|
||||
checkNameStuttering = "stuttering"
|
||||
)
|
||||
|
||||
// isDisabled returns true if the given check is disabled, false otherwise
|
||||
func (dc *disabledChecks) isDisabled(checkName string) bool {
|
||||
@@ -66,11 +67,12 @@ var commonMethods = map[string]bool{
|
||||
type ExportedRule struct {
|
||||
stuttersMsg string
|
||||
disabledChecks disabledChecks
|
||||
|
||||
configureOnce sync.Once
|
||||
}
|
||||
|
||||
func (r *ExportedRule) configure(arguments lint.Arguments) error {
|
||||
// Configure validates the rule configuration, and configures the rule accordingly.
|
||||
//
|
||||
// Configuration implements the [lint.ConfigurableRule] interface.
|
||||
func (r *ExportedRule) Configure(arguments lint.Arguments) error {
|
||||
r.disabledChecks = disabledChecks{PrivateReceivers: true, PublicInterfaces: true}
|
||||
r.stuttersMsg = "stutters"
|
||||
for _, flag := range arguments {
|
||||
@@ -107,14 +109,7 @@ func (r *ExportedRule) configure(arguments lint.Arguments) error {
|
||||
}
|
||||
|
||||
// Apply applies the rule to given file.
|
||||
func (r *ExportedRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var configureErr error
|
||||
r.configureOnce.Do(func() { configureErr = r.configure(arguments) })
|
||||
|
||||
if configureErr != nil {
|
||||
return newInternalFailureError(configureErr)
|
||||
}
|
||||
|
||||
func (r *ExportedRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||
var failures []lint.Failure
|
||||
if file.IsTest() {
|
||||
return failures
|
||||
|
||||
@@ -3,7 +3,6 @@ package rule
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"sync"
|
||||
|
||||
"github.com/mgechev/revive/lint"
|
||||
)
|
||||
@@ -11,8 +10,6 @@ import (
|
||||
// FileHeaderRule lints the header that each file should have.
|
||||
type FileHeaderRule struct {
|
||||
header string
|
||||
|
||||
configureOnce sync.Once
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -20,7 +17,10 @@ var (
|
||||
singleRegexp = regexp.MustCompile("^//")
|
||||
)
|
||||
|
||||
func (r *FileHeaderRule) configure(arguments lint.Arguments) error {
|
||||
// Configure validates the rule configuration, and configures the rule accordingly.
|
||||
//
|
||||
// Configuration implements the [lint.ConfigurableRule] interface.
|
||||
func (r *FileHeaderRule) Configure(arguments lint.Arguments) error {
|
||||
if len(arguments) < 1 {
|
||||
return nil
|
||||
}
|
||||
@@ -34,14 +34,7 @@ func (r *FileHeaderRule) configure(arguments lint.Arguments) error {
|
||||
}
|
||||
|
||||
// Apply applies the rule to given file.
|
||||
func (r *FileHeaderRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var configureErr error
|
||||
r.configureOnce.Do(func() { configureErr = r.configure(arguments) })
|
||||
|
||||
if configureErr != nil {
|
||||
return newInternalFailureError(configureErr)
|
||||
}
|
||||
|
||||
func (r *FileHeaderRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||
if r.header == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"go/ast"
|
||||
"go/token"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/mgechev/revive/lint"
|
||||
)
|
||||
@@ -20,19 +19,10 @@ type FileLengthLimitRule struct {
|
||||
skipComments bool
|
||||
// skipBlankLines indicates whether to skip blank lines when counting lines.
|
||||
skipBlankLines bool
|
||||
|
||||
configureOnce sync.Once
|
||||
}
|
||||
|
||||
// Apply applies the rule to given file.
|
||||
func (r *FileLengthLimitRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var configureErr error
|
||||
r.configureOnce.Do(func() { configureErr = r.configure(arguments) })
|
||||
|
||||
if configureErr != nil {
|
||||
return newInternalFailureError(configureErr)
|
||||
}
|
||||
|
||||
func (r *FileLengthLimitRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||
if r.max <= 0 {
|
||||
// when max is negative or 0 the rule is disabled
|
||||
return nil
|
||||
@@ -80,7 +70,10 @@ func (r *FileLengthLimitRule) Apply(file *lint.File, arguments lint.Arguments) [
|
||||
}
|
||||
}
|
||||
|
||||
func (r *FileLengthLimitRule) configure(arguments lint.Arguments) error {
|
||||
// Configure validates the rule configuration, and configures the rule accordingly.
|
||||
//
|
||||
// Configuration implements the [lint.ConfigurableRule] interface.
|
||||
func (r *FileLengthLimitRule) Configure(arguments lint.Arguments) error {
|
||||
if len(arguments) < 1 {
|
||||
return nil // use default
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sync"
|
||||
"unicode"
|
||||
|
||||
"github.com/mgechev/revive/lint"
|
||||
@@ -13,19 +12,10 @@ import (
|
||||
// FilenameFormatRule lints source filenames according to a set of regular expressions given as arguments
|
||||
type FilenameFormatRule struct {
|
||||
format *regexp.Regexp
|
||||
|
||||
configureOnce sync.Once
|
||||
}
|
||||
|
||||
// Apply applies the rule to the given file.
|
||||
func (r *FilenameFormatRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var configureErr error
|
||||
r.configureOnce.Do(func() { configureErr = r.configure(arguments) })
|
||||
|
||||
if configureErr != nil {
|
||||
return newInternalFailureError(configureErr)
|
||||
}
|
||||
|
||||
func (r *FilenameFormatRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||
filename := filepath.Base(file.Name)
|
||||
if r.format.MatchString(filename) {
|
||||
return nil
|
||||
@@ -60,7 +50,10 @@ func (*FilenameFormatRule) Name() string {
|
||||
|
||||
var defaultFormat = regexp.MustCompile(`^[_A-Za-z0-9][_A-Za-z0-9-]*\.go$`)
|
||||
|
||||
func (r *FilenameFormatRule) configure(arguments lint.Arguments) error {
|
||||
// Configure validates the rule configuration, and configures the rule accordingly.
|
||||
//
|
||||
// Configuration implements the [lint.ConfigurableRule] interface.
|
||||
func (r *FilenameFormatRule) Configure(arguments lint.Arguments) error {
|
||||
argsCount := len(arguments)
|
||||
if argsCount == 0 {
|
||||
r.format = defaultFormat
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"reflect"
|
||||
"sync"
|
||||
|
||||
"github.com/mgechev/revive/lint"
|
||||
)
|
||||
@@ -13,11 +12,12 @@ import (
|
||||
type FunctionLength struct {
|
||||
maxStmt int
|
||||
maxLines int
|
||||
|
||||
configureOnce sync.Once
|
||||
}
|
||||
|
||||
func (r *FunctionLength) configure(arguments lint.Arguments) error {
|
||||
// Configure validates the rule configuration, and configures the rule accordingly.
|
||||
//
|
||||
// Configuration implements the [lint.ConfigurableRule] interface.
|
||||
func (r *FunctionLength) Configure(arguments lint.Arguments) error {
|
||||
maxStmt, maxLines, err := r.parseArguments(arguments)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -28,14 +28,7 @@ func (r *FunctionLength) configure(arguments lint.Arguments) error {
|
||||
}
|
||||
|
||||
// Apply applies the rule to given file.
|
||||
func (r *FunctionLength) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var configureErr error
|
||||
r.configureOnce.Do(func() { configureErr = r.configure(arguments) })
|
||||
|
||||
if configureErr != nil {
|
||||
return newInternalFailureError(configureErr)
|
||||
}
|
||||
|
||||
func (r *FunctionLength) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||
var failures []lint.Failure
|
||||
for _, decl := range file.AST.Decls {
|
||||
funcDecl, ok := decl.(*ast.FuncDecl)
|
||||
@@ -80,8 +73,10 @@ func (*FunctionLength) Name() string {
|
||||
return "function-length"
|
||||
}
|
||||
|
||||
const defaultFuncStmtsLimit = 50
|
||||
const defaultFuncLinesLimit = 75
|
||||
const (
|
||||
defaultFuncStmtsLimit = 50
|
||||
defaultFuncLinesLimit = 75
|
||||
)
|
||||
|
||||
func (*FunctionLength) parseArguments(arguments lint.Arguments) (maxStmt, maxLines int64, err error) {
|
||||
if len(arguments) == 0 {
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"sync"
|
||||
|
||||
"github.com/mgechev/revive/lint"
|
||||
)
|
||||
@@ -12,19 +11,10 @@ import (
|
||||
// FunctionResultsLimitRule limits the maximum number of results a function can return.
|
||||
type FunctionResultsLimitRule struct {
|
||||
max int
|
||||
|
||||
configureOnce sync.Once
|
||||
}
|
||||
|
||||
// Apply applies the rule to given file.
|
||||
func (r *FunctionResultsLimitRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var configureErr error
|
||||
r.configureOnce.Do(func() { configureErr = r.configure(arguments) })
|
||||
|
||||
if configureErr != nil {
|
||||
return newInternalFailureError(configureErr)
|
||||
}
|
||||
|
||||
func (r *FunctionResultsLimitRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||
var failures []lint.Failure
|
||||
for _, decl := range file.AST.Decls {
|
||||
funcDecl, ok := decl.(*ast.FuncDecl)
|
||||
@@ -59,7 +49,10 @@ func (*FunctionResultsLimitRule) Name() string {
|
||||
|
||||
const defaultResultsLimit = 3
|
||||
|
||||
func (r *FunctionResultsLimitRule) configure(arguments lint.Arguments) error {
|
||||
// Configure validates the rule configuration, and configures the rule accordingly.
|
||||
//
|
||||
// Configuration implements the [lint.ConfigurableRule] interface.
|
||||
func (r *FunctionResultsLimitRule) Configure(arguments lint.Arguments) error {
|
||||
if len(arguments) < 1 {
|
||||
r.max = defaultResultsLimit
|
||||
return nil
|
||||
|
||||
@@ -3,7 +3,6 @@ package rule
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"sync"
|
||||
|
||||
"github.com/mgechev/revive/lint"
|
||||
)
|
||||
@@ -12,15 +11,16 @@ import (
|
||||
type ImportAliasNamingRule struct {
|
||||
allowRegexp *regexp.Regexp
|
||||
denyRegexp *regexp.Regexp
|
||||
|
||||
configureOnce sync.Once
|
||||
}
|
||||
|
||||
const defaultImportAliasNamingAllowRule = "^[a-z][a-z0-9]{0,}$"
|
||||
|
||||
var defaultImportAliasNamingAllowRegexp = regexp.MustCompile(defaultImportAliasNamingAllowRule)
|
||||
|
||||
func (r *ImportAliasNamingRule) configure(arguments lint.Arguments) error {
|
||||
// Configure validates the rule configuration, and configures the rule accordingly.
|
||||
//
|
||||
// Configuration implements the [lint.ConfigurableRule] interface.
|
||||
func (r *ImportAliasNamingRule) Configure(arguments lint.Arguments) error {
|
||||
if len(arguments) == 0 {
|
||||
r.allowRegexp = defaultImportAliasNamingAllowRegexp
|
||||
return nil
|
||||
@@ -61,14 +61,7 @@ func (r *ImportAliasNamingRule) configure(arguments lint.Arguments) error {
|
||||
}
|
||||
|
||||
// Apply applies the rule to given file.
|
||||
func (r *ImportAliasNamingRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var configureErr error
|
||||
r.configureOnce.Do(func() { configureErr = r.configure(arguments) })
|
||||
|
||||
if configureErr != nil {
|
||||
return newInternalFailureError(configureErr)
|
||||
}
|
||||
|
||||
func (r *ImportAliasNamingRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||
var failures []lint.Failure
|
||||
|
||||
for _, is := range file.AST.Imports {
|
||||
|
||||
@@ -3,7 +3,6 @@ package rule
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"sync"
|
||||
|
||||
"github.com/mgechev/revive/lint"
|
||||
)
|
||||
@@ -11,13 +10,14 @@ import (
|
||||
// ImportsBlocklistRule disallows importing the specified packages.
|
||||
type ImportsBlocklistRule struct {
|
||||
blocklist []*regexp.Regexp
|
||||
|
||||
configureOnce sync.Once
|
||||
}
|
||||
|
||||
var replaceImportRegexp = regexp.MustCompile(`/?\*\*/?`)
|
||||
|
||||
func (r *ImportsBlocklistRule) configure(arguments lint.Arguments) error {
|
||||
// Configure validates the rule configuration, and configures the rule accordingly.
|
||||
//
|
||||
// Configuration implements the [lint.ConfigurableRule] interface.
|
||||
func (r *ImportsBlocklistRule) Configure(arguments lint.Arguments) error {
|
||||
r.blocklist = []*regexp.Regexp{}
|
||||
for _, arg := range arguments {
|
||||
argStr, ok := arg.(string)
|
||||
@@ -43,14 +43,7 @@ func (r *ImportsBlocklistRule) isBlocklisted(path string) bool {
|
||||
}
|
||||
|
||||
// Apply applies the rule to given file.
|
||||
func (r *ImportsBlocklistRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var configureErr error
|
||||
r.configureOnce.Do(func() { configureErr = r.configure(arguments) })
|
||||
|
||||
if configureErr != nil {
|
||||
return newInternalFailureError(configureErr)
|
||||
}
|
||||
|
||||
func (r *ImportsBlocklistRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||
var failures []lint.Failure
|
||||
|
||||
for _, is := range file.AST.Imports {
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"fmt"
|
||||
"go/token"
|
||||
"strings"
|
||||
"sync"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/mgechev/revive/lint"
|
||||
@@ -16,13 +15,14 @@ import (
|
||||
// LineLengthLimitRule lints number of characters in a line.
|
||||
type LineLengthLimitRule struct {
|
||||
max int
|
||||
|
||||
configureOnce sync.Once
|
||||
}
|
||||
|
||||
const defaultLineLengthLimit = 80
|
||||
|
||||
func (r *LineLengthLimitRule) configure(arguments lint.Arguments) error {
|
||||
// Configure validates the rule configuration, and configures the rule accordingly.
|
||||
//
|
||||
// Configuration implements the [lint.ConfigurableRule] interface.
|
||||
func (r *LineLengthLimitRule) Configure(arguments lint.Arguments) error {
|
||||
if len(arguments) < 1 {
|
||||
r.max = defaultLineLengthLimit
|
||||
return nil
|
||||
@@ -38,14 +38,7 @@ func (r *LineLengthLimitRule) configure(arguments lint.Arguments) error {
|
||||
}
|
||||
|
||||
// Apply applies the rule to given file.
|
||||
func (r *LineLengthLimitRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var configureErr error
|
||||
r.configureOnce.Do(func() { configureErr = r.configure(arguments) })
|
||||
|
||||
if configureErr != nil {
|
||||
return newInternalFailureError(configureErr)
|
||||
}
|
||||
|
||||
func (r *LineLengthLimitRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||
var failures []lint.Failure
|
||||
|
||||
checker := lintLineLengthNum{
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"sync"
|
||||
|
||||
"github.com/mgechev/revive/lint"
|
||||
)
|
||||
@@ -12,21 +11,12 @@ import (
|
||||
// MaxControlNestingRule sets restriction for maximum nesting of control structures.
|
||||
type MaxControlNestingRule struct {
|
||||
max int64
|
||||
|
||||
configureOnce sync.Once
|
||||
}
|
||||
|
||||
const defaultMaxControlNesting = 5
|
||||
|
||||
// Apply applies the rule to given file.
|
||||
func (r *MaxControlNestingRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var configureErr error
|
||||
r.configureOnce.Do(func() { configureErr = r.configure(arguments) })
|
||||
|
||||
if configureErr != nil {
|
||||
return newInternalFailureError(configureErr)
|
||||
}
|
||||
|
||||
func (r *MaxControlNestingRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||
var failures []lint.Failure
|
||||
|
||||
fileAst := file.AST
|
||||
@@ -113,7 +103,10 @@ func (w *lintMaxControlNesting) walkControlledBlock(b ast.Node) {
|
||||
w.nestingLevelAcc = oldNestingLevel
|
||||
}
|
||||
|
||||
func (r *MaxControlNestingRule) configure(arguments lint.Arguments) error {
|
||||
// Configure validates the rule configuration, and configures the rule accordingly.
|
||||
//
|
||||
// Configuration implements the [lint.ConfigurableRule] interface.
|
||||
func (r *MaxControlNestingRule) Configure(arguments lint.Arguments) error {
|
||||
if len(arguments) < 1 {
|
||||
r.max = defaultMaxControlNesting
|
||||
return nil
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/mgechev/revive/lint"
|
||||
)
|
||||
@@ -13,13 +12,14 @@ import (
|
||||
// MaxPublicStructsRule lints the number of public structs in a file.
|
||||
type MaxPublicStructsRule struct {
|
||||
max int64
|
||||
|
||||
configureOnce sync.Once
|
||||
}
|
||||
|
||||
const defaultMaxPublicStructs = 5
|
||||
|
||||
func (r *MaxPublicStructsRule) configure(arguments lint.Arguments) error {
|
||||
// Configure validates the rule configuration, and configures the rule accordingly.
|
||||
//
|
||||
// Configuration implements the [lint.ConfigurableRule] interface.
|
||||
func (r *MaxPublicStructsRule) Configure(arguments lint.Arguments) error {
|
||||
if len(arguments) < 1 {
|
||||
r.max = defaultMaxPublicStructs
|
||||
return nil
|
||||
@@ -39,14 +39,7 @@ func (r *MaxPublicStructsRule) configure(arguments lint.Arguments) error {
|
||||
}
|
||||
|
||||
// Apply applies the rule to given file.
|
||||
func (r *MaxPublicStructsRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var configureErr error
|
||||
r.configureOnce.Do(func() { configureErr = r.configure(arguments) })
|
||||
|
||||
if configureErr != nil {
|
||||
return newInternalFailureError(configureErr)
|
||||
}
|
||||
|
||||
func (r *MaxPublicStructsRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||
var failures []lint.Failure
|
||||
|
||||
if r.max < 1 {
|
||||
|
||||
@@ -3,7 +3,6 @@ package rule
|
||||
import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"sync"
|
||||
|
||||
"github.com/mgechev/revive/internal/typeparams"
|
||||
"github.com/mgechev/revive/lint"
|
||||
@@ -12,13 +11,13 @@ import (
|
||||
// ReceiverNamingRule lints a receiver name.
|
||||
type ReceiverNamingRule struct {
|
||||
receiverNameMaxLength int
|
||||
|
||||
configureOnce sync.Once
|
||||
}
|
||||
|
||||
const defaultReceiverNameMaxLength = -1 // thus will not check
|
||||
|
||||
func (r *ReceiverNamingRule) configure(arguments lint.Arguments) error {
|
||||
// Configure validates the rule configuration, and configures the rule accordingly.
|
||||
//
|
||||
// Configuration implements the [lint.ConfigurableRule] interface.
|
||||
func (r *ReceiverNamingRule) Configure(arguments lint.Arguments) error {
|
||||
r.receiverNameMaxLength = defaultReceiverNameMaxLength
|
||||
if len(arguments) < 1 {
|
||||
return nil
|
||||
@@ -45,14 +44,7 @@ func (r *ReceiverNamingRule) configure(arguments lint.Arguments) error {
|
||||
}
|
||||
|
||||
// Apply applies the rule to given file.
|
||||
func (r *ReceiverNamingRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var configureErr error
|
||||
r.configureOnce.Do(func() { configureErr = r.configure(arguments) })
|
||||
|
||||
if configureErr != nil {
|
||||
return newInternalFailureError(configureErr)
|
||||
}
|
||||
|
||||
func (r *ReceiverNamingRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||
typeReceiver := map[string]string{}
|
||||
var failures []lint.Failure
|
||||
for _, decl := range file.AST.Decls {
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"go/ast"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/fatih/structtag"
|
||||
"github.com/mgechev/revive/lint"
|
||||
@@ -14,11 +13,12 @@ import (
|
||||
// StructTagRule lints struct tags.
|
||||
type StructTagRule struct {
|
||||
userDefined map[string][]string // map: key -> []option
|
||||
|
||||
configureOnce sync.Once
|
||||
}
|
||||
|
||||
func (r *StructTagRule) configure(arguments lint.Arguments) error {
|
||||
// Configure validates the rule configuration, and configures the rule accordingly.
|
||||
//
|
||||
// Configuration implements the [lint.ConfigurableRule] interface.
|
||||
func (r *StructTagRule) Configure(arguments lint.Arguments) error {
|
||||
if len(arguments) == 0 {
|
||||
return nil
|
||||
}
|
||||
@@ -47,14 +47,7 @@ func (r *StructTagRule) configure(arguments lint.Arguments) error {
|
||||
}
|
||||
|
||||
// Apply applies the rule to given file.
|
||||
func (r *StructTagRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var configureErr error
|
||||
r.configureOnce.Do(func() { configureErr = r.configure(arguments) })
|
||||
|
||||
if configureErr != nil {
|
||||
return newInternalFailureError(configureErr)
|
||||
}
|
||||
|
||||
func (r *StructTagRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||
var failures []lint.Failure
|
||||
onFailure := func(failure lint.Failure) {
|
||||
failures = append(failures, failure)
|
||||
@@ -102,14 +95,16 @@ func (w lintStructTagRule) Visit(node ast.Node) ast.Visitor {
|
||||
return w
|
||||
}
|
||||
|
||||
const keyASN1 = "asn1"
|
||||
const keyBSON = "bson"
|
||||
const keyDefault = "default"
|
||||
const keyJSON = "json"
|
||||
const keyProtobuf = "protobuf"
|
||||
const keyRequired = "required"
|
||||
const keyXML = "xml"
|
||||
const keyYAML = "yaml"
|
||||
const (
|
||||
keyASN1 = "asn1"
|
||||
keyBSON = "bson"
|
||||
keyDefault = "default"
|
||||
keyJSON = "json"
|
||||
keyProtobuf = "protobuf"
|
||||
keyRequired = "required"
|
||||
keyXML = "xml"
|
||||
keyYAML = "yaml"
|
||||
)
|
||||
|
||||
func (w lintStructTagRule) checkTagNameIfNeed(tag *structtag.Tag) (string, bool) {
|
||||
isUnnamedTag := tag.Name == "" || tag.Name == "-"
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"sync"
|
||||
|
||||
"github.com/mgechev/revive/lint"
|
||||
)
|
||||
@@ -17,11 +16,12 @@ const (
|
||||
// UncheckedTypeAssertionRule lints missing or ignored `ok`-value in dynamic type casts.
|
||||
type UncheckedTypeAssertionRule struct {
|
||||
acceptIgnoredAssertionResult bool
|
||||
|
||||
configureOnce sync.Once
|
||||
}
|
||||
|
||||
func (r *UncheckedTypeAssertionRule) configure(arguments lint.Arguments) error {
|
||||
// Configure validates the rule configuration, and configures the rule accordingly.
|
||||
//
|
||||
// Configuration implements the [lint.ConfigurableRule] interface.
|
||||
func (r *UncheckedTypeAssertionRule) Configure(arguments lint.Arguments) error {
|
||||
if len(arguments) == 0 {
|
||||
return nil
|
||||
}
|
||||
@@ -46,14 +46,7 @@ func (r *UncheckedTypeAssertionRule) configure(arguments lint.Arguments) error {
|
||||
}
|
||||
|
||||
// Apply applies the rule to given file.
|
||||
func (r *UncheckedTypeAssertionRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var configureErr error
|
||||
r.configureOnce.Do(func() { configureErr = r.configure(arguments) })
|
||||
|
||||
if configureErr != nil {
|
||||
return newInternalFailureError(configureErr)
|
||||
}
|
||||
|
||||
func (r *UncheckedTypeAssertionRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||
var failures []lint.Failure
|
||||
|
||||
walker := &lintUncheckedTypeAssertion{
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"go/types"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/mgechev/revive/lint"
|
||||
)
|
||||
@@ -15,11 +14,12 @@ import (
|
||||
// UnhandledErrorRule warns on unhandled errors returned by function calls.
|
||||
type UnhandledErrorRule struct {
|
||||
ignoreList []*regexp.Regexp
|
||||
|
||||
configureOnce sync.Once
|
||||
}
|
||||
|
||||
func (r *UnhandledErrorRule) configure(arguments lint.Arguments) error {
|
||||
// Configure validates the rule configuration, and configures the rule accordingly.
|
||||
//
|
||||
// Configuration implements the [lint.ConfigurableRule] interface.
|
||||
func (r *UnhandledErrorRule) Configure(arguments lint.Arguments) error {
|
||||
for _, arg := range arguments {
|
||||
argStr, ok := arg.(string)
|
||||
if !ok {
|
||||
@@ -42,14 +42,7 @@ func (r *UnhandledErrorRule) configure(arguments lint.Arguments) error {
|
||||
}
|
||||
|
||||
// Apply applies the rule to given file.
|
||||
func (r *UnhandledErrorRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var configureErr error
|
||||
r.configureOnce.Do(func() { configureErr = r.configure(arguments) })
|
||||
|
||||
if configureErr != nil {
|
||||
return newInternalFailureError(configureErr)
|
||||
}
|
||||
|
||||
func (r *UnhandledErrorRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||
var failures []lint.Failure
|
||||
|
||||
walker := &lintUnhandledErrors{
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"regexp"
|
||||
"sync"
|
||||
|
||||
"github.com/mgechev/revive/lint"
|
||||
)
|
||||
@@ -16,11 +15,12 @@ type UnusedParamRule struct {
|
||||
// regex to check if some name is valid for unused parameter, "^_$" by default
|
||||
allowRegex *regexp.Regexp
|
||||
failureMsg string
|
||||
|
||||
configureOnce sync.Once
|
||||
}
|
||||
|
||||
func (r *UnusedParamRule) configure(args lint.Arguments) error {
|
||||
// Configure validates the rule configuration, and configures the rule accordingly.
|
||||
//
|
||||
// Configuration implements the [lint.ConfigurableRule] interface.
|
||||
func (r *UnusedParamRule) Configure(args lint.Arguments) error {
|
||||
// while by default args is an array, i think it's good to provide structures inside it by default, not arrays or primitives
|
||||
// it's more compatible to JSON nature of configurations
|
||||
r.allowRegex = allowBlankIdentifierRegex
|
||||
@@ -50,14 +50,7 @@ func (r *UnusedParamRule) configure(args lint.Arguments) error {
|
||||
}
|
||||
|
||||
// Apply applies the rule to given file.
|
||||
func (r *UnusedParamRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var configureErr error
|
||||
r.configureOnce.Do(func() { configureErr = r.configure(arguments) })
|
||||
|
||||
if configureErr != nil {
|
||||
return newInternalFailureError(configureErr)
|
||||
}
|
||||
|
||||
func (r *UnusedParamRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||
var failures []lint.Failure
|
||||
|
||||
onFailure := func(failure lint.Failure) {
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"regexp"
|
||||
"sync"
|
||||
|
||||
"github.com/mgechev/revive/lint"
|
||||
)
|
||||
@@ -14,11 +13,12 @@ type UnusedReceiverRule struct {
|
||||
// regex to check if some name is valid for unused parameter, "^_$" by default
|
||||
allowRegex *regexp.Regexp
|
||||
failureMsg string
|
||||
|
||||
configureOnce sync.Once
|
||||
}
|
||||
|
||||
func (r *UnusedReceiverRule) configure(args lint.Arguments) error {
|
||||
// Configure validates the rule configuration, and configures the rule accordingly.
|
||||
//
|
||||
// Configuration implements the [lint.ConfigurableRule] interface.
|
||||
func (r *UnusedReceiverRule) Configure(args lint.Arguments) error {
|
||||
// while by default args is an array, i think it's good to provide structures inside it by default, not arrays or primitives
|
||||
// it's more compatible to JSON nature of configurations
|
||||
r.allowRegex = allowBlankIdentifierRegex
|
||||
@@ -48,14 +48,7 @@ func (r *UnusedReceiverRule) configure(args lint.Arguments) error {
|
||||
}
|
||||
|
||||
// Apply applies the rule to given file.
|
||||
func (r *UnusedReceiverRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var configureErr error
|
||||
r.configureOnce.Do(func() { configureErr = r.configure(arguments) })
|
||||
|
||||
if configureErr != nil {
|
||||
return newInternalFailureError(configureErr)
|
||||
}
|
||||
|
||||
func (r *UnusedReceiverRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||
var failures []lint.Failure
|
||||
|
||||
for _, decl := range file.AST.Decls {
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"go/token"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/mgechev/revive/lint"
|
||||
)
|
||||
@@ -29,11 +28,12 @@ type VarNamingRule struct {
|
||||
blockList []string
|
||||
allowUpperCaseConst bool // if true - allows to use UPPER_SOME_NAMES for constants
|
||||
skipPackageNameChecks bool
|
||||
|
||||
configureOnce sync.Once
|
||||
}
|
||||
|
||||
func (r *VarNamingRule) configure(arguments lint.Arguments) error {
|
||||
// Configure validates the rule configuration, and configures the rule accordingly.
|
||||
//
|
||||
// Configuration implements the [lint.ConfigurableRule] interface.
|
||||
func (r *VarNamingRule) Configure(arguments lint.Arguments) error {
|
||||
if len(arguments) >= 1 {
|
||||
list, err := getList(arguments[0], "allowlist")
|
||||
if err != nil {
|
||||
@@ -91,14 +91,7 @@ func (*VarNamingRule) applyPackageCheckRules(walker *lintNames) {
|
||||
}
|
||||
|
||||
// Apply applies the rule to given file.
|
||||
func (r *VarNamingRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var configureErr error
|
||||
r.configureOnce.Do(func() { configureErr = r.configure(arguments) })
|
||||
|
||||
if configureErr != nil {
|
||||
return newInternalFailureError(configureErr)
|
||||
}
|
||||
|
||||
func (r *VarNamingRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||
var failures []lint.Failure
|
||||
|
||||
fileAst := file.AST
|
||||
|
||||
@@ -36,6 +36,10 @@ var rules = []lint.Rule{
|
||||
func TestAll(t *testing.T) {
|
||||
baseDir := "../testdata/golint/"
|
||||
|
||||
for _, r := range rules {
|
||||
configureRule(t, r, nil)
|
||||
}
|
||||
|
||||
rx, err := regexp.Compile(*lintMatch)
|
||||
if err != nil {
|
||||
t.Fatalf("Bad -lint.match value %q: %v", *lintMatch, err)
|
||||
|
||||
@@ -16,6 +16,22 @@ import (
|
||||
"github.com/mgechev/revive/lint"
|
||||
)
|
||||
|
||||
// configureRule configures the given rule with the given configuration
|
||||
// if the rule implements the ConfigurableRule interface
|
||||
func configureRule(t *testing.T, rule lint.Rule, arguments lint.Arguments) {
|
||||
t.Helper()
|
||||
|
||||
cr, ok := rule.(lint.ConfigurableRule)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
err := cr.Configure(arguments)
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot configure rule %s: %v", rule.Name(), err)
|
||||
}
|
||||
}
|
||||
|
||||
func testRule(t *testing.T, filename string, rule lint.Rule, config ...*lint.RuleConfig) {
|
||||
t.Helper()
|
||||
|
||||
@@ -30,10 +46,14 @@ func testRule(t *testing.T, filename string, rule lint.Rule, config ...*lint.Rul
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot get file info for %s: %v", rule.Name(), err)
|
||||
}
|
||||
var ruleConfig lint.RuleConfig
|
||||
c := map[string]lint.RuleConfig{}
|
||||
if config != nil {
|
||||
c[rule.Name()] = *config[0]
|
||||
if len(config) > 0 {
|
||||
ruleConfig = *config[0]
|
||||
c[rule.Name()] = ruleConfig
|
||||
}
|
||||
configureRule(t, rule, ruleConfig.Arguments)
|
||||
|
||||
if parseInstructions(t, fullFilePath, src) == nil {
|
||||
assertSuccess(t, baseDir, stat, []lint.Rule{rule}, c)
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user