mirror of
https://github.com/mgechev/revive.git
synced 2025-11-23 22:04:49 +02:00
refactor: enable godoclint linter in golangci-lint (#1576)
This commit is contained in:
@@ -9,6 +9,7 @@ linters:
|
||||
- dupword
|
||||
- gocritic
|
||||
- godot
|
||||
- godoclint
|
||||
- govet
|
||||
- ineffassign
|
||||
- misspell
|
||||
@@ -19,12 +20,32 @@ linters:
|
||||
- staticcheck
|
||||
- unused
|
||||
|
||||
exclusions:
|
||||
warn-unused: true
|
||||
rules:
|
||||
- path: '(.+)_test\.go'
|
||||
linters:
|
||||
- godoclint
|
||||
- linters:
|
||||
- godoclint
|
||||
text: 'symbol should have a godoc \("Visit"\)'
|
||||
|
||||
settings:
|
||||
gocritic:
|
||||
enable-all: true
|
||||
disabled-checks:
|
||||
- hugeParam
|
||||
- rangeValCopy
|
||||
godoclint:
|
||||
default: all
|
||||
options:
|
||||
max-len:
|
||||
length: 120
|
||||
require-doc:
|
||||
ignore-exported: false
|
||||
ignore-unexported: true
|
||||
start-with-name:
|
||||
include-unexported: true
|
||||
govet:
|
||||
enable-all: true
|
||||
disable:
|
||||
|
||||
@@ -41,6 +41,7 @@ func ParseFileFilter(rawFilter string) (*FileFilter, error) {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// String returns the original raw filter definition as it appears in the configuration.
|
||||
func (ff *FileFilter) String() string { return ff.raw }
|
||||
|
||||
// MatchFileName checks if the file name matches the filter.
|
||||
|
||||
@@ -198,6 +198,7 @@ func normalizeSplit(strs []string) []string {
|
||||
// ArrayFlags type for string list.
|
||||
type ArrayFlags []string
|
||||
|
||||
// String returns the space-separated representation of the ArrayFlags.
|
||||
func (i *ArrayFlags) String() string {
|
||||
return strings.Join([]string(*i), " ")
|
||||
}
|
||||
|
||||
@@ -70,7 +70,8 @@ func (*ConfusingNamingRule) Name() string {
|
||||
return "confusing-naming"
|
||||
}
|
||||
|
||||
// checkMethodName checks if a given method/function name is similar (just case differences) to other method/function of the same struct/file.
|
||||
// checkMethodName checks if a given method/function name is similar (just case differences) to other method/function
|
||||
// of the same struct/file.
|
||||
func checkMethodName(holder string, id *ast.Ident, w *lintConfusingNames) {
|
||||
if id.Name == "init" && holder == defaultStructName {
|
||||
// ignore init functions
|
||||
|
||||
@@ -170,15 +170,15 @@ func (w *lintExported) lintFuncDoc(fn *ast.FuncDecl) {
|
||||
case exportedGoDocStatusOK:
|
||||
return // comment is fine
|
||||
case exportedGoDocStatusMissing:
|
||||
w.addFailuref(fn, status.Confidence(), lint.FailureCategoryComments,
|
||||
w.addFailuref(fn, status.confidence(), lint.FailureCategoryComments,
|
||||
"exported %s %s should have comment or be unexported", kind, name,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
firstCommentLine := w.firstCommentLine(fn.Doc)
|
||||
w.addFailuref(fn.Doc, status.Confidence(), lint.FailureCategoryComments,
|
||||
`comment on exported %s %s should be of the form "%s ..."%s`, kind, name, fn.Name.Name, status.CorrectionHint(firstCommentLine),
|
||||
w.addFailuref(fn.Doc, status.confidence(), lint.FailureCategoryComments,
|
||||
`comment on exported %s %s should be of the form "%s ..."%s`, kind, name, fn.Name.Name, status.correctionHint(firstCommentLine),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -264,8 +264,8 @@ func (w *lintExported) lintTypeDoc(t *ast.TypeSpec, doc *ast.CommentGroup, first
|
||||
if status == exportedGoDocStatusOK {
|
||||
return
|
||||
}
|
||||
w.addFailuref(doc, status.Confidence(), lint.FailureCategoryComments,
|
||||
`comment on exported type %v should be of the form "%s ..." (with optional leading article)%s`, t.Name, typeName, status.CorrectionHint(firstCommentLine),
|
||||
w.addFailuref(doc, status.confidence(), lint.FailureCategoryComments,
|
||||
`comment on exported type %v should be of the form "%s ..." (with optional leading article)%s`, t.Name, typeName, status.correctionHint(firstCommentLine),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -347,8 +347,8 @@ func (w *lintExported) lintValueSpecDoc(vs *ast.ValueSpec, gd *ast.GenDecl, genD
|
||||
if status == exportedGoDocStatusOK {
|
||||
return
|
||||
}
|
||||
w.addFailuref(doc, status.Confidence(), lint.FailureCategoryComments,
|
||||
`comment on exported %s %s should be of the form "%s ..."%s`, kind, name, name, status.CorrectionHint(firstCommentLine),
|
||||
w.addFailuref(doc, status.confidence(), lint.FailureCategoryComments,
|
||||
`comment on exported %s %s should be of the form "%s ..."%s`, kind, name, name, status.correctionHint(firstCommentLine),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -362,14 +362,14 @@ const (
|
||||
exportedGoDocStatusUnexpected
|
||||
)
|
||||
|
||||
func (gds exportedGoDocStatus) Confidence() float64 {
|
||||
func (gds exportedGoDocStatus) confidence() float64 {
|
||||
if gds == exportedGoDocStatusUnexpected {
|
||||
return 0.8
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
func (gds exportedGoDocStatus) CorrectionHint(firstCommentLine string) string {
|
||||
func (gds exportedGoDocStatus) correctionHint(firstCommentLine string) string {
|
||||
firstWord := strings.Split(firstCommentLine, " ")[0]
|
||||
switch gds {
|
||||
case exportedGoDocStatusCaseMismatch:
|
||||
@@ -501,15 +501,15 @@ func (w *lintExported) lintInterfaceMethod(typeName string, m *ast.Field) {
|
||||
case exportedGoDocStatusOK:
|
||||
return // comment is fine
|
||||
case exportedGoDocStatusMissing:
|
||||
w.addFailuref(m, status.Confidence(), lint.FailureCategoryComments,
|
||||
w.addFailuref(m, status.confidence(), lint.FailureCategoryComments,
|
||||
"public interface method %s.%s should be commented", typeName, name,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
firstCommentLine := w.firstCommentLine(m.Doc)
|
||||
w.addFailuref(m.Doc, status.Confidence(), lint.FailureCategoryComments,
|
||||
`comment on exported interface method %s.%s should be of the form "%s ..."%s`, typeName, name, name, status.CorrectionHint(firstCommentLine),
|
||||
w.addFailuref(m.Doc, status.confidence(), lint.FailureCategoryComments,
|
||||
`comment on exported interface method %s.%s should be of the form "%s ..."%s`, typeName, name, name, status.correctionHint(firstCommentLine),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ type stringFormatSubruleScope struct {
|
||||
field string // (optional) If the argument to be checked is a struct, which member of the struct is checked against the rule (top level members only)
|
||||
}
|
||||
|
||||
// Regex inserted to match valid function/struct field identifiers.
|
||||
// identRegex matches valid function/struct field identifiers.
|
||||
const identRegex = "[_A-Za-z][_A-Za-z0-9]*"
|
||||
|
||||
var parseStringFormatScope = regexp.MustCompile(
|
||||
@@ -165,17 +165,18 @@ func (r *StringFormatRule) parseArgument(argument any, ruleNum int) (scopes stri
|
||||
return scopes, regex, negated, errorMessage, nil
|
||||
}
|
||||
|
||||
// Report an invalid config, this is specifically the user's fault.
|
||||
// configError reports an invalid config, this is specifically the user's fault.
|
||||
func (*StringFormatRule) configError(msg string, ruleNum, option int) error {
|
||||
return fmt.Errorf("invalid configuration for string-format: %s [argument %d, option %d]", msg, ruleNum, option)
|
||||
}
|
||||
|
||||
// Report a general config parsing failure, this may be the user's fault, but it isn't known for certain.
|
||||
// parseError reports a general config parsing failure, this may be the user's fault, but it isn't known for certain.
|
||||
func (*StringFormatRule) parseError(msg string, ruleNum, option int) error {
|
||||
return fmt.Errorf("failed to parse configuration for string-format: %s [argument %d, option %d]", msg, ruleNum, option)
|
||||
}
|
||||
|
||||
// Report a general scope config parsing failure, this may be the user's fault, but it isn't known for certain.
|
||||
// parseScopeError reports a general scope config parsing failure, this may be the user's fault,
|
||||
// but it isn't known for certain.
|
||||
func (*StringFormatRule) parseScopeError(msg string, ruleNum, option, scopeNum int) error {
|
||||
return fmt.Errorf("failed to parse configuration for string-format: %s [argument %d, option %d, scope index %d]", msg, ruleNum, option, scopeNum)
|
||||
}
|
||||
@@ -204,7 +205,7 @@ func (w *lintStringFormatRule) Visit(node ast.Node) ast.Visitor {
|
||||
return w
|
||||
}
|
||||
|
||||
// Return the name of a call expression in the form of package.Func or Func.
|
||||
// getCallName returns the name of a call expression in the form of package.Func or Func.
|
||||
func (*lintStringFormatRule) getCallName(call *ast.CallExpr) (callName string, ok bool) {
|
||||
if ident, ok := call.Fun.(*ast.Ident); ok {
|
||||
// Local function call
|
||||
@@ -227,7 +228,8 @@ func (*lintStringFormatRule) getCallName(call *ast.CallExpr) (callName string, o
|
||||
return "", false
|
||||
}
|
||||
|
||||
// apply a single format rule to a call expression (should be done after verifying the that the call expression matches the rule's scope).
|
||||
// apply a single format rule to a call expression
|
||||
// (should be done after verifying the that the call expression matches the rule's scope).
|
||||
func (r *stringFormatSubrule) apply(call *ast.CallExpr, scope *stringFormatSubruleScope) {
|
||||
if len(call.Args) <= scope.argument {
|
||||
return
|
||||
|
||||
@@ -1003,7 +1003,7 @@ var validateSingleOptions = map[string]struct{}{
|
||||
"validateFn": {},
|
||||
}
|
||||
|
||||
// These are options that are used in expressions of the form:
|
||||
// validateLHS are options that are used in expressions of the form:
|
||||
//
|
||||
// <option> = <RHS>
|
||||
var validateLHS = map[string]struct{}{
|
||||
|
||||
@@ -136,7 +136,8 @@ func (w *lintUncheckedTypeAssertion) handleAssignment(n *ast.AssignStmt) {
|
||||
}
|
||||
}
|
||||
|
||||
// handles "return foo(.*bar)" - one of them is enough to fail as golang does not forward the type cast tuples in return statements.
|
||||
// handleReturn handles "return foo(.*bar)" - one of them is enough to fail
|
||||
// as Go does not forward the type cast tuples in return statements.
|
||||
func (w *lintUncheckedTypeAssertion) handleReturn(n *ast.ReturnStmt) {
|
||||
for _, r := range n.Results {
|
||||
w.requireNoTypeAssert(r)
|
||||
|
||||
@@ -79,11 +79,14 @@ type lintUnconditionalRecursionRule struct {
|
||||
}
|
||||
|
||||
// Visit will traverse function's body we search for calls to the function itself.
|
||||
// We do not search inside conditional control structures (if, for, switch, ...) because any recursive call inside them is conditioned.
|
||||
// We do search inside conditional control structures are statements that will take the control out of the function (return, exit, panic).
|
||||
// We do not search inside conditional control structures (if, for, switch, ...)
|
||||
// because any recursive call inside them is conditioned.
|
||||
// We do search inside conditional control structures are statements
|
||||
// that will take the control out of the function (return, exit, panic).
|
||||
// If we find conditional control exits, it means the function is NOT unconditionally-recursive.
|
||||
// If we find a recursive call before finding any conditional exit, a failure is generated.
|
||||
// In resume: if we found a recursive call control-dependent from the entry point of the function then we raise a failure.
|
||||
// In resume: if we found a recursive call control-dependent from the entry point of
|
||||
// the function then we raise a failure.
|
||||
func (w *lintUnconditionalRecursionRule) Visit(node ast.Node) ast.Visitor {
|
||||
switch n := node.(type) {
|
||||
case *ast.CallExpr:
|
||||
|
||||
@@ -10,7 +10,8 @@ import (
|
||||
"github.com/mgechev/revive/lint"
|
||||
)
|
||||
|
||||
// UnsecureURLSchemeRule checks if a file contains string literals with unsecure URL schemes (for example: http://... in place of https://...).
|
||||
// UnsecureURLSchemeRule checks if a file contains string literals with unsecure URL schemes.
|
||||
// For example: http://... in place of https://....
|
||||
type UnsecureURLSchemeRule struct{}
|
||||
|
||||
// Apply applied the rule to the given file.
|
||||
|
||||
@@ -150,7 +150,7 @@ func (*lintUseWaitGroupGo) isCallToWgAdd(stmt ast.Stmt) bool {
|
||||
return ok && astutils.IsPkgDotName(call.Fun, "wg", "Add")
|
||||
}
|
||||
|
||||
// function used when calling astutils.SeekNode that search for calls to wg.Done.
|
||||
// wgDonePicker is used when calling astutils.SeekNode that search for calls to wg.Done.
|
||||
func wgDonePicker(n ast.Node) bool {
|
||||
call, ok := n.(*ast.CallExpr)
|
||||
result := ok && astutils.IsPkgDotName(call.Fun, "wg", "Done")
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"github.com/mgechev/revive/lint"
|
||||
)
|
||||
|
||||
// exitChecker is a function type that checks whether a function call is an exit function.
|
||||
// exitFuncChecker is a function type that checks whether a function call is an exit function.
|
||||
type exitFuncChecker func(args []ast.Expr) bool
|
||||
|
||||
var alwaysTrue exitFuncChecker = func([]ast.Expr) bool { return true }
|
||||
|
||||
@@ -372,7 +372,8 @@ func (w *lintNames) Visit(n ast.Node) ast.Visitor {
|
||||
return w
|
||||
}
|
||||
|
||||
// isUpperCaseConst checks if a string is in constant name format like `SOME_CONST`, `SOME_CONST_2`, `X123_3`, `_SOME_PRIVATE_CONST`.
|
||||
// isUpperCaseConst checks if a string is in constant name format like `SOME_CONST`, `SOME_CONST_2`,
|
||||
// `X123_3`, `_SOME_PRIVATE_CONST`.
|
||||
// See #851, #865.
|
||||
func isUpperCaseConst(s string) bool {
|
||||
if s == "" {
|
||||
@@ -418,7 +419,7 @@ func isUpperOrDigit(r rune) bool {
|
||||
return isUpper(r) || isDigit(r)
|
||||
}
|
||||
|
||||
// isUpper checks if rune is a simple digit.
|
||||
// isDigit checks if rune is a simple digit.
|
||||
//
|
||||
// We don't use unicode.IsDigit as it returns true for a large variety of digits that are not 0-9.
|
||||
func isDigit(r rune) bool {
|
||||
|
||||
Reference in New Issue
Block a user