2018-05-26 16:39:22 -07:00
[![Build Status ](https://travis-ci.org/mgechev/revive.svg?branch=master )](https://travis-ci.org/mgechev/revive)
2017-08-27 20:57:46 -07:00
# revive
2018-02-04 13:42:05 -08:00
Fast, configurable, extensible, flexible, and beautiful linter for Go.
2017-08-27 21:05:02 -07:00
2017-08-27 21:00:20 -07:00
< p align = "center" >
2018-05-30 13:44:18 -07:00
< img src = "./assets/logo.png" alt = "" width = "300" >
< br >
Logo by < a href = "https://github.com/hawkgs" > Georgi Serev< / a >
2017-08-27 21:00:20 -07:00
< / p >
2017-08-27 20:59:53 -07:00
2018-02-04 13:42:05 -08:00
Here's how `revive` is different from `golint` :
2018-05-28 20:27:04 -07:00
- Allow us to enable or disable rules using a configuration file.
- Allows us to configure the linting rules with a TOML file.
- 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.
- Provides multiple formatters which let us customize the output.
- Allows us 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` .
- Faster. It runs the rules over each file in a separate goroutine.
2018-02-04 13:42:05 -08:00
2018-05-30 13:42:28 -07:00
< p align = "center" >
2018-05-30 13:44:18 -07:00
< img src = "./assets/demo.svg" alt = "" width = "700" >
2018-05-30 13:42:28 -07:00
< / p >
2018-02-04 12:19:24 -08:00
## Usage
2018-05-26 15:17:28 -07:00
Since the default behavior of `revive` is compatible with `golint` , without providing any additional flags, the only difference you'd notice is faster execution.
2018-02-04 12:19:24 -08:00
2018-05-26 16:19:34 -07:00
### Installation
```bash
go get -u github.com/mgechev/revive
```
2018-02-04 12:19:24 -08:00
### Command Line Flags
2018-05-26 15:17:28 -07:00
`revive` accepts three command line parameters:
2018-02-04 12:19:24 -08:00
2018-05-26 15:17:28 -07:00
* `-config [PATH]` - path to config file in TOML format.
* `-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:
2018-05-26 14:16:38 -07:00
* `default` - will output the failures the same way that `golint` does.
* `json` - outputs the failures in JSON 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.
2018-02-04 12:19:24 -08:00
2018-05-26 15:17:28 -07:00
### 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`
2018-02-04 12:19:24 -08:00
### Configuration
2018-05-26 15:17:28 -07:00
`revive` can be configured with a TOML file. Here's a sample configuration with explanation for the individual properties:
```toml
# 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"
```
2018-02-04 12:19:24 -08:00
2018-02-04 13:42:05 -08:00
### Default Configuration
2018-02-18 22:19:37 -08:00
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` ).
2018-02-04 13:42:05 -08:00
```shell
revive -config defaults.toml github.com/mgechev/revive
```
2018-02-18 22:19:37 -08:00
This will use the configuration file `defaults.toml` , the `default` formatter, and will run linting over the `github.com/mgechev/revive` package.
2018-02-04 13:42:05 -08:00
### Recommended Configuration
```shell
2018-05-26 15:17:28 -07:00
revive -config config.toml -formatter friendly github.com/mgechev/revive
2018-02-04 13:42:05 -08:00
```
2018-05-26 15:17:28 -07:00
This will use `config.toml` , the `friendly` formatter, and will run linting over the `github.com/mgechev/revive` package.
2018-02-04 13:42:05 -08:00
2018-02-18 22:26:59 -08:00
## Available Rules
2018-05-26 16:16:10 -07:00
List of all available rules. The rules ported from `golint` are left unchanged and indicated in the `golit` column.
2018-05-26 16:16:35 -07:00
| Name | Config | Description | `golint` |
| --------------------- | :----: | :--------------------------------------------------------------- | :------: |
2018-05-26 16:16:55 -07:00
| `blank-imports` | n/a | Disallows blank imports | yes |
2018-05-26 21:28:31 -07:00
| `context-as-argument` | n/a | `context.Context` should be the first argument of a function. | yes |
| `context-keys-type` | n/a | Disallows the usage of basic types in `context.WithValue` . | yes |
2018-05-26 16:16:55 -07:00
| `dot-imports` | n/a | Forbids `.` imports. | yes |
| `error-return` | n/a | The error return parameter should be last. | yes |
| `error-strings` | n/a | Conventions around error strings. | yes |
2018-05-26 21:28:31 -07:00
| `error-naming` | n/a | Naming of error variables. | yes |
2018-05-26 16:16:55 -07:00
| `exported` | n/a | Naming and commenting conventions on exported symbols. | yes |
| `if-return` | n/a | Redundant if when returning an error. | yes |
| `increment-decrement` | n/a | Use `i++` and `i--` instead of `i += 1` and `i -= 1` . | yes |
2018-05-26 21:28:31 -07:00
| `var-naming` | n/a | Naming rules. | yes |
| `var-declaration` | n/a | Reduces redundancies around variable declaration. | yes |
2018-05-26 16:16:55 -07:00
| `package-comments` | n/a | Package commenting conventions. | yes |
| `range` | n/a | Prevents redundant variables when iterating over a collection. | yes |
2018-05-26 21:28:31 -07:00
| `receiver-naming` | n/a | Conventions around the naming of receivers. | yes |
| `time-naming` | n/a | Conventions around the naming of time variables. | yes |
| `unexported-return` | n/a | Warns when a public return is from unexported type. | yes |
2018-05-26 16:16:55 -07:00
| `indent-error-flow` | n/a | Prevents redundant else statements. | yes |
| `errorf` | n/a | Should replace `error.New(fmt.Sprintf())` with `error.Errorf()` | yes |
2018-05-26 16:16:10 -07:00
| `argument-limit` | int | Specifies the maximum number of arguments a function can receive | no |
2018-05-26 16:16:35 -07:00
| `cyclomatic` | int | Sets restriction for maximum Cyclomatic complexity. | no |
| `max-public-structs` | int | The maximum number of public structs in a file. | no |
| `file-header` | string | Header which each file should have. | no |
2018-02-18 22:26:59 -08:00
2018-02-18 22:40:53 -08:00
## Available Formatters
This section lists all the available formatters and provides a screenshot for each one.
2018-05-26 14:12:02 -07:00
### Friendly
![Friendly formatter ](/assets/friendly-formatter.png )
2018-05-26 12:08:02 -07:00
### Stylish
2018-02-18 22:40:53 -08:00
2018-05-26 12:08:02 -07:00
![Stylish formatter ](/assets/stylish-formatter.png )
2018-02-18 22:40:53 -08:00
2018-05-26 14:12:02 -07:00
### Default
![Default formatter ](/assets/default-formatter.png )
2018-05-26 15:17:28 -07:00
## Extensibility
2018-02-04 15:40:39 -08:00
The tool can be extended with custom rules or formatters. This section contains additional information on how to implement such.
2018-05-26 15:17:28 -07:00
**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) ](https://golang.org/pkg/plugin/ ).
2018-02-04 15:40:39 -08:00
### Custom Rule
Each rule needs to implement the `lint.Rule` interface:
```go
type Rule interface {
Name() string
Apply(*File, Arguments) []Failure
}
```
2018-02-18 22:19:37 -08:00
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:
2018-02-04 15:40:39 -08:00
```toml
[rule.ban-struct-name]
2018-02-04 15:41:22 -08:00
arguments = ["Foo"]
2018-02-04 15:40:39 -08:00
```
With the snippet above we:
2018-02-18 22:19:37 -08:00
* 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.
2018-02-04 15:40:39 -08:00
A sample rule implementation can be found [here ](/rule/argument-limit.go ).
### Custom Formatter
Each formatter needs to implement the following interface:
```go
type Formatter interface {
Format(< -chan Failure , RulesConfig ) ( string , error )
Name() string
}
```
2018-02-18 22:19:37 -08:00
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.
2018-02-04 15:40:39 -08:00
For a sample formatter, take a look at [this file ](/formatter/json.go ).
2018-05-26 19:13:54 -07:00
## 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
```shell
time golint kubernetes/... > /dev/null
real 0m54.837s
user 0m57.844s
sys 0m9.146s
```
### revive
```shell
time revive kubernetes/... > /dev/null
real 0m13.515s
user 0m53.472s
sys 0m3.199s
```
2018-02-04 12:19:24 -08:00
## License
2017-08-27 20:57:46 -07:00
MIT