mgechev / revive
- пятница, 1 июня 2018 г. в 00:16:39
Go
Fast, configurable, extensible, flexible, and beautiful linter for Go. Drop-in replacement of golint.
Fast, configurable, extensible, flexible, and beautiful linter for Go. Drop-in replacement of golint.
Logo by Georgi Serev
Here's how revive is different from golint:
golint allows this only for generated files.Revive provides more rules compared to golint.Since the default behavior of revive is compatible with golint, without providing any additional flags, the only difference you'd notice is faster execution.
go get -u github.com/mgechev/reviverevive accepts three command line parameters:
-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:
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.revive -config revive.toml -exclude file1.go -exclude file2.go -formatter friendly github.com/mgechev/revive package/...revive.tomlrevive will ignore file1.go and file2.gofriendly formattergithub.com/mgechev/revive and the files in packagerevive can be configured with a TOML file. Here's a sample configuration with explanation for the individual properties:
# 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"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/reviveThis will use the configuration file defaults.toml, the default formatter, and will run linting over the github.com/mgechev/revive package.
revive -config config.toml -formatter friendly github.com/mgechev/reviveThis will use config.toml, the friendly formatter, and will run linting over the github.com/mgechev/revive package.
List of all available rules. The rules ported from golint are left unchanged and indicated in the golit column.
| Name | Config | Description | golint |
|---|---|---|---|
blank-imports |
n/a | Disallows blank imports | yes |
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 |
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 |
error-naming |
n/a | Naming of error variables. | yes |
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 |
var-naming |
n/a | Naming rules. | yes |
var-declaration |
n/a | Reduces redundancies around variable declaration. | yes |
package-comments |
n/a | Package commenting conventions. | yes |
range |
n/a | Prevents redundant variables when iterating over a collection. | yes |
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 |
indent-error-flow |
n/a | Prevents redundant else statements. | yes |
errorf |
n/a | Should replace error.New(fmt.Sprintf()) with error.Errorf() |
yes |
argument-limit |
int | Specifies the maximum number of arguments a function can receive | no |
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 |
This section lists all the available formatters and provides a screenshot for each one.
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).
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.
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:
ban-struct-name. The Name() method of our rule should return a string which matches ban-struct-name.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.
Each formatter needs to implement the following interface:
type Formatter interface {
Format(<-chan Failure, RulesConfig) (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.
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:
time golint kubernetes/... > /dev/null
real 0m54.837s
user 0m57.844s
sys 0m9.146stime revive kubernetes/... > /dev/null
real 0m13.515s
user 0m53.472s
sys 0m3.199sMIT