mirror of
https://github.com/mgechev/revive.git
synced 2025-01-10 03:17:11 +02:00
resolves conflict in README.md
This commit is contained in:
commit
b7bb0314ca
96
README.md
96
README.md
@ -12,28 +12,69 @@ Fast, configurable, extensible, flexible, and beautiful linter for Go. Drop-in r
|
||||
|
||||
Here's how `revive` is different from `golint`:
|
||||
|
||||
* Allows us to enable or disable rules using a configuration file.
|
||||
* Allows us 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 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`.
|
||||
- Allows us to enable or disable rules using a configuration file.
|
||||
- Allows us 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 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`.
|
||||
|
||||
<p align="center">
|
||||
<img src="./assets/demo.svg" alt="" width="700">
|
||||
</p>
|
||||
|
||||
<!-- TOC -->
|
||||
|
||||
- [revive](#revive)
|
||||
- [Usage](#usage)
|
||||
- [Text Editors](#text-editors)
|
||||
- [Installation](#installation)
|
||||
- [Command Line Flags](#command-line-flags)
|
||||
- [Sample Invocations](#sample-invocations)
|
||||
- [Comment Annotations](#comment-annotations)
|
||||
- [Configuration](#configuration)
|
||||
- [Default Configuration](#default-configuration)
|
||||
- [Recommended Configuration](#recommended-configuration)
|
||||
- [Available Rules](#available-rules)
|
||||
- [Available Formatters](#available-formatters)
|
||||
- [Friendly](#friendly)
|
||||
- [Stylish](#stylish)
|
||||
- [Default](#default)
|
||||
- [Extensibility](#extensibility)
|
||||
- [Custom Rule](#custom-rule)
|
||||
- [Example](#example)
|
||||
- [Custom Formatter](#custom-formatter)
|
||||
- [Speed Comparison](#speed-comparison)
|
||||
- [golint](#golint)
|
||||
- [revive](#revive-1)
|
||||
- [Contributors](#contributors)
|
||||
- [License](#license)
|
||||
|
||||
<!-- /TOC -->
|
||||
|
||||
## 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.
|
||||
|
||||
### Text Editors
|
||||
|
||||
* Support for VSCode in [vscode-go](https://github.com/Microsoft/vscode-go/pull/1699).
|
||||
- Support for VSCode in [vscode-go](https://github.com/Microsoft/vscode-go/pull/1699).
|
||||
- Support for vim via [w0rp/ale](https://github.com/w0rp/ale):
|
||||
|
||||
```vim
|
||||
call ale#linter#Define('go', {
|
||||
\ 'name': 'revive',
|
||||
\ 'output_stream': 'both',
|
||||
\ 'executable': 'revive',
|
||||
\ 'read_buffer': 0,
|
||||
\ 'command': 'revive %t',
|
||||
\ 'callback': 'ale#handlers#unix#HandleAsWarning',
|
||||
\})
|
||||
```
|
||||
|
||||
### Installation
|
||||
|
||||
@ -45,13 +86,13 @@ go get -u github.com/mgechev/revive
|
||||
|
||||
`revive` 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.
|
||||
- `-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.
|
||||
|
||||
### Sample Invocations
|
||||
|
||||
@ -59,10 +100,10 @@ go get -u github.com/mgechev/revive
|
||||
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`
|
||||
- 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 Annotations
|
||||
|
||||
@ -167,6 +208,7 @@ List of all available rules. The rules ported from `golint` are left unchanged a
|
||||
| `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 |
|
||||
|
||||
## Available Formatters
|
||||
@ -215,8 +257,8 @@ Let's suppose we have developed a rule called `BanStructNameRule` which disallow
|
||||
|
||||
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.
|
||||
- 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](/rule/argument-limit.go).
|
||||
|
||||
@ -273,6 +315,12 @@ 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
|
||||
|
||||
| [<img alt="mgechev" src="https://avatars1.githubusercontent.com/u/455023?v=4&s=117" width="117">](https://github.com/mgechev) | [<img alt="paul-at-start" src="https://avatars2.githubusercontent.com/u/5486775?v=4&s=117" width="117">](https://github.com/paul-at-start) | [<img alt="chavacava" src="https://avatars2.githubusercontent.com/u/25788468?v=4&s=117" width="117">](https://github.com/chavacava) |
|
||||
| :---------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------: |
|
||||
| [mgechev](https://github.com/mgechev) | [paul-at-start](https://github.com/paul-at-start) | [chavacava](https://github.com/chavacava) |
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
@ -47,6 +47,8 @@ var allRules = append([]lint.Rule{
|
||||
&rule.ArgumentsLimitRule{},
|
||||
&rule.CyclomaticRule{},
|
||||
&rule.FileHeaderRule{},
|
||||
&rule.EmptyBlockRule{},
|
||||
&rule.SuperfluousElseRule{},
|
||||
}, defaultRules...)
|
||||
|
||||
var allFormatters = []lint.Formatter{
|
||||
|
33
fixtures/empty-block.go
Normal file
33
fixtures/empty-block.go
Normal file
@ -0,0 +1,33 @@
|
||||
// Test of empty-blocks.
|
||||
|
||||
package fixtures
|
||||
|
||||
func f(x int) bool { // MATCH /this block is empty, you can remove it/
|
||||
|
||||
}
|
||||
|
||||
func g(f func() bool) string {
|
||||
{ // MATCH /this block is empty, you can remove it/
|
||||
}
|
||||
|
||||
if ok := f(); ok { // MATCH /this block is empty, you can remove it/
|
||||
// only a comment
|
||||
} else {
|
||||
println("it's NOT empty!")
|
||||
}
|
||||
|
||||
if ok := f(); ok {
|
||||
println("it's NOT empty!")
|
||||
} else { // MATCH /this block is empty, you can remove it/
|
||||
|
||||
}
|
||||
|
||||
for i := 0; i < 10; i++ { // MATCH /this block is empty, you can remove it/
|
||||
|
||||
}
|
||||
|
||||
for { // MATCH /this block is empty, you can remove it/
|
||||
|
||||
}
|
||||
|
||||
}
|
52
rule/empty-block.go
Normal file
52
rule/empty-block.go
Normal file
@ -0,0 +1,52 @@
|
||||
package rule
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
|
||||
"github.com/mgechev/revive/lint"
|
||||
)
|
||||
|
||||
// EmptyBlockRule lints given else constructs.
|
||||
type EmptyBlockRule struct{}
|
||||
|
||||
// Apply applies the rule to given file.
|
||||
func (r *EmptyBlockRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||
var failures []lint.Failure
|
||||
|
||||
onFailure := func(failure lint.Failure) {
|
||||
failures = append(failures, failure)
|
||||
}
|
||||
|
||||
w := lintEmptyBlock{make(map[*ast.IfStmt]bool), onFailure}
|
||||
ast.Walk(w, file.AST)
|
||||
return failures
|
||||
}
|
||||
|
||||
// Name returns the rule name.
|
||||
func (r *EmptyBlockRule) Name() string {
|
||||
return "empty-block"
|
||||
}
|
||||
|
||||
type lintEmptyBlock struct {
|
||||
ignore map[*ast.IfStmt]bool
|
||||
onFailure func(lint.Failure)
|
||||
}
|
||||
|
||||
func (w lintEmptyBlock) Visit(node ast.Node) ast.Visitor {
|
||||
block, ok := node.(*ast.BlockStmt)
|
||||
if !ok {
|
||||
return w
|
||||
}
|
||||
|
||||
if len(block.List) == 0 {
|
||||
w.onFailure(lint.Failure{
|
||||
Confidence: 1,
|
||||
Node: block,
|
||||
Category: "logic",
|
||||
URL: "#empty-block",
|
||||
Failure: "this block is empty, you can remove it",
|
||||
})
|
||||
}
|
||||
|
||||
return w
|
||||
}
|
12
test/empty-block_test.go
Normal file
12
test/empty-block_test.go
Normal file
@ -0,0 +1,12 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/mgechev/revive/rule"
|
||||
)
|
||||
|
||||
// TestEmptyBlock rule.
|
||||
func TestEmptyBlock(t *testing.T) {
|
||||
testRule(t, "empty-block", &rule.EmptyBlockRule{})
|
||||
}
|
@ -12,3 +12,4 @@
|
||||
[rule.range]
|
||||
[rule.receiver-naming]
|
||||
[rule.indent-error-flow]
|
||||
[rule.empty-block]
|
||||
|
Loading…
Reference in New Issue
Block a user