From c97c816133b42257d0bcf1ee4bd178bb2a7a2b9e Mon Sep 17 00:00:00 2001 From: Taras Madan Date: Tue, 10 Sep 2024 12:16:33 +0200 Subject: vendor: update --- vendor/github.com/mgechev/revive/config/config.go | 1 + vendor/github.com/mgechev/revive/lint/config.go | 7 ++ vendor/github.com/mgechev/revive/lint/linter.go | 95 ++++++++++++++++++++-- vendor/github.com/mgechev/revive/lint/package.go | 14 +++- .../github.com/mgechev/revive/rule/add-constant.go | 9 +- .../mgechev/revive/rule/comment-spacings.go | 11 +-- .../mgechev/revive/rule/comments-density.go | 95 ++++++++++++++++++++++ .../mgechev/revive/rule/confusing-naming.go | 26 ++++-- vendor/github.com/mgechev/revive/rule/datarace.go | 8 +- .../mgechev/revive/rule/enforce-slice-style.go | 29 ++++++- .../mgechev/revive/rule/optimize-operands-order.go | 13 ++- .../mgechev/revive/rule/package-comments.go | 12 +-- .../mgechev/revive/rule/range-val-address.go | 4 + .../mgechev/revive/rule/range-val-in-closure.go | 4 + vendor/github.com/mgechev/revive/rule/utils.go | 6 ++ 15 files changed, 291 insertions(+), 43 deletions(-) create mode 100644 vendor/github.com/mgechev/revive/rule/comments-density.go (limited to 'vendor/github.com/mgechev') diff --git a/vendor/github.com/mgechev/revive/config/config.go b/vendor/github.com/mgechev/revive/config/config.go index 50a2b8966..fed1d1913 100644 --- a/vendor/github.com/mgechev/revive/config/config.go +++ b/vendor/github.com/mgechev/revive/config/config.go @@ -95,6 +95,7 @@ var allRules = append([]lint.Rule{ &rule.EnforceRepeatedArgTypeStyleRule{}, &rule.EnforceSliceStyleRule{}, &rule.MaxControlNestingRule{}, + &rule.CommentsDensityRule{}, }, defaultRules...) var allFormatters = []lint.Formatter{ diff --git a/vendor/github.com/mgechev/revive/lint/config.go b/vendor/github.com/mgechev/revive/lint/config.go index 7e51a93c2..d7ecd964a 100644 --- a/vendor/github.com/mgechev/revive/lint/config.go +++ b/vendor/github.com/mgechev/revive/lint/config.go @@ -1,5 +1,9 @@ package lint +import ( + goversion "github.com/hashicorp/go-version" +) + // Arguments is type used for the arguments of a rule. type Arguments = []interface{} @@ -61,4 +65,7 @@ type Config struct { WarningCode int `toml:"warningCode"` Directives DirectivesConfig `toml:"directive"` Exclude []string `toml:"exclude"` + // If set, overrides the go language version specified in go.mod of + // packages being linted, and assumes this specific language version. + GoVersion *goversion.Version } diff --git a/vendor/github.com/mgechev/revive/lint/linter.go b/vendor/github.com/mgechev/revive/lint/linter.go index fb1ab6f28..3c97f306f 100644 --- a/vendor/github.com/mgechev/revive/lint/linter.go +++ b/vendor/github.com/mgechev/revive/lint/linter.go @@ -3,12 +3,18 @@ package lint import ( "bufio" "bytes" + "encoding/json" "fmt" "go/token" "os" + "os/exec" + "path/filepath" "regexp" "strconv" + "strings" "sync" + + goversion "github.com/hashicorp/go-version" ) // ReadFile defines an abstraction for reading files. @@ -57,16 +63,52 @@ var ( func (l *Linter) Lint(packages [][]string, ruleSet []Rule, config Config) (<-chan Failure, error) { failures := make(chan Failure) + perModVersions := make(map[string]*goversion.Version) + perPkgVersions := make([]*goversion.Version, len(packages)) + for n, files := range packages { + if len(files) == 0 { + continue + } + if config.GoVersion != nil { + perPkgVersions[n] = config.GoVersion + continue + } + + dir, err := filepath.Abs(filepath.Dir(files[0])) + if err != nil { + return nil, err + } + + alreadyKnownMod := false + for d, v := range perModVersions { + if strings.HasPrefix(dir, d) { + perPkgVersions[n] = v + alreadyKnownMod = true + break + } + } + if alreadyKnownMod { + continue + } + + d, v, err := detectGoMod(dir) + if err != nil { + return nil, err + } + perModVersions[d] = v + perPkgVersions[n] = v + } + var wg sync.WaitGroup - for _, pkg := range packages { + for n := range packages { wg.Add(1) - go func(pkg []string) { - if err := l.lintPackage(pkg, ruleSet, config, failures); err != nil { + go func(pkg []string, gover *goversion.Version) { + if err := l.lintPackage(pkg, gover, ruleSet, config, failures); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } defer wg.Done() - }(pkg) + }(packages[n], perPkgVersions[n]) } go func() { @@ -77,10 +119,15 @@ func (l *Linter) Lint(packages [][]string, ruleSet []Rule, config Config) (<-cha return failures, nil } -func (l *Linter) lintPackage(filenames []string, ruleSet []Rule, config Config, failures chan Failure) error { +func (l *Linter) lintPackage(filenames []string, gover *goversion.Version, ruleSet []Rule, config Config, failures chan Failure) error { + if len(filenames) == 0 { + return nil + } + pkg := &Package{ - fset: token.NewFileSet(), - files: map[string]*File{}, + fset: token.NewFileSet(), + files: map[string]*File{}, + goVersion: gover, } for _, filename := range filenames { content, err := l.readFile(filename) @@ -108,6 +155,40 @@ func (l *Linter) lintPackage(filenames []string, ruleSet []Rule, config Config, return nil } +func detectGoMod(dir string) (rootDir string, ver *goversion.Version, err error) { + // https://github.com/golang/go/issues/44753#issuecomment-790089020 + cmd := exec.Command("go", "list", "-m", "-json") + cmd.Dir = dir + + out, err := cmd.Output() + if err != nil { + return "", nil, fmt.Errorf("command go list: %w", err) + } + + // NOTE: A package may be part of a go workspace. In this case `go list -m` + // lists all modules in the workspace, so we need to go through them all. + d := json.NewDecoder(bytes.NewBuffer(out)) + for d.More() { + var v struct { + GoMod string `json:"GoMod"` + GoVersion string `json:"GoVersion"` + Dir string `json:"Dir"` + } + if err = d.Decode(&v); err != nil { + return "", nil, err + } + if v.GoMod == "" { + return "", nil, fmt.Errorf("not part of a module: %q", dir) + } + if v.Dir != "" && strings.HasPrefix(dir, v.Dir) { + rootDir = v.Dir + ver, err = goversion.NewVersion(strings.TrimPrefix(v.GoVersion, "go")) + return rootDir, ver, err + } + } + return "", nil, fmt.Errorf("not part of a module: %q", dir) +} + // isGenerated reports whether the source file is generated code // according the rules from https://golang.org/s/generatedcode. // This is inherited from the original go lint. diff --git a/vendor/github.com/mgechev/revive/lint/package.go b/vendor/github.com/mgechev/revive/lint/package.go index 5976acf99..b4a0a72c7 100644 --- a/vendor/github.com/mgechev/revive/lint/package.go +++ b/vendor/github.com/mgechev/revive/lint/package.go @@ -7,13 +7,16 @@ import ( "go/types" "sync" + goversion "github.com/hashicorp/go-version" + "github.com/mgechev/revive/internal/typeparams" ) // Package represents a package in the project. type Package struct { - fset *token.FileSet - files map[string]*File + fset *token.FileSet + files map[string]*File + goVersion *goversion.Version typesPkg *types.Package typesInfo *types.Info @@ -29,6 +32,8 @@ var ( trueValue = 1 falseValue = 2 notSet = 3 + + go122 = goversion.Must(goversion.NewVersion("1.22")) ) // Files return package's files. @@ -188,3 +193,8 @@ func (p *Package) lint(rules []Rule, config Config, failures chan Failure) { } wg.Wait() } + +// IsAtLeastGo122 returns true if the Go version for this package is 1.22 or higher, false otherwise +func (p *Package) IsAtLeastGo122() bool { + return p.goVersion.GreaterThanOrEqual(go122) +} diff --git a/vendor/github.com/mgechev/revive/rule/add-constant.go b/vendor/github.com/mgechev/revive/rule/add-constant.go index 86182623a..73dfa932c 100644 --- a/vendor/github.com/mgechev/revive/rule/add-constant.go +++ b/vendor/github.com/mgechev/revive/rule/add-constant.go @@ -53,7 +53,7 @@ func (r *AddConstantRule) Apply(file *lint.File, arguments lint.Arguments) []lin onFailure: onFailure, strLits: make(map[string]int), strLitLimit: r.strLitLimit, - allowList: r.allowList, + allowList: r.allowList, ignoreFunctions: r.ignoreFunctions, structTags: make(map[*ast.BasicLit]struct{}), } @@ -72,7 +72,7 @@ type lintAddConstantRule struct { onFailure func(lint.Failure) strLits map[string]int strLitLimit int - allowList allowList + allowList allowList ignoreFunctions []*regexp.Regexp structTags map[*ast.BasicLit]struct{} } @@ -127,6 +127,11 @@ func (*lintAddConstantRule) getFuncName(expr *ast.CallExpr) string { switch prefix := f.X.(type) { case *ast.Ident: return prefix.Name + "." + f.Sel.Name + case *ast.CallExpr: + // If the selector is an CallExpr, like `fn().Info`, we return `.Info` as function name + if f.Sel != nil { + return "." + f.Sel.Name + } } case *ast.Ident: return f.Name diff --git a/vendor/github.com/mgechev/revive/rule/comment-spacings.go b/vendor/github.com/mgechev/revive/rule/comment-spacings.go index 2b8240ca5..bfb7eaf23 100644 --- a/vendor/github.com/mgechev/revive/rule/comment-spacings.go +++ b/vendor/github.com/mgechev/revive/rule/comment-spacings.go @@ -20,18 +20,13 @@ func (r *CommentSpacingsRule) configure(arguments lint.Arguments) { defer r.Unlock() if r.allowList == nil { - r.allowList = []string{ - "//go:", - "//revive:", - "//nolint:", - } - + r.allowList = []string{} for _, arg := range arguments { allow, ok := arg.(string) // Alt. non panicking version if !ok { panic(fmt.Sprintf("invalid argument %v for %s; expected string but got %T", arg, r.Name(), arg)) } - r.allowList = append(r.allowList, `//`+allow+`:`) + r.allowList = append(r.allowList, `//`+allow) } } } @@ -87,5 +82,5 @@ func (r *CommentSpacingsRule) isAllowed(line string) bool { } } - return false + return isDirectiveComment(line) } diff --git a/vendor/github.com/mgechev/revive/rule/comments-density.go b/vendor/github.com/mgechev/revive/rule/comments-density.go new file mode 100644 index 000000000..5956fea23 --- /dev/null +++ b/vendor/github.com/mgechev/revive/rule/comments-density.go @@ -0,0 +1,95 @@ +package rule + +import ( + "fmt" + "go/ast" + "strings" + "sync" + + "github.com/mgechev/revive/lint" +) + +// CommentsDensityRule lints given else constructs. +type CommentsDensityRule struct { + minimumCommentsDensity int64 + configured bool + sync.Mutex +} + +const defaultMinimumCommentsPercentage = 0 + +func (r *CommentsDensityRule) configure(arguments lint.Arguments) { + r.Lock() + defer r.Unlock() + + if r.configured { + return + } + + r.configured = true + + if len(arguments) < 1 { + r.minimumCommentsDensity = defaultMinimumCommentsPercentage + return + } + + var ok bool + r.minimumCommentsDensity, ok = arguments[0].(int64) + if !ok { + panic(fmt.Sprintf("invalid argument for %q rule: argument should be an int, got %T", r.Name(), arguments[0])) + } +} + +// Apply applies the rule to given file. +func (r *CommentsDensityRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure { + r.configure(arguments) + + commentsLines := countDocLines(file.AST.Comments) + statementsCount := countStatements(file.AST) + density := (float32(commentsLines) / float32(statementsCount+commentsLines)) * 100 + + if density < float32(r.minimumCommentsDensity) { + return []lint.Failure{ + { + Node: file.AST, + Confidence: 1, + Failure: fmt.Sprintf("the file has a comment density of %2.f%% (%d comment lines for %d code lines) but expected a minimum of %d%%", density, commentsLines, statementsCount, r.minimumCommentsDensity), + }, + } + } + + return nil +} + +// Name returns the rule name. +func (*CommentsDensityRule) Name() string { + return "comments-density" +} + +// countStatements counts the number of program statements in the given AST. +func countStatements(node ast.Node) int { + counter := 0 + + ast.Inspect(node, func(n ast.Node) bool { + switch n.(type) { + case *ast.ExprStmt, *ast.AssignStmt, *ast.ReturnStmt, *ast.GoStmt, *ast.DeferStmt, + *ast.BranchStmt, *ast.IfStmt, *ast.SwitchStmt, *ast.TypeSwitchStmt, + *ast.SelectStmt, *ast.ForStmt, *ast.RangeStmt, *ast.CaseClause, *ast.CommClause, + *ast.DeclStmt, *ast.FuncDecl: + counter++ + } + return true + }) + + return counter +} + +func countDocLines(comments []*ast.CommentGroup) int { + acc := 0 + for _, c := range comments { + lines := strings.Split(c.Text(), "\n") + acc += len(lines) - 1 + } + + return acc +} diff --git a/vendor/github.com/mgechev/revive/rule/confusing-naming.go b/vendor/github.com/mgechev/revive/rule/confusing-naming.go index febfd8824..32f6dd803 100644 --- a/vendor/github.com/mgechev/revive/rule/confusing-naming.go +++ b/vendor/github.com/mgechev/revive/rule/confusing-naming.go @@ -138,16 +138,32 @@ func getStructName(r *ast.FieldList) string { switch v := t.(type) { case *ast.StarExpr: - t = v.X + return extractFromStarExpr(v) case *ast.IndexExpr: - t = v.X + return extractFromIndexExpr(v) + case *ast.Ident: + return v.Name } - if p, _ := t.(*ast.Ident); p != nil { - result = p.Name + return defaultStructName +} + +func extractFromStarExpr(expr *ast.StarExpr) string { + switch v := expr.X.(type) { + case *ast.IndexExpr: + return extractFromIndexExpr(v) + case *ast.Ident: + return v.Name } + return defaultStructName +} - return result +func extractFromIndexExpr(expr *ast.IndexExpr) string { + switch v := expr.X.(type) { + case *ast.Ident: + return v.Name + } + return defaultStructName } func checkStructFields(fields *ast.FieldList, structName string, w *lintConfusingNames) { diff --git a/vendor/github.com/mgechev/revive/rule/datarace.go b/vendor/github.com/mgechev/revive/rule/datarace.go index 39e96696a..86ec6e113 100644 --- a/vendor/github.com/mgechev/revive/rule/datarace.go +++ b/vendor/github.com/mgechev/revive/rule/datarace.go @@ -16,7 +16,7 @@ func (*DataRaceRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { onFailure := func(failure lint.Failure) { failures = append(failures, failure) } - w := lintDataRaces{onFailure: onFailure} + w := lintDataRaces{onFailure: onFailure, go122for: file.Pkg.IsAtLeastGo122()} ast.Walk(w, file.AST) @@ -30,6 +30,7 @@ func (*DataRaceRule) Name() string { type lintDataRaces struct { onFailure func(failure lint.Failure) + go122for bool } func (w lintDataRaces) Visit(n ast.Node) ast.Visitor { @@ -47,7 +48,7 @@ func (w lintDataRaces) Visit(n ast.Node) ast.Visitor { if results != nil { returnIDs = w.ExtractReturnIDs(results.List) } - fl := &lintFunctionForDataRaces{onFailure: w.onFailure, returnIDs: returnIDs, rangeIDs: map[*ast.Object]struct{}{}} + fl := &lintFunctionForDataRaces{onFailure: w.onFailure, returnIDs: returnIDs, rangeIDs: map[*ast.Object]struct{}{}, go122for: w.go122for} ast.Walk(fl, node.Body) return nil @@ -69,6 +70,7 @@ type lintFunctionForDataRaces struct { onFailure func(failure lint.Failure) returnIDs map[*ast.Object]struct{} rangeIDs map[*ast.Object]struct{} + go122for bool } func (w lintFunctionForDataRaces) Visit(node ast.Node) ast.Visitor { @@ -118,7 +120,7 @@ func (w lintFunctionForDataRaces) Visit(node ast.Node) ast.Visitor { _, isReturnID := w.returnIDs[id.Obj] switch { - case isRangeID: + case isRangeID && !w.go122for: w.onFailure(lint.Failure{ Confidence: 1, Node: id, diff --git a/vendor/github.com/mgechev/revive/rule/enforce-slice-style.go b/vendor/github.com/mgechev/revive/rule/enforce-slice-style.go index abaf20be0..60d8ac066 100644 --- a/vendor/github.com/mgechev/revive/rule/enforce-slice-style.go +++ b/vendor/github.com/mgechev/revive/rule/enforce-slice-style.go @@ -14,6 +14,7 @@ const ( enforceSliceStyleTypeAny enforceSliceStyleType = "any" enforceSliceStyleTypeMake enforceSliceStyleType = "make" enforceSliceStyleTypeLiteral enforceSliceStyleType = "literal" + enforceSliceStyleTypeNil enforceSliceStyleType = "nil" ) func sliceStyleFromString(s string) (enforceSliceStyleType, error) { @@ -24,6 +25,8 @@ func sliceStyleFromString(s string) (enforceSliceStyleType, error) { return enforceSliceStyleTypeMake, nil case string(enforceSliceStyleTypeLiteral): return enforceSliceStyleTypeLiteral, nil + case string(enforceSliceStyleTypeNil): + return enforceSliceStyleTypeNil, nil default: return enforceSliceStyleTypeAny, fmt.Errorf( "invalid slice style: %s (expecting one of %v)", @@ -32,6 +35,7 @@ func sliceStyleFromString(s string) (enforceSliceStyleType, error) { enforceSliceStyleTypeAny, enforceSliceStyleTypeMake, enforceSliceStyleTypeLiteral, + enforceSliceStyleTypeNil, }, ) } @@ -86,7 +90,10 @@ func (r *EnforceSliceStyleRule) Apply(file *lint.File, arguments lint.Arguments) ast.Inspect(astFile, func(n ast.Node) bool { switch v := n.(type) { case *ast.CompositeLit: - if r.enforceSliceStyle != enforceSliceStyleTypeMake { + switch r.enforceSliceStyle { + case enforceSliceStyleTypeMake, enforceSliceStyleTypeNil: + // continue + default: return true } @@ -99,14 +106,22 @@ func (r *EnforceSliceStyleRule) Apply(file *lint.File, arguments lint.Arguments) return true } + var failureMessage string + if r.enforceSliceStyle == enforceSliceStyleTypeNil { + failureMessage = "use nil slice declaration (e.g. var args []type) instead of []type{}" + } else { + failureMessage = "use make([]type) instead of []type{} (or declare nil slice)" + } failures = append(failures, lint.Failure{ Confidence: 1, Node: v, Category: "style", - Failure: "use make([]type) instead of []type{} (or declare nil slice)", + Failure: failureMessage, }) case *ast.CallExpr: - if r.enforceSliceStyle != enforceSliceStyleTypeLiteral { + switch r.enforceSliceStyle { + case enforceSliceStyleTypeLiteral, enforceSliceStyleTypeNil: + default: // skip any function calls, even if it's make([]type) // we don't want to report it if literals are not enforced return true @@ -151,11 +166,17 @@ func (r *EnforceSliceStyleRule) Apply(file *lint.File, arguments lint.Arguments) } } + var failureMessage string + if r.enforceSliceStyle == enforceSliceStyleTypeNil { + failureMessage = "use nil slice declaration (e.g. var args []type) instead of make([]type, 0)" + } else { + failureMessage = "use []type{} instead of make([]type, 0) (or declare nil slice)" + } failures = append(failures, lint.Failure{ Confidence: 1, Node: v.Args[0], Category: "style", - Failure: "use []type{} instead of make([]type, 0) (or declare nil slice)", + Failure: failureMessage, }) } return true diff --git a/vendor/github.com/mgechev/revive/rule/optimize-operands-order.go b/vendor/github.com/mgechev/revive/rule/optimize-operands-order.go index 841bde56c..43d982d6b 100644 --- a/vendor/github.com/mgechev/revive/rule/optimize-operands-order.go +++ b/vendor/github.com/mgechev/revive/rule/optimize-operands-order.go @@ -49,8 +49,17 @@ func (w lintOptimizeOperandsOrderlExpr) Visit(node ast.Node) ast.Visitor { } isCaller := func(n ast.Node) bool { - _, ok := n.(*ast.CallExpr) - return ok + ce, ok := n.(*ast.CallExpr) + if !ok { + return false + } + + ident, isIdent := ce.Fun.(*ast.Ident) + if !isIdent { + return true + } + + return ident.Name != "len" || ident.Obj != nil } // check if the left sub-expression contains a function call diff --git a/vendor/github.com/mgechev/revive/rule/package-comments.go b/vendor/github.com/mgechev/revive/rule/package-comments.go index 02f246be0..f1e5462fe 100644 --- a/vendor/github.com/mgechev/revive/rule/package-comments.go +++ b/vendor/github.com/mgechev/revive/rule/package-comments.go @@ -150,17 +150,9 @@ func (l *lintPackageComments) Visit(_ ast.Node) ast.Visitor { return nil } s := l.fileAst.Doc.Text() - if ts := strings.TrimLeft(s, " \t"); ts != s { - l.onFailure(lint.Failure{ - Category: "comments", - Node: l.fileAst.Doc, - Confidence: 1, - Failure: "package comment should not have leading space", - }) - s = ts - } + // Only non-main packages need to keep to this form. - if !l.file.Pkg.IsMain() && !strings.HasPrefix(s, prefix) { + if !l.file.Pkg.IsMain() && !strings.HasPrefix(s, prefix) && !isDirectiveComment(s) { l.onFailure(lint.Failure{ Category: "comments", Node: l.fileAst.Doc, diff --git a/vendor/github.com/mgechev/revive/rule/range-val-address.go b/vendor/github.com/mgechev/revive/rule/range-val-address.go index 51ad8e108..d2ab0392a 100644 --- a/vendor/github.com/mgechev/revive/rule/range-val-address.go +++ b/vendor/github.com/mgechev/revive/rule/range-val-address.go @@ -16,6 +16,10 @@ type RangeValAddress struct{} func (*RangeValAddress) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { var failures []lint.Failure + if file.Pkg.IsAtLeastGo122() { + return failures + } + walker := rangeValAddress{ file: file, onFailure: func(failure lint.Failure) { diff --git a/vendor/github.com/mgechev/revive/rule/range-val-in-closure.go b/vendor/github.com/mgechev/revive/rule/range-val-in-closure.go index 1e85d0d0d..6f9255a74 100644 --- a/vendor/github.com/mgechev/revive/rule/range-val-in-closure.go +++ b/vendor/github.com/mgechev/revive/rule/range-val-in-closure.go @@ -14,6 +14,10 @@ type RangeValInClosureRule struct{} func (*RangeValInClosureRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { var failures []lint.Failure + if file.Pkg.IsAtLeastGo122() { + return failures + } + walker := rangeValInClosure{ onFailure: func(failure lint.Failure) { failures = append(failures, failure) diff --git a/vendor/github.com/mgechev/revive/rule/utils.go b/vendor/github.com/mgechev/revive/rule/utils.go index 5778e7696..1267c2d39 100644 --- a/vendor/github.com/mgechev/revive/rule/utils.go +++ b/vendor/github.com/mgechev/revive/rule/utils.go @@ -165,3 +165,9 @@ func checkNumberOfArguments(expected int, args lint.Arguments, ruleName string) panic(fmt.Sprintf("not enough arguments for %s rule, expected %d, got %d. Please check the rule's documentation", ruleName, expected, len(args))) } } + +var directiveCommentRE = regexp.MustCompile("^//(line |extern |export |[a-z0-9]+:[a-z0-9])") // see https://go-review.googlesource.com/c/website/+/442516/1..2/_content/doc/comment.md#494 + +func isDirectiveComment(line string) bool { + return directiveCommentRE.MatchString(line) +} -- cgit mrf-deployment