revive

golint 的完美替代品:约6倍的增速、更严格、可配置、可扩展且美观。「 ? ~6x faster, stricter, configurable, extensible, and beautiful drop-in replacement for golint. 」

Github stars Tracking Chart

revive

Go 的快速、可配置、可扩展、灵活和美观的 linter。 直接替换 golint。 Revive 提供了一个开发自定义规则的框架,并允许您定义严格的预设,以增强您的开发和代码审查流程。

以下是 revive 与 golint 的不同之处:

  • 允许使用配置文件启用或禁用规则。
  • 允许使用 TOML 文件配置 linting 规则。
  • 运行与 golint 相同的规则快2倍。
  • 提供禁用特定规则或文件或一系列行的整个 linter 的功能。
    • golint 只允许对生成的文件执行此操作。
  • 可选的类型检查。 golint 中的大多数规则都不需要进行类型检查。 如果在配置文件中禁用它们,revive 将比 golint 快6倍。
  • 提供多个格式化程序,让我们自定义输出。
  • 允许自定义整个 linter 的返回码或仅基于某些规则的失败。
  • 每个人都可以使用自定义规则或格式化程序轻松扩展它。
  • 与 golint 相比,Revive 提供了更多规则。

谁在使用 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
  • 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
  • gorush - A push notification server written in Go (Golang)a
  • go-echarts - The adorable charts library for Golang
  • reviewdog - Automated code review tool integrated with any code analysis tools regardless of programming language
  • sklearn - A partial port of scikit-learn written in Go
  • lorawan-stack - The Things Network Stack for LoRaWAN V3
  • gofight - Testing API Handler written in Golang.
  • ggz - An URL shortener service written in Golang

用法

由于 revive 的默认行为与 golint 兼容,而不提供任何其他标志,因此您注意到的唯一区别是执行速度更快。

Bazel

如果您想配合 Bazel 使用 revive,请查看 Atlassian 维护的 规则

文字编辑

call ale#linter#Define('go', {
\   'name': 'revive',
\   'output_stream': 'both',
\   'executable': 'revive',
\   'read_buffer': 0,
\   'command': 'revive %t',
\   'callback': 'ale#handlers#unix#HandleAsWarning',
\})

安装

go get -u github.com/mgechev/revive

许可

MIT

Main metrics

Overview
Name With Ownermgechev/revive
Primary LanguageGo
Program languageGo (Language Count: 3)
PlatformLinux, Mac, Windows
License:MIT License
所有者活动
Created At2017-07-04 16:36:32
Pushed At2025-06-25 13:29:59
Last Commit At2025-06-25 16:29:58
Release Count40
Last Release Namev1.10.0 (Posted on )
First Release Namev1.0.0 (Posted on )
用户参与
Stargazers Count5.2k
Watchers Count38
Fork Count298
Commits Count1.2k
Has Issues Enabled
Issues Count418
Issue Open Count43
Pull Requests Count909
Pull Requests Open Count1
Pull Requests Close Count77
项目设置
Has Wiki Enabled
Is Archived
Is Fork
Is Locked
Is Mirror
Is Private

Build Status

revive

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.

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
  • 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
  • gorush - A push notification server written in Go (Golang)a
  • go-echarts - The adorable charts library for Golang
  • reviewdog - Automated code review tool integrated with any code analysis tools regardless of programming language
  • sklearn - A partial port of scikit-learn written in Go
  • lorawan-stack - The Things Network Stack for LoRaWAN V3
  • gofight - Testing API Handler written in Golang.
  • 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.

Open a PR to add your project.

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.

Bazel

If you want to use revive with Bazel, take a look at the rules that Atlassian maintains.

Text Editors

call ale#linter#Define('go', {
\   'name': 'revive',
\   'output_stream': 'both',
\   'executable': 'revive',
\   'read_buffer': 0,
\   'command': 'revive %t',
\   'callback': 'ale#handlers#unix#HandleAsWarning',
\})

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)

Installation

go get -u github.com/mgechev/revive

Command Line Flags

revive accepts three command line parameters:

  • -config [PATH] - path to 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.

  • -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 stream in newline delimited JSON (NDJSON) format.
    • friendly - outputs the failures when found. Shows 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.

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 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 for 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"

Configuration

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

# When set to false, ignores files with "GENERATED" header, similar to golint
ignoreGeneratedHeader = 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 severity "error"
errorCode = 0

# Sets the error code for failures with severity "warning"
warningCode = 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"

Default Configuration

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

revive -config defaults.toml github.com/mgechev/revive

This will use the configuration file defaults.toml, the default formatter, and will run linting over the github.com/mgechev/revive package.

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.

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

ignoreGeneratedHeader = false
severity = "warning"
confidence = 0.8
errorCode = 0
warningCode = 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.if-return]
[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]

Available Rules

List of all available rules. The rules ported from golint are left unchanged and indicated in the golint column., Name, Config, Description, golint, Typed, ---------------------, :----:, :---------------------------------------------------------------, :------:, :---:, context-keys-type, n/a, Disallows the usage of basic types in context.WithValue., yes, yes, time-naming, n/a, Conventions around the naming of time variables., yes, yes, var-declaration, n/a, Reduces redundancies around variable declaration., yes, yes, unexported-return, n/a, Warns when a public return is from unexported type., yes, yes, errorf, n/a, Should replace errors.New(fmt.Sprintf()) with fmt.Errorf(), yes, yes, blank-imports, n/a, Disallows blank imports, yes, no, context-as-argument, n/a, context.Context should be the first argument of a function., yes, no, dot-imports, n/a, Forbids . imports., yes, no, error-return, n/a, The error return parameter should be last., yes, no, error-strings, n/a, Conventions around error strings., yes, no, error-naming, n/a, Naming of error variables., yes, no, exported, n/a, Naming and commenting conventions on exported symbols., yes, no, if-return, n/a, Redundant if when returning an error., yes, no, increment-decrement, n/a, Use i++ and i-- instead of i += 1 and i -= 1., yes, no, var-naming, whitelist & blacklist of initialisms, Naming rules., yes, no, package-comments, n/a, Package commenting conventions., yes, no, range, n/a, Prevents redundant variables when iterating over a collection., yes, no, receiver-naming, n/a, Conventions around the naming of receivers., yes, no, indent-error-flow, n/a, Prevents redundant else statements., yes, no, argument-limit, int, Specifies the maximum number of arguments a function can receive, no, no, cyclomatic, int, Sets restriction for maximum Cyclomatic complexity., no, no, max-public-structs, int, The maximum number of public structs in a file., no, no, file-header, string, Header which each file should have., no, no, empty-block, n/a, Warns on empty code blocks, no, no, superfluous-else, n/a, Prevents redundant else statements (extends indent-error-flow), no, no, confusing-naming, n/a, Warns on methods with names that differ only by capitalization, no, no, get-return, n/a, Warns on getters that do not yield any result, no, no, modifies-parameter, n/a, Warns on assignments to function parameters, no, no, confusing-results, n/a, Suggests to name potentially confusing function results, no, no, deep-exit, n/a, Looks for program exits in funcs other than main() or init(), no, no, unused-parameter, n/a, Suggests to rename or remove unused function parameters, no, no, unreachable-code, n/a, Warns on unreachable code, no, no, add-constant, map, Suggests using constant for magic numbers and string literals, no, no, flag-parameter, n/a, Warns on boolean parameters that create a control coupling, no, no, unnecessary-stmt, n/a, Suggests removing or simplifying unnecessary statements, no, no, struct-tag, n/a, Checks common struct tags like json,xml,yaml, no, no, modifies-value-receiver, n/a, Warns on assignments to value-passed method receivers, no, yes, constant-logical-expr, n/a, Warns on constant logical expressions, no, no, bool-literal-in-expr, n/a, Suggests removing Boolean literals from logic expressions, no, no, redefines-builtin-id, n/a, Warns on redefinitions of builtin identifiers, no, no, function-result-limit, int, Specifies the maximum number of results a function can return, no, no, imports-blacklist, []string, Disallows importing the specified packages, no, no, range-val-in-closure, n/a, Warns if range value is used in a closure dispatched as goroutine, no, no, waitgroup-by-value, n/a, Warns on functions taking sync.WaitGroup as a by-value parameter, no, no, atomic, n/a, Check for common mistaken usages of the sync/atomic package, no, no, empty-lines, n/a, Warns when there are heading or trailing newlines in a block, no, no, line-length-limit, int, Specifies the maximum number of characters in a line, no, no, call-to-gc, n/a, Warns on explicit call to the garbage collector, no, no, duplicated-imports, n/a, Looks for packages that are imported two or more times, no, no, import-shadowing, n/a, Spots identifiers that shadow an import, no, no, bare-return, n/a, Warns on bare returns, no, no, unused-receiver, n/a, Suggests to rename or remove unused method receivers, no, no, unhandled-error, []string, Warns on unhandled errors returned by funcion calls, no, yes, cognitive-complexity, int, Sets restriction for maximum Cognitive complexity., no, no, ## Configurable rules

Here you can find how you can configure some of the existing rules:

var-naming

This rule accepts two slices of strings, a whitelist and a blacklist of initialisms. By default the rule behaves exactly as the alternative in golint but optionally, you can relax it (see golint/lint/issues/89)

[rule.var-naming]
  arguments = [["ID"], ["VM"]]

This way, revive will not warn for identifier called customId but will warn that customVm should be called customVM.

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

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 or a 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).

Custom Rule

Each rule needs to implement the lint.Rule interface:

type Rule interface {
	Name() string
	Apply(*File, Arguments) []Failure
}

The Arguments type is an alias of the type []interface{}. The arguments of the rule are passed from the configuration file.

Example

Let's suppose we have developed a rule called BanStructNameRule which disallow us to name a structure with given identifier. We can set the banned identifier by using the TOML configuration file:

[rule.ban-struct-name]
  arguments = ["Foo"]

With the snippet above we:

  • Enable the rule with name ban-struct-name. The Name() method of our rule should return a string which matches ban-struct-name.
  • Configure the rule with the argument Foo. The list of arguments will be passed to Apply(*File, Arguments) together with the target file we're linting currently.

A sample rule implementation can be found here.

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

# 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 which 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.

Contributors

, , , , , , :---:, :---:, :---:, :---:, :---:, :---:, mgechev, chavacava, xuri, gsamokovarov, morphy2k, markelog, , , , , , , :---:, :---:, :---:, :---:, :---:, :---:, tamird, mapreal19, Clivern, AragurDEV, yangdiangzb, jamesmaidment, , , , , , , :---:, :---:, :---:, :---:, :---:, :---:, johnrichardrinehart, michalhisim, pa-m, paul-at-start, weastur, ridvansumset, , , , :---:, :---:, :---:, Jarema, vkrol, haya14busa, ## License

MIT