revive

revive-lintMIT活跃维护

一个用 Go 写的快速、严格且可配置的代码检查工具,用来替代 golint,帮你在 CI 里揪出 Go 代码的风格和潜在问题。

🔥 Fast, strict, configurable, extensible, and beautiful linter for Go

v1.17.1发布于 2026-10-07 12:09 UTC5,565star +1 / 7 天339fork同步于 2026-11-10 17:36 UTC

怎么上手

由 README 提炼,执行前请确认
brew install revive
go install github.com/mgechev/revive@latest
硬件要求按 README 说明

README 未说明,纯 Go 命令行工具,无 GPU 或显存要求

有 Docker 镜像
下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

Go 代码 linter,golint 的即插即用替代品,用 TOML 配置规则并支持自定义扩展

一个用 Go 写的快速、严格且可配置的代码检查工具,用来替代 golint,帮你在 CI 里揪出 Go 代码的风格和潜在问题。

核心能力

  • 用 TOML 配置文件启用或禁用规则并传参
  • 支持按文件或行范围用注释指令关闭检查
  • 提供 friendly、stylish、JSON、SARIF 等多种输出格式
  • 可自定义规则和格式化器,也可作为库集成
  • 关闭类型检查后运行速度比 golint 快 6 倍以上

容易踩的坑

不传 -config 时依次查找 $HOME/revive.toml 和内置默认规则,容易误以为配置已生效;一旦提供配置文件,只有其中列出的规则才会启用,golint 默认规则不再自动生效;Docker 镜像 v1.16.0 之后从 ghcr.io/mgechev/revive 迁到 ghcr.io/revive-lint/revive,旧地址拉不到新版本

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

5 个版本v1.17.1
  1. v1.17.1最新正式版2026-10-07 · 2026-10-07 12:09 UTC

    What's Changed

    A patch release with fixes for rules that reused configuration across runs and for false positives/negatives.

    [!IMPORTANT] add-constant now inspects nested call arguments and function literal signatures (#1843), so existing projects may see new findings after upgrading.

    Bug Fixes

    Documentation

    Dependency Updates

    New Contributors

    Full Changelog: https://github.com/revive-lint/revive/compare/v1.17.0...v1.17.1

  2. v1.17.02026-09-23 · 2026-09-23 15:38 UTC
    查看更新说明

    What's Changed

    The documentation website revive.run has been rebuilt with Hugo, replacing the Gatsby site that had served the docs since 2018 (#74). See mgechev/revive.run#89 by @alexandear, closes #1647.

    Features

    [!IMPORTANT] unexported-return and redefines-builtin-id now report code that previous versions accepted, so existing projects may see new findings after upgrading.

    Bug Fixes

    Documentation

    Dependency Updates

    Chores & Internal

    New Contributors

    Full Changelog: https://github.com/mgechev/revive/compare/v1.16.0...v1.17.0

  3. v1.16.02026-08-21 · 2026-08-21 16:47 UTC
    查看更新说明

    What's Changed

    Features

    Bug Fixes

    Documentation

    Dependency Updates

  4. v1.15.02026-03-06 · 2026-03-06 10:03 UTC
    查看更新说明

    What's Changed

    BREAKING CHANGE: package-related checks moved from var-naming to a new rule package-naming. var-naming options skipPackageNameChecks, extraBadPackageNames, and skipPackageNameCollisionWithGoStd are deprecated and treated as no-ops.

    Features

    Bug fixes

    Docs

    Updates

    Other

    Full Changelog: https://github.com/mgechev/revive/compare/v1.14.0...v1.15.0

  5. v1.14.02026-02-10 · 2026-02-10 22:24 UTC
    查看更新说明

    What's Changed

    Features

    Bug fixes

    Updates

    Docs

    Other

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译

    revive

    Build Status Go Reference Ask DeepWiki OpenSSF Best Practices OpenSSF Scorecard

    Fast, configurable, extensible, flexible, and beautiful linter for Go. Drop-in replacement of golint. Revive provides a framework for development of custom rules, and lets you define a strict preset for enhancing your development & code review processes.

    Here's how revive is different from golint:

    • Allows to enable or disable rules using a configuration file.
    • Allows to configure the linting rules with a TOML file.
    • 2x faster running the same rules as golint.
    • Provides functionality for disabling a specific rule or the entire linter for a file or a range of lines.
      • golint allows this only for generated files.
    • Optional type checking. Most rules in golint do not require type checking. If you disable them in the config file, revive will run over 6x faster than golint.
    • Provides multiple formatters which let us customize the output.
    • Allows to customize the return code for the entire linter or based on the failure of only some rules.
    • Everyone can extend it easily with custom rules or formatters.
    • Revive provides more rules compared to golint.

    Installation

    revive is available inside the majority of package managers.

    Homebrew

    Install revive using brew:

    brew install revive
    

    To upgrade to the latest version:

    brew upgrade revive
    

    Install from Sources

    Install the latest stable release directly from source:

    go install github.com/mgechev/revive@latest
    

    To install the latest commit from the main branch:

    go install github.com/mgechev/revive@HEAD
    

    Docker

    You can run revive using Docker to avoid installing it directly on your system:

    docker run --rm -v "$(pwd)":/app -w /app ghcr.io/revive-lint/revive:latest -config /app/revive.toml -formatter stylish ./...
    

    Note: images up to and including v1.16.0 are published at ghcr.io/mgechev/revive. Later releases are published at ghcr.io/revive-lint/revive.

    Manual Binary Download

    Download the precompiled binary from the Releases page:

    1. Select the appropriate binary for your OS and architecture.
    2. Extract the binary and move it to a directory in your PATH (e.g., /usr/local/bin).
    3. Verify installation:
    revive -version
    

    Usage

    Since the default behavior of revive is compatible with golint, without providing any additional flags, the only difference you'd notice is faster execution.

    revive supports a -config flag whose value should correspond to a TOML file describing which rules to use for revive's linting. If not provided, revive will try to use a global config file (assumed to be located at $HOME/revive.toml). Otherwise, if no configuration TOML file is found then revive uses a built-in set of default linting rules.

    Text Editors

    • Support for VSCode via vscode-go by changing the go.lintTool setting to revive:
    {
      "go.lintTool": "revive",
    }
    

    GitHub Actions

    Continuous Integration

    Codeac.io - Automated code review service integrates with GitHub, Bitbucket and GitLab (even self-hosted) and helps you fight technical debt. Check your pull-requests with revive automatically. (Free for open-source projects)

    Linter aggregators

    golangci-lint

    To enable revive in golangci-lint you need to add revive to the list of enabled linters:

    # golangci-lint configuration file
    version: "2"
    linters:
       enable:
         - revive
    

    Then revive can be configured by adding an entry to the linters.settings section of the configuration, for example:

    # golangci-lint configuration file
    linters:
      settings:
        revive:
          severity: warning
          rules:
            - name: atomic
            - name: line-length-limit
              severity: error
              arguments: [80]
            - name: unhandled-error
              arguments: ["fmt.Printf", "myFunction"]
    

    The above configuration enables three rules of revive: atomic, line-length-limit and unhandled-error and passes some arguments to the last two. The Configuration section of this document provides details on how to configure revive. Note that while revive configuration is in TOML, that of golangci-lint is in YAML or JSON. See the golangci-lint website for more information about configuring revive.

    Please notice that if no particular configuration is provided, revive will behave as golint does, i.e. all golint rules are enabled (the Available Rules table details what are the golint rules). When a configuration is provided, only rules in the configuration are enabled.

    MegaLinter

    MegaLinter, an open-source linters aggregator for CI, runs revive on Go projects out of the box. See its revive documentation page for configuration details.

    Command Line Flags

    revive accepts the following command line parameters:

    • -config [PATH] - path to the config file in TOML format, defaults to $HOME/revive.toml if present.

    • -exclude [PATTERN] - pattern for files/directories/packages to be excluded for linting. You can specify the files you want to exclude for linting either as package name (i.e. github.com/mgechev/revive), list them as individual files (i.e. file.go), directories (i.e. ./foo/...), or any combination of the three. If no exclusion patterns are specified, vendor/... will be excluded by default.

    • -formatter [NAME] - formatter to be used for the output. The currently available formatters are:

      • default - will output the failures the same way that golint does.
      • json - outputs the failures in JSON format.
      • ndjson - outputs the failures as a stream in newline delimited JSON (NDJSON) format.
      • friendly - outputs the failures when found. Shows the summary of all the failures.
      • stylish - formats the failures in a table. Keep in mind that it doesn't stream the output so it might be perceived as slower compared to others.
      • checkstyle - outputs the failures in XML format compatible with that of Java's Checkstyle.
    • -max_open_files - maximum number of open files at the same time. Defaults to unlimited.

    • -set_exit_status - set exit status to 1 if any issues are found, overwrites error-code and warning-code in config.

    • -version - get revive version.

    Sample Invocations

    revive -config revive.toml -exclude file1.go -exclude file2.go -formatter friendly github.com/mgechev/revive package/...
    
    • The command above will use the configuration from revive.toml
    • revive will ignore file1.go and file2.go
    • The output will be formatted with the friendly formatter
    • The linter will analyze github.com/mgechev/revive and the files in package

    Comment Directives

    Using comments, you can disable the linter for the entire file or only a range of lines:

    //revive:disable
    
    func Public() {}
    
    //revive:enable
    

    The snippet above, will disable revive between the revive:disable and revive:enable comments. If you skip revive:enable, the linter will be disabled for the rest of the file.

    With revive:disable-next-line and revive:disable-line you can disable revive on a particular code line.

    You can do the same on a rule level. In case you want to disable only a particular rule, you can use:

    //revive:disable:unexported-return
    func Public() private {
    	return private
    }
    
    //revive:enable:unexported-return
    

    This way, revive will not warn you that you're returning an object of an unexported type, from an exported function.

    You can document why you disable the linter by adding a trailing text in the directive, for example

    //revive:disable Until the code is stable
    
    //revive:disable:cyclomatic High complexity score but easy to understand
    

    You can also configure revive to enforce documenting linter disabling directives by adding

    [directive.specify-disable-reason]
    

    in the configuration. You can set the severity (defaults to warning) of the violation of this directive

    [directive.specify-disable-reason]
    severity = "error"
    

    Similarly, you can enforce specifying rule names in disable directives by adding

    [directive.specify-disable-rule]
    

    This forbids "naked" //revive:disable, //revive:disable-line, and //revive:disable-next-line directives and requires specifying at least one rule name, e.g. //revive:disable:cyclomatic or //revive:disable-next-line:cyclomatic. You can set the severity (defaults to warning) of the violation of this directive

    [directive.specify-disable-rule]
    severity = "error"
    

    Configuration

    revive can be configured with a TOML file. Here's a sample configuration with an explanation of the individual properties:

    # When set to false, ignores files with "GENERATED" header, similar to golint
    ignore-generated-header = true
    
    # Sets the default severity to "warning"
    severity = "warning"
    
    # Sets the default failure confidence. This means that linting errors
    # with less than 0.8 confidence will be ignored.
    confidence = 0.8
    
    # Sets the error code for failures with the "error" severity
    error-code = 0
    
    # Sets the error code for failures with severity "warning"
    warning-code = 0
    
    # Configuration of the `cyclomatic` rule. Here we specify that
    # the rule should fail if it detects code with higher complexity than 10.
    [rule.cyclomatic]
    arguments = [10]
    
    # Sets the severity of the `package-comments` rule to "error".
    [rule.package-comments]
    severity = "error"
    

    By default revive will enable only the linting rules that are named in the configuration file. For example, the previous configuration file makes revive to enable only cyclomatic and package-comments linting rules.

    To enable default rules you need to use:

    enable-default-rules = true
    

    This will enable all rules available in golint and use their default configuration (i.e. the way they are hardcoded in golint). The default configuration of revive can be found at defaults.toml.

    To enable all available rules you need to add:

    enable-all-rules = true
    

    This will enable all available rules no matter what rules are named in the configuration file.

    Options enable-all-rules and enable-default-rules cannot be combined.

    To disable a rule, you simply mark it as disabled in the configuration. For example:

    [rule.line-length-limit]
    disabled = true
    

    When enabling all rules you still need/can provide specific configurations for rules. The following file is an example configuration where all rules are enabled, except for those that are explicitly disabled, and some rules are configured with particular arguments:

    severity = "warning"
    confidence = 0.8
    error-code = 0
    warning-code = 0
    
    # Enable all available rules
    enable-all-rules = true
    
    # Disabled rules
    [rule.blank-imports]
    disabled = true
    [rule.file-header]
    disabled = true
    [rule.max-public-structs]
    disabled = true
    [rule.line-length-limit]
    disabled = true
    [rule.function-length]
    disabled = true
    [rule.banned-characters]
    disabled = true
    
    # Rule tuning
    [rule.argument-limit]
    arguments = [5]
    [rule.cyclomatic]
    arguments = [10]
    [rule.cognitive-complexity]
    arguments = [7]
    [rule.function-result-limit]
    arguments = [3]
    [rule.error-strings]
    arguments = ["mypackage.Error"]
    

    Custom Configuration

    revive -config config.toml -formatter friendly github.com/mgechev/revive
    

    This will use config.toml, the friendly formatter, and will run linting over the github.com/mgechev/revive package.

    Recommended Configuration

    The following snippet contains the recommended revive configuration that you can use in your project:

    ignore-generated-header = false
    severity = "warning"
    confidence = 0.8
    error-code = 0
    warning-code = 0
    
    [rule.blank-imports]
    [rule.context-as-argument]
    [rule.context-keys-type]
    [rule.dot-imports]
    [rule.error-return]
    [rule.error-strings]
    [rule.error-naming]
    [rule.exported]
    [rule.increment-decrement]
    [rule.var-naming]
    [rule.var-declaration]
    [rule.package-comments]
    [rule.range]
    [rule.receiver-naming]
    [rule.time-naming]
    [rule.unexported-return]
    [rule.indent-error-flow]
    [rule.errorf]
    [rule.empty-block]
    [rule.superfluous-else]
    [rule.unused-parameter]
    [rule.unreachable-code]
    [rule.redefines-builtin-id]
    

    Rule-level file excludes

    You also can setup custom excludes for each rule.

    It's an alternative for the global -exclude program arg.

    ignore-generated-header = false
    severity = "warning"
    confidence = 0.8
    error-code = 0
    warning-code = 0
    
    [rule.blank-imports]
    exclude = ["**/*.pb.go"]
    [rule.context-as-argument]
    exclude = ["src/somepkg/*.go", "TEST"]
    

    You can use the following exclude patterns

    1. full paths to files src/pkg/mypkg/some.go
    2. globs src/**/*.pb.go
    3. regexes (should have prefix ~) ~\.(pb|auto|generated)\.go$
    4. well-known TEST (same as **/*_test.go)
    5. special cases: a. * and ~ patterns exclude all files (same effect as disabling the rule) b. "" (empty) pattern excludes nothing

    NOTE: do not mess with exclude that can be used at the top level of TOML file, that means "exclude package patterns", not "exclude file patterns"

    Available Rules

    List of all available rules.

    NameConfigDescriptionGo versionRevive versiongolintTyped
    add-constantmapSuggests using constant for magic numbers and string literals1.0v1.0.0nono
    argument-limitint (defaults to 8)Specifies the maximum number of arguments a function can receive1.0v1.0.0nono
    atomicn/aCheck for common mistaken usages of the sync/atomic package1.0v1.0.0nono
    banned-characters[]string (defaults to []string{})Checks banned characters in identifiers1.0v1.1.3nono
    bare-returnn/aWarns on bare returns1.0v1.0.0nono
    blank-importsn/aDisallows blank imports1.0v1.0.0yesno
    bool-literal-in-exprn/aSuggests removing Boolean literals from logic expressions1.0v1.0.0nono
    call-to-gcn/aWarns on explicit call to the garbage collector1.0v1.0.0nono
    cognitive-complexityint (defaults to 7)Sets restriction for maximum Cognitive complexity.1.0v1.0.0nono
    comment-spacings[]stringWarns on malformed comments1.0v1.2.5nono
    comments-densityint (defaults to 0)Enforces a minimum comment / code relation1.0v1.3.8nono
    confusing-namingn/aWarns on methods with names that differ only by capitalization1.0v1.0.0nono
    confusing-resultsn/aSuggests to name potentially confusing function results1.0v1.0.0nono
    constant-logical-exprn/aWarns on constant logical expressions1.0v1.0.0nono
    context-as-argumentn/acontext.Context should be the first argument of a function.1.0v1.0.0yesno
    context-keys-typen/aDisallows the usage of basic types in context.WithValue.1.0v1.0.0yesyes
    cyclomaticint (defaults to 10)Sets restriction for maximum Cyclomatic complexity.1.0v1.0.0nono
    dataracen/aSpots potential dataraces1.0v1.2.2nono
    deep-exitn/aLooks for program exits in funcs other than main() or init()1.0v1.0.0nono
    defermapWarns on some defer gotchas1.0v1.0.3nono
    dot-importsn/aForbids . imports.1.0v1.0.0yesno
    duplicated-importsn/aLooks for packages that are imported two or more times1.0v1.0.0nono
    early-return[]stringSpots if-then-else statements where the predicate may be inverted to reduce nesting1.0v1.0.3nono
    empty-blockn/aWarns on empty code blocks1.0v1.0.0nono
    empty-linesn/aWarns when there are heading or trailing newlines in a block1.0v1.0.0nono
    epoch-namingn/aEnforces naming conventions for epoch time variables1.0v1.14.0noyes
    enforce-map-stylestring (defaults to "any")Enforces consistent usage of make(map[type]type) or map[type]type{} for map initialization. Does not affect make(map[type]type, size) constructions.1.0v1.3.4nono
    enforce-repeated-arg-type-stylestring (defaults to "any")Enforces consistent style for repeated argument and/or return value types.1.0v1.3.5nono
    enforce-slice-stylestring (defaults to "any")Enforces consistent usage of make([]type, 0) or []type{} for slice initialization. Does not affect make(map[type]type, non_zero_len, or_non_zero_cap) constructions.1.0v1.3.5nono
    enforce-switch-style[]string (defaults to enforce occurrence and position)Enforces consistent usage of default on switch statements.1.0v1.11.0nono
    error-namingn/aNaming of error variables.1.0v1.0.0yesno
    error-returnn/aThe error return parameter should be last.1.0v1.0.0yesno
    error-strings[]stringConventions around error strings.1.0v1.0.0yesno
    errorfn/aShould replace errors.New(fmt.Sprintf()) with fmt.Errorf()1.0v1.0.0yesyes
    exported[]stringNaming and commenting conventions on exported symbols.1.0v1.0.0yesno
    file-headerstring (defaults to none)Header which each file should have.1.0v1.0.0nono
    file-length-limitmap (optional)Enforces a maximum number of lines per file1.0v1.5.0nono
    filename-formatregular expression (optional)Enforces the formatting of filenames1.0v1.5.0nono
    flag-parametern/aWarns on boolean parameters that create a control coupling1.0v1.0.0nono
    forbidden-call-in-wg-gon/aWarns on forbidden calls inside calls to wg.Go>= 1.25v1.13.0nono
    function-lengthint, int (defaults to 50 statements, 75 lines)Warns on functions exceeding the statements or lines max1.0v1.0.5nono
    function-result-limitint (defaults to 3)Specifies the maximum number of results a function can return1.0v1.0.0nono
    get-returnn/aWarns on getters that do not yield any result1.0v1.0.0nono
    identical-branchesn/aSpots if-then-else statements with identical then and else branches1.0v1.0.3nono
    identical-ifelseif-branchesn/aSpots if ... else if chains with identical branches.1.0v1.12.0nono
    identical-ifelseif-conditionsn/aSpots identical conditions in if ... else if chains.1.0v1.12.0nono
    identical-switch-branchesmapSpots switch with identical branches.1.0v1.12.0nono
    identical-switch-conditionsn/aSpots identical conditions in case clauses of switch statements.1.0v1.12.0nono
    if-returnn/aRedundant if when returning an error.1.0v1.0.0nono
    import-alias-namingstring or map[string]string (defaults to allow regex pattern ^[a-z][a-z0-9]{0,}$)Conventions around the naming of import aliases.1.0v1.3.4nono
    import-shadowingn/aSpots identifiers that shadow an import1.0v1.0.0nono
    imports-blocklist[]stringDisallows importing the specified packages1.0v1.0.0nono
    increment-decrementn/aUse i++ and i-- instead of i += 1 and i -= 1.1.0v1.0.0yesno
    indent-error-flow[]stringPrevents redundant else statements.1.0v1.0.0yesno
    inefficient-map-lookupn/aSpots iterative searches for a key in a map1.0v1.13.0noyes
    line-length-limitint or mapSpecifies the maximum number of characters in a line, with optional per-line exclusions1.0v1.0.0nono
    marshal-receivern/aChecks receiver type consistency for common marshal/unmarshal methods.1.0v1.16.0nono
    max-control-nestingint (defaults to 5)Sets restriction for maximum nesting of control structures.1.0v1.3.7nono
    max-public-structsint (defaults to 5)The maximum number of public structs in a file.1.0v1.0.0nono
    modifies-parametern/aWarns on assignments to function parameters1.0v1.0.0nono
    modifies-value-receivern/aWarns on assignments to value-passed method receivers1.0v1.0.0noyes
    multiline-if-initn/aFlags if statements whose init clause spans multiple lines1.0v1.16.0nono
    nested-structsn/aWarns on structs within structs1.0v1.0.8nono
    optimize-operands-ordern/aChecks inefficient conditional expressions1.0v1.1.3nono
    package-commentsn/aPackage commenting conventions.1.0v1.0.0yesno
    package-namingmapChecks that package names follow Go conventions and best practices1.0v1.15.0nono
    package-directory-mismatchstringChecks that package name matches containing directory name1.0v1.12.0nono
    range-val-addressn/aWarns if address of range value is used dangerously< 1.22v1.0.2noyes
    range-val-in-closuren/aWarns if range value is used in a closure dispatched as goroutine< 1.22v1.0.0nono
    rangen/aPrevents redundant variables when iterating over a collection.1.0v1.0.0yesno
    receiver-namingmap (optional)Conventions around the naming of receivers.1.0v1.0.0yesno
    redefines-builtin-idn/aWarns on redefinitions of builtin identifiers1.0v1.0.0nono
    redundant-build-tagn/aWarns about build tags that are redundant: a // +build line, a go1.X constraint already guaranteed by go.mod, or a constraint implied by the file name>= 1.17v1.6.0nono
    redundant-import-aliasn/aWarns on import aliases matching the imported package name1.0v1.3.3nono
    redundant-test-main-exitn/aSuggests removing Exit call in TestMain function for test files>= 1.15v1.6.1nono
    string-formatmapWarns on specific string literals that fail one or more user-configured regular expressions1.0v1.0.7nono
    string-of-intn/aWarns on suspicious casts from int to string1.0v1.0.2noyes
    struct-tag[]stringChecks common struct tags like json, xml, yaml1.0v1.0.0nono
    superfluous-else[]stringPrevents redundant else statements (extends indent-error-flow)1.0v1.0.0nono
    time-daten/aReports bad usage of time.Date.1.0v1.10.0nono
    time-equaln/aSuggests to use time.Time.Equal instead of == and != for equality check time.1.0v1.1.3noyes
    time-namingn/aConventions around the naming of time variables.1.0v1.0.0yesyes
    unchecked-type-assertionn/aDisallows type assertions without checking the result.1.0v1.3.4nono
    unconditional-recursionn/aWarns on function calls that will lead to (direct) infinite recursion1.0v1.0.3nono
    unexported-namingn/aWarns on wrongly named un-exported symbols1.0v1.0.3nono
    unexported-returnn/aWarns when a public return is from unexported type.1.0v1.0.0yesyes
    unhandled-error[]stringWarns on unhandled errors returned by function calls1.0v1.0.0noyes
    unnecessary-ifn/aIdentifies if-else statements that can be replaced by simpler statements1.0v1.13.0nono
    unnecessary-formatn/aIdentifies calls to formatting functions where the format string does not contain any formatting verbs1.0v1.10.0nono
    unnecessary-stmtn/aSuggests removing or simplifying unnecessary statements1.0v1.0.0nono
    unreachable-coden/aWarns on unreachable code1.0v1.0.0nono
    unsecure-url-schemen/aChecks for usage of potentially unsecure URL schemes.1.0v1.12.0nono
    unused-parametern/aSuggests to rename or remove unused function parameters1.0v1.0.0nono
    unused-receivern/aSuggests to rename or remove unused method receivers1.0v1.0.0nono
    use-anyn/aProposes to replace interface{} with its alias any>= 1.18v1.2.0nono
    use-errors-newn/aSpots calls to fmt.Errorf that can be replaced by errors.New< 1.26v1.6.0nono
    use-fmt-printn/aProposes to replace calls to built-in print and println with their equivalents from fmt.1.0v1.10.0nono
    use-slices-concatn/aProposes to replace appends to an empty slice with a call to slices.Concat.>= 1.22v1.17.0nono
    use-slices-sortn/aProposes to replace calls to sort.Ints, sort.Strings and the like with their equivalents from slices package.>= 1.21v1.14.0nono
    use-waitgroup-gon/aProposes to replace wg.Add ... go {... wg.Done ...} idiom with wg.Go>= 1.25v1.12.0nono
    useless-breakn/aWarns on useless break statements in case clauses1.0v1.1.0nono
    useless-fallthroughn/aWarns on useless fallthrough statements in case clauses1.0v1.12.0nono
    var-declarationn/aReduces redundancies around variable declaration.1.0v1.0.0yesyes
    var-namingallowlist & blocklist of initialismsNaming rules.1.0v1.0.0yesno
    waitgroup-by-valuen/aWarns on functions taking sync.WaitGroup as a by-value parameter1.0v1.0.0nono

    The rules ported from golint are left unchanged and indicated in the "golint" column.

    The rules in the "Typed" column use the type system, which depends on the GOROOT and GOPATH environment variables. Therefore, if revive binary is built with -trimpath or run on GitHub Actions, these rules may not work as expected. See #1277 for details.

    Configurable rules

    A lot of rules can be configured. See RULES_DESCRIPTIONS.md for the list of all configurable rules and their options.

    Available Formatters

    This section lists all the available formatters and provides a screenshot for each one.

    Friendly

    Friendly formatter

    Stylish

    Stylish formatter

    Default

    The default formatter produces the same output as golint.

    Default formatter

    Plain

    The plain formatter produces the same output as the default formatter and appends the URL to the rule description.

    Plain formatter

    Unix

    The unix formatter produces the same output as the default formatter but surrounds the rules in [].

    Unix formatter

    JSON

    The json formatter produces output in JSON format.

    NDJSON

    The ndjson formatter produces output in Newline Delimited JSON format.

    Checkstyle

    The checkstyle formatter produces output in a Checkstyle-like format.

    SARIF

    The sarif formatter produces output in SARIF, for Static Analysis Results Interchange Format, a standard JSON-based format for the output of static analysis tools defined and promoted by OASIS.

    Current supported version of the standard is SARIF-v2.1.0.

    Extensibility

    The tool can be extended with custom rules or formatters. This section contains additional information on how to implement such.

    To extend the linter with a custom rule you can push it to this repository or use revive as a library (see below)

    To add a custom formatter you'll have to push it to this repository or fork it. This is due to the limited -buildmode=plugin support which works only on Linux (with known issues).

    Writing a Custom Rule

    See DEVELOPING.md for instructions on how to write a custom rule.

    Using revive as a library

    If a rule is specific to your use case (i.e. it is not a good candidate to be added to revive's rule set) you can add it to your linter using revive as a linting engine.

    The following code shows how to use revive in your application. In the example only one rule is added (myRule), of course, you can add as many as you need to. Your rules can be configured programmatically or with the standard revive configuration file. The full rule set of revive is also actionable by your application.

    package main
    
    import (
    	"github.com/mgechev/revive/cli"
    	"github.com/mgechev/revive/lint"
    	"github.com/mgechev/revive/revivelib"
    )
    
    func main() {
    	cli.RunRevive(revivelib.NewExtraRule(&myRule{}, lint.RuleConfig{}))
    }
    
    type myRule struct{}
    
    func (f myRule) Name() string {
    	return "myRule"
    }
    
    func (f myRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
    	// ...
    }
    

    You can still go further and use revive without its CLI, as part of your library, or your CLI:

    package mylib
    
    import (
    	"github.com/mgechev/revive/config"
    	"github.com/mgechev/revive/lint"
    	"github.com/mgechev/revive/revivelib"
    )
    
    // Error checking removed for clarity
    func LintMyFile(file string) {
    	conf, _ := config.GetConfig("../defaults.toml")
    
    	revive, _ := revivelib.New(
    		conf, // Configuration file
    		true, // Set exit status
    		2048, // Max open files
    
    		// Then add as many extra rules as you need
    		revivelib.NewExtraRule(&myRule{}, lint.RuleConfig{}),
    	)
    
    	failuresChan, err := revive.Lint(
    		revivelib.Include(file),
    		revivelib.Exclude("./fixtures"),
    		// You can use as many revivelib.Include or revivelib.Exclude as required
    	)
    	if err != nil {
    		panic("Shouldn't have failed: " + err.Error())
    	}
    
    	// Now let's return the formatted errors
    	failures, exitCode, _ := revive.Format("stylish", failuresChan)
    
    	// failures is the string with all formatted lint error messages
    	// exit code is 0 if no errors, 1 if errors (unless config options change it)
    	// ... do something with them
    }
    
    type myRule struct{}
    
    func (f myRule) Name() string {
    	return "myRule"
    }
    
    func (f myRule) Apply(*lint.File, lint.Arguments) []lint.Failure {
    	// ...
    }
    

    Custom Formatter

    Each formatter needs to implement the following interface:

    type Formatter interface {
    	Format(<-chan Failure, Config) (string, error)
    	Name() string
    }
    

    The Format method accepts a channel of Failure instances and the configuration of the enabled rules. The Name() method should return a string different from the names of the already existing rules. This string is used when specifying the formatter when invoking the revive CLI tool.

    For a sample formatter, take a look at this file.

    Speed Comparison

    Compared to golint, revive performs better because it lints the files for each individual rule into a separate goroutine. Here's a basic performance benchmark on MacBook Pro Early 2013 run on Kubernetes:

    golint

    $ time golint kubernetes/... > /dev/null
    
    real    0m54.837s
    user    0m57.844s
    sys     0m9.146s
    

    revive's speed

    # no type checking
    $ time revive -config untyped.toml kubernetes/... > /dev/null
    
    real    0m8.471s
    user    0m40.721s
    sys     0m3.262s
    

    Keep in mind that if you use rules that require type checking, the performance may drop to 2x faster than golint:

    # type checking enabled
    $ time revive kubernetes/... > /dev/null
    
    real    0m26.211s
    user    2m6.708s
    sys     0m17.192s
    

    Currently, type-checking is enabled by default. If you want to run the linter without type-checking, remove all typed rules from the configuration file.

    Overriding colorization detection

    By default, revive determines whether or not to colorize its output based on whether it's connected to a TTY or not. This works for most use cases, but may not behave as expected if you use revive in a pipeline of commands, where STDOUT is being piped to another command.

    To force colorization, add REVIVE_FORCE_COLOR=1 to the environment you're running in. For example:

    REVIVE_FORCE_COLOR=1 revive -formatter friendly ./... | tee revive.log
    

    Who uses Revive

    • tidb - TiDB is a distributed HTAP database compatible with the MySQL protocol
    • grafana - The tool for beautiful monitoring and metric analytics & dashboards for Graphite, InfluxDB & Prometheus & More
    • etcd - Distributed reliable key-value store for the most critical data of a distributed system
    • cadence - Cadence is a distributed, scalable, durable, and highly available orchestration engine by Uber to execute asynchronous long-running business logic in a scalable and resilient way
    • ferret - Declarative web scraping
    • gopass - The slightly more awesome standard unix password manager for teams
    • gitea - Git with a cup of tea, painless self-hosted git service
    • excelize - Go library for reading and writing Microsoft Excel™ (XLSX) files
    • aurora - aurora is a web-based Beanstalk queue server console written in Go
    • soar - SQL Optimizer And Rewriter
    • pyroscope - Continuous profiling platform
    • gorush - A push notification server written in Go (Golang).
    • dry - dry - A Docker manager for the terminal.
    • go-echarts - The adorable charts library for Golang
    • reviewdog - Automated code review tool integrated with any code analysis tools regardless of programming language
    • rudder-server - Privacy and Security focused Segment-alternative, in Golang and React.
    • sklearn - A partial port of scikit-learn written in Go.
    • protoc-gen-doc - Documentation generator plugin for Google Protocol Buffers.
    • llvm - Library for interacting with LLVM IR in pure Go.
    • jenkins-library - Jenkins shared library for Continuous Delivery pipelines by SAP.
    • pd - Placement driver for TiKV.
    • shellhub - ShellHub enables teams to easily access any Linux device behind firewall and NAT.
    • lorawan-stack - The Things Network Stack for LoRaWAN V3
    • gin-jwt - This is a JWT middleware for Gin framework.
    • gofight - Testing API Handler written in Golang.
    • Beaver - A Real Time Messaging Server.
    • ggz - An URL shortener service written in Golang
    • Codeac.io - Automated code review service integrates with GitHub, Bitbucket and GitLab (even self-hosted) and helps you fight technical debt.
    • DevLake - Apache DevLake is an open-source dev data platform to ingest, analyze, and visualize the fragmented data from DevOps tools,which can distill insights to improve engineering productivity.
    • checker - Checker helps validating user input through rules defined in struct tags or directly through functions.
    • milvus - A cloud-native vector database, storage for next generation AI applications.
    • indicator - Indicator provides various technical analysis indicators, strategies, and a backtesting framework.

    Open a PR to add your project.

    Contributors

    Maintainers

    alexandearchavacavadenisvmedia

    Revive was created by mgechev.

    All

    This project exists thanks to all the people who contribute.

    License

    MIT