[run] deadline = "10m" tests = true [linters] disable-all = true enable = [ "asciicheck", "bidichk", "bodyclose", "containedctx", "contextcheck", "deadcode", "depguard", "durationcheck", "errcheck", "errchkjson", "errname", "errorlint", "exportloopref", "forbidigo", #"forcetypeassert", "goconst", "gocyclo", "gocritic", "godot", "gofumpt", "gomodguard", "gosec", "gosimple", "govet", "grouper", "ineffassign", "lll", "makezero", "maintidx", "misspell", "nakedret", "nilerr", "noctx", "nolintlint", "nosprintfhostport", "predeclared", "revive", "rowserrcheck", "sqlclosecheck", "staticcheck", "structcheck", "stylecheck", "tenv", "tparallel", "typecheck", "unconvert", "unparam", "unused", "varcheck", "vetshadow", "wastedassign", ] # Please note that we only use depguard for stdlib as gomodguard only # supports modules currently. See https://github.com/ryancurrah/gomodguard/issues/12 [linters-settings.depguard] list-type = "blacklist" include-go-root = true packages = [ # ioutil is deprecated. The functions have been moved elsewhere: # https://golang.org/doc/go1.16#ioutil "io/ioutil", ] [linters-settings.errcheck] # Don't allow setting of error to the blank identifier. If there is a legtimate # reason, there should be a nolint with an explanation. check-blank = true exclude-functions = [ # If we are rolling back a transaction, we are often already in an error # state. '(*database/sql.Tx).Rollback', # It is reasonable to ignore errors if Cleanup fails in most cases. '(*github.com/google/renameio/v2.PendingFile).Cleanup', # We often don't care if removing a file failed (e.g., it doesn't exist) 'os.Remove', 'os.RemoveAll', ] # Ignoring Close so that we don't have to have a bunch of # `defer func() { _ = r.Close() }()` constructs when we # don't actually care about the error. ignore = "Close,fmt:.*" [linters-settings.errorlint] errorf = true asserts = true comparison = true [linters-settings.exhaustive] default-signifies-exhaustive = true [linters-settings.forbidigo] # Forbid the following identifiers forbid = [ "^minFraud*", "^maxMind*", ] [linters-settings.gocritic] enabled-checks = [ "appendAssign", "appendCombine", "argOrder", "assignOp", "badCall", "badCond", "badLock", "badRegexp", "badSorting", "boolExprSimplify", "builtinShadow", "builtinShadowDecl", "captLocal", "caseOrder", "codegenComment", "commentedOutCode", "commentedOutImport", "commentFormatting", "defaultCaseOrder", # Revive's defer rule already captures this. This caught no extra cases. # "deferInLoop", "deferUnlambda", "deprecatedComment", "docStub", "dupArg", "dupBranchBody", "dupCase", "dupImport", "dupSubExpr", "dynamicFmtString", "elseif", "emptyDecl", "emptyFallthrough", "emptyStringTest", "equalFold", "evalOrder", "exitAfterDefer", "exposedSyncMutex", "externalErrorReassign", # Given that all of our code runs on Linux and the / separate should # work fine, this seems less important. # "filepathJoin", "flagDeref", "flagName", "hexLiteral", "ifElseChain", "importShadow", "indexAlloc", "initClause", "ioutilDeprecated", "mapKey", "methodExprCall", "nestingReduce", "newDeref", "nilValReturn", "octalLiteral", "offBy1", "paramTypeCombine", "preferDecodeRune", "preferFilepathJoin", "preferFprint", "preferStringWriter", "preferWriteByte", "ptrToRefParam", "rangeExprCopy", "rangeValCopy", "redundantSprint", "regexpMust", "regexpPattern", # This might be good, but I don't think we want to encourage # significant changes to regexes as we port stuff from Perl. # "regexpSimplify", "ruleguard", "singleCaseSwitch", "sliceClear", "sloppyLen", # This seems like it might also be good, but a lot of existing code # fails. # "sloppyReassign", "returnAfterHttpError", "sloppyTypeAssert", "sortSlice", "sprintfQuotedString", "sqlQuery", "stringsCompare", "stringXbytes", "switchTrue", "syncMapLoadAndDelete", "timeExprSimplify", "todoCommentWithoutDetail", "tooManyResultsChecker", "truncateCmp", "typeAssertChain", "typeDefFirst", "typeSwitchVar", "typeUnparen", "underef", "unlabelStmt", "unlambda", # I am not sure we would want this linter and a lot of existing # code fails. # "unnamedResult", "unnecessaryBlock", "unnecessaryDefer", "unslice", "valSwap", "weakCond", "wrapperFunc", "yodaStyleExpr", # This requires explanations for "nolint" directives. This would be # nice for gosec ones, but I am not sure we want it generally unless # we can get the false positive rate lower. # "whyNoLint" ] [linters-settings.gofumpt] extra-rules = true lang-version = "1.18" [linters-settings.govet] "enable-all" = true [linters-settings.lll] line-length = 120 tab-width = 4 [linters-settings.nolintlint] allow-leading-space = false allow-unused = false allow-no-explanation = ["lll", "misspell"] require-explanation = true require-specific = true [linters-settings.revive] ignore-generated-header = true severity = "warning" # This might be nice but it is so common that it is hard # to enable. # [[linters-settings.revive.rules]] # name = "add-constant" # [[linters-settings.revive.rules]] # name = "argument-limit" [[linters-settings.revive.rules]] name = "atomic" [[linters-settings.revive.rules]] name = "bare-return" [[linters-settings.revive.rules]] name = "blank-imports" [[linters-settings.revive.rules]] name = "bool-literal-in-expr" [[linters-settings.revive.rules]] name = "call-to-gc" # [[linters-settings.revive.rules]] # name = "cognitive-complexity" # Probably a good rule, but we have a lot of names that # only have case differences. # [[linters-settings.revive.rules]] # name = "confusing-naming" # [[linters-settings.revive.rules]] # name = "confusing-results" [[linters-settings.revive.rules]] name = "constant-logical-expr" [[linters-settings.revive.rules]] name = "context-as-argument" [[linters-settings.revive.rules]] name = "context-keys-type" # [[linters-settings.revive.rules]] # name = "cyclomatic" # [[linters-settings.revive.rules]] # name = "deep-exit" [[linters-settings.revive.rules]] name = "defer" [[linters-settings.revive.rules]] name = "dot-imports" [[linters-settings.revive.rules]] name = "duplicated-imports" [[linters-settings.revive.rules]] name = "early-return" [[linters-settings.revive.rules]] name = "empty-block" [[linters-settings.revive.rules]] name = "empty-lines" [[linters-settings.revive.rules]] name = "errorf" [[linters-settings.revive.rules]] name = "error-naming" [[linters-settings.revive.rules]] name = "error-return" [[linters-settings.revive.rules]] name = "error-strings" [[linters-settings.revive.rules]] name = "exported" # [[linters-settings.revive.rules]] # name = "file-header" # We have a lot of flag parameters. This linter probably makes # a good point, but we would need some cleanup or a lot of nolints. # [[linters-settings.revive.rules]] # name = "flag-parameter" # [[linters-settings.revive.rules]] # name = "function-result-limit" [[linters-settings.revive.rules]] name = "get-return" [[linters-settings.revive.rules]] name = "identical-branches" [[linters-settings.revive.rules]] name = "if-return" [[linters-settings.revive.rules]] name = "imports-blacklist" [[linters-settings.revive.rules]] name = "import-shadowing" [[linters-settings.revive.rules]] name = "increment-decrement" [[linters-settings.revive.rules]] name = "indent-error-flow" # [[linters-settings.revive.rules]] # name = "line-length-limit" # [[linters-settings.revive.rules]] # name = "max-public-structs" [[linters-settings.revive.rules]] name = "modifies-parameter" [[linters-settings.revive.rules]] name = "modifies-value-receiver" # We frequently use nested structs, particularly in tests. # [[linters-settings.revive.rules]] # name = "nested-structs" [[linters-settings.revive.rules]] name = "optimize-operands-order" [[linters-settings.revive.rules]] name = "package-comments" [[linters-settings.revive.rules]] name = "range" [[linters-settings.revive.rules]] name = "range-val-address" [[linters-settings.revive.rules]] name = "range-val-in-closure" [[linters-settings.revive.rules]] name = "receiver-naming" [[linters-settings.revive.rules]] name = "redefines-builtin-id" [[linters-settings.revive.rules]] name = "string-of-int" [[linters-settings.revive.rules]] name = "struct-tag" [[linters-settings.revive.rules]] name = "superfluous-else" [[linters-settings.revive.rules]] name = "time-naming" [[linters-settings.revive.rules]] name = "unconditional-recursion" [[linters-settings.revive.rules]] name = "unexported-naming" [[linters-settings.revive.rules]] name = "unexported-return" # This is covered elsewhere and we want to ignore some # functions such as fmt.Fprintf. # [[linters-settings.revive.rules]] # name = "unhandled-error" [[linters-settings.revive.rules]] name = "unnecessary-stmt" [[linters-settings.revive.rules]] name = "unreachable-code" [[linters-settings.revive.rules]] name = "unused-parameter" # We generally have unused receivers in tests for meeting the # requirements of an interface. # [[linters-settings.revive.rules]] # name = "unused-receiver" # This probably makes sense after we upgrade to 1.18 # [[linters-settings.revive.rules]] # name = "use-any" [[linters-settings.revive.rules]] name = "useless-break" [[linters-settings.revive.rules]] name = "var-declaration" [[linters-settings.revive.rules]] name = "var-naming" [[linters-settings.revive.rules]] name = "waitgroup-by-value" [linters-settings.unparam] check-exported = true [[issues.exclude-rules]] linters = [ "govet" ] # we want to enable almost all govet rules. It is easier to just filter out # the ones we don't want: # # * fieldalignment - way too noisy. Although it is very useful in particular # cases where we are trying to use as little memory as possible, having # it go off on every struct isn't helpful. # * shadow - although often useful, it complains about _many_ err # shadowing assignments and some others where shadowing is clear. text = "^(fieldalignment|shadow)"