revive
~6x faster, stricter, configurable, extensible, and beautiful drop-in replacement for `golint`
About revive
This large README is shown as a plain-text preview. Read the full README at the source
# revive
[](https://github.com/revive-lint/revive/actions/workflows/test.yaml)
[](https://pkg.go.dev/github.com/mgechev/revive)
[](https://deepwiki.com/revive-lint/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**.
<p align="center">
<img src="./assets/logo.png" alt="" width="300">
<br>
Logo by <a href="https://github.com/hawkgs">Georgi Serev</a>
</p>
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`.
<p align="center">
<img src="./assets/demo.svg" alt="" width="700">
</p>
<!-- toc -->
- [Installation](#installation)
- [Homebrew](#homebrew)
- [Install from Sources](#install-from-sources)
- [Docker](#docker)
- [Manual Binary Download](#manual-binary-download)
- [Usage](#usage)
- [Text Editors](#text-editors)
- [GitHub Actions](#github-actions)
- [Continuous Integration](#continuous-integration)
- [Linter aggregators](#linter-aggregators)
- [golangci-lint](#golangci-lint)
- [MegaLinter](#megalinter)
- [Command Line Flags](#command-line-flags)
- [Sample Invocations](#sample-invocations)
- [Comment Directives](#comment-directives)
- [Configuration](#configuration)
- [Custom Configuration](#custom-configuration)
- [Recommended Configuration](#recommended-configuration)
- [Rule-level file excludes](#rule-level-file-excludes)
- [Available Rules](#available-rules)
- [Configurable rules](#configurable-rules)
- [Available Formatters](#available-formatters)
- [Friendly](#friendly)
- [Stylish](#stylish)
- [Default](#default)
- [Plain](#plain)
- [Unix](#unix)
- [JSON](#json)
- [NDJSON](#ndjson)
- [Checkstyle](#checkstyle)
- [SARIF](#sarif)
- [Extensibility](#extensibility)
- [Writing a Custom Rule](#writing-a-custom-rule)
- [Using `revive` as a library](#using-revive-as-a-library)
- [Custom Formatter](#custom-formatter)
- [Speed Comparison](#speed-comparison)
- [golint](#golint)
- [revive's speed](#revives-speed)
- [Overriding colorization detection](#overriding-colorization-detection)
- [Who uses Revive](#who-uses-revive)
- [Contributors](#contributors)
- [Maintainers](#maintainers)
- [All](#all)
- [License](#license)
<!-- tocstop -->
## Installation
`revive` is available inside the majority of package managers.
[<img alt="Repology packaging status" src="https://repology.org/badge/vertical-allrepos/revive.svg">](https://repology.org/project/revive/versions)
### Homebrew
Install `revive` using [brew](https://brew.sh/):
```bash
brew install revive
```
To upgrade to the latest version:
```bash
brew upgrade revive
```
### Install from Sources
Install the latest stable release directly from source:
```bash
go install github.com/mgechev/revive@latest
```
To install the latest commit from the main branch:
```bash
go install github.com/mgechev/revive@HEAD
```
### Docker
You can run `revive` using Docker to avoid installing it directly on your system:
```bash
docker run -v "$(pwd)":/var/YOUR_REPOSITORY ghcr.io/mgechev/revive:v1.16.0 -config /var/YOUR_REPOSITORY/revive.toml -formatter stylish ./var/YOUR_REPOSITORY/...
```
_Note_: Replace `YOUR_REPOSITORY` with the path to your repository.
A volume must be mounted to share the current repository with the container.
For more details, refer to the [bind mounts Docker documentation](https://docs.docker.com/storage/bind-mounts/).
- `-v`: Mounts the current directory (`$(pwd)`) to `/var/YOUR_REPOSITORY` inside the container.
- `ghcr.io/mgechev/revive:v1.16.0`: Specifies the Docker image and its version.
- `revive`: The command to run inside the container.
- Flags like `-config` and `-formatter` are the same as when using the binary directly.
_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](https://github.com/revive-lint/revive/releases):
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:
```bash
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](https://code.visualstudio.com/docs/languages/go#_build-and-diagnose) by changing the `go.lintTool` setting to `revive`:
```json
{
"go.lintTool": "revive",
}
```
- Support for GoLand via [File Watchers](https://dev.to/s0xzwasd/configure-revive-go-linter-in-goland-2ggl).
- Support for vim via [dense-analysis/ale](https://github.com/dense-analysis/ale).
```vim
let g:ale_linters = {
\ 'go': ['revive'],
\}
```
### GitHub Actions
- [Revive Action](https://github.com/marketplace/actions/revive-action) with annotation support
### Continuous Integration
[Codeac.io](https://www.codeac.io?ref=revive) - Automated code review service integrates with GitHub,
Bitbucket and GitLab (even self-hosted) and helps you fight technical debt.
Check your [pull-requests](https://www.codeac.io/documentation/pull-requests.html?ref=revive) with
[revive](https://www.codeac.io/documentation/revive-configuration.html?ref=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:
```yaml
# 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:
```yaml
# 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](#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](https://golangci-lint.run/usage/linters/#revive) 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](#available-rules) details what are the `golint` rules).
When a configuration is provided, only rules in the configuration are enabled.
#### MegaLinter
[MegaLinter](https://megalinter.io/), an open-source linters aggregator for CI, runs `revive` on Go projects out of the box.
See its [revive documentation page](https://megalinter.io/latest/descriptors/go_revive/) 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](https://checkstyle.org/).
- `-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
```shell
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:
```go
//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:
```go
//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
```go
//revive:disable Until the code is stable
```
```go
//revive:disable:cyclomatic High complexity score but easy to understand
```
You can also configure `revive` to enforce documenting linter disabling directives by adding
```toml
[directive.specify-disable-reason]
```
in the configuration. You can set the severity (defaults to _warning_) of the violation of this directive
```toml
[directive.specify-disable-reason]
severity = "error"
```
Similarly, you can enforce specifying rule names in disable directives by adding
```toml
[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
```toml
[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:
```toml
# 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:
```toml
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:
```toml
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:
```toml
[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:
```toml
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
```shell
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:
```toml
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.
```toml
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](./RULES_DESCRIPTIONS.md).
| Name | Config | Description | Go version | Revive version | `golint` | Typed |
| --------------------- | :----: | :--------------------------------------------------------------- | :--------: | :------------: | :------: | :---: |
| [`add-constant`](./RULES_DESCRIPTIONS.md#add-constant) | map | Suggests using constant for magic numbers and string literals | 1.0 | [v1.0.0](https://github.com/revive-lint/revive/releases/tag/v1.0.0) | no | no |
| [`argument-limit`](./RULES_DESCRIPTIONS.md#argument-limit) | int (defaults to 8) | Specifies the maximum number of arguments a function can receive | 1.0 | [v1.0.0](https://github.com/revive-lint/revive/releases/tag/v1.0.0) | no | no |
| [`atomic`](./RULES_DESCRIPTIONS.md#atomic) | n/a | Check for common mistaken usages of the `sync/atomic` package | 1.0 | [v1.0.0](https://github.com/revive-lint/revive/releases/tag/v1.0.0) | no | no |
| [`banned-characters`](./RULES_DESCRIPTIONS.md#banned-characters) | []string (defaults to []string{}) | Checks banned characters in identifiers | 1.0 | [v1.1.3](https://github.com/revive-lint/revive/releases/tag/v1.1.3) | no | no |
| [`bare-return`](./RULES_DESCRIPTIONS.md#bare-return) | n/a | Warns on bare returns | 1.0 | [v1.0.0](https://github.com/revive-lint/revive/releases/tag/v1.0.0) | no | no |
| [`blank-imports`](./RULES_DESCRIPTIONS.md#blank-imports) | n/a | Disallows blank imports | 1.0 | [v1.0.0](https://github.com/revive-lint/revive/releases/tag/v1.0.0) | yes | no |
| [`bool-literal-in-expr`](./RULES_DESCRIPTIONS.md#bool-literal-in-expr)| n/a | Suggests removing Boolean literals from logic expressions | 1.0 | [v1.0.0](https://github.com/revive-lint/revive/releases/tag/v1.0.0) | no | no |
| [`call-to-gc`](./RULES_DESCRIPTIONS.md#call-to-gc) | n/a | Warns on explicit call to the garbage collector | 1.0 | [v1.0.0](https://github.com/revive-lint/revive/releases/tag/v1.0.0) | no | no |
| [`cognitive-complexity`](./RULES_DESCRIPTIONS.md#cognitive-complexity) | int (defaults to 7) | Sets restriction for maximum Cognitive complexity. | 1.0 | [v1.0.0](https://github.com/revive-lint/revive/releases/tag/v1.0.0) | no | no |
| [`comment-spacings`](./RULES_DESCRIPTIONS.md#comment-spacings) | []string | Warns on malformed comments | 1.0 | [v1.2.5](https://github.com/revive-lint/revive/releases/tag/v1.2.5) | no | no |
| [`comments-density`](./RULES_DESCRIPTIONS.md#comments-density) | int (defaults to 0) | Enforces a minimum comment / code relation | 1.0 | [v1.3.8](https://github.com/revive-lint/revive/releases/tag/v1.3.8) | no | no |Frequently Asked Questions
What is revive?
revive is a Code Analysis library for the Go programming language. ~6x faster, stricter, configurable, extensible, and beautiful drop-in replacement for `golint`
How many GitHub stars does revive have?
revive has 5,554 GitHub stars in the directory's latest synchronization.
How do I install revive?
Install revive with the Go module system using `go get mgechev/revive`. Check the repository for the current installation instructions.
What category does revive belong to?
revive is listed under Code Analysis, specifically Code Analysis.