1
0
mirror of https://github.com/mgechev/revive.git synced 2025-10-30 23:37: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:
ccoVeille
2024-12-13 21:38:46 +01:00
committed by GitHub
parent 7cbd3d117a
commit 3d1115dacd
37 changed files with 228 additions and 408 deletions

View File

@@ -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)
}

View File

@@ -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)
}()

View File

@@ -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{

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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)

View File

@@ -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{

View File

@@ -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 {

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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

View File

@@ -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 {

View File

@@ -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

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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{

View File

@@ -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

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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 == "-"

View File

@@ -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{

View File

@@ -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{

View File

@@ -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) {

View File

@@ -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 {

View File

@@ -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

View File

@@ -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)

View File

@@ -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