1
0
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:
chavacava 2018-06-09 18:25:45 +02:00
commit b7bb0314ca
6 changed files with 172 additions and 24 deletions

View File

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

View File

@ -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
View 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
View 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
View 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{})
}

View File

@ -12,3 +12,4 @@
[rule.range]
[rule.receiver-naming]
[rule.indent-error-flow]
[rule.empty-block]