github.com/Johnny2210/revive@v1.0.8-0.20210625134200-febf37ccd0f5/README.md (about)

     1  [![Build Status](https://travis-ci.org/mgechev/revive.svg?branch=master)](https://travis-ci.org/mgechev/revive)
     2  
     3  # revive
     4  
     5  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**.
     6  
     7  <p align="center">
     8    <img src="./assets/logo.png" alt="" width="300">
     9    <br>
    10    Logo by <a href="https://github.com/hawkgs">Georgi Serev</a>
    11  </p>
    12  
    13  Here's how `revive` is different from `golint`:
    14  
    15  - Allows to enable or disable rules using a configuration file.
    16  - Allows to configure the linting rules with a TOML file.
    17  - 2x faster running the same rules as golint.
    18  - Provides functionality for disabling a specific rule or the entire linter for a file or a range of lines.
    19    - `golint` allows this only for generated files.
    20  - 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.
    21  - Provides multiple formatters which let us customize the output.
    22  - Allows to customize the return code for the entire linter or based on the failure of only some rules.
    23  - _Everyone can extend it easily with custom rules or formatters._
    24  - `Revive` provides more rules compared to `golint`.
    25  
    26  ## Who uses Revive
    27  
    28  - [`tidb`](https://github.com/pingcap/tidb) - TiDB is a distributed HTAP database compatible with the MySQL protocol
    29  - [`grafana`](https://github.com/grafana/grafana) - The tool for beautiful monitoring and metric analytics & dashboards for Graphite, InfluxDB & Prometheus & More
    30  - [`etcd`](https://github.com/etcd-io/etcd) - Distributed reliable key-value store for the most critical data of a distributed system
    31  - [`ferret`](https://github.com/MontFerret/ferret) - Declarative web scraping
    32  - [`gopass`](https://github.com/gopasspw/gopass) - The slightly more awesome standard unix password manager for teams
    33  - [`gitea`](https://github.com/go-gitea/gitea) - Git with a cup of tea, painless self-hosted git service
    34  - [`excelize`](https://github.com/360EntSecGroup-Skylar/excelize) - Go library for reading and writing Microsoft Excelâ„¢ (XLSX) files
    35  - [`aurora`](https://github.com/xuri/aurora) - aurora is a web-based Beanstalk queue server console written in Go
    36  - [`soar`](https://github.com/XiaoMi/soar) - SQL Optimizer And Rewriter
    37  - [`pyroscope`](https://github.com/pyroscope-io/pyroscope) - Continuous profiling platform
    38  - [`gorush`](https://github.com/appleboy/gorush) - A push notification server written in Go (Golang)a
    39  - [`dry`](https://github.com/moncho/dry) - dry - A Docker manager for the terminal.
    40  - [`go-echarts`](https://github.com/chenjiandongx/go-echarts) - The adorable charts library for Golang
    41  - [`reviewdog`](https://github.com/reviewdog/reviewdog) - Automated code review tool integrated with any code analysis tools regardless of programming language
    42  - [`rudder-server`](https://github.com/rudderlabs/rudder-server) - Privacy and Security focused Segment-alternative, in Golang and React.
    43  - [`sklearn`](https://github.com/pa-m/sklearn) - A partial port of scikit-learn written in Go.
    44  - [`protoc-gen-doc`](https://github.com/pseudomuto/protoc-gen-doc) - Documentation generator plugin for Google Protocol Buffers.
    45  - [`llvm`](https://github.com/llir/llvm) - Library for interacting with LLVM IR in pure Go.
    46  - [`jenkins-library`](https://github.com/SAP/jenkins-library) - Jenkins shared library for Continuous Delivery pipelines by SAP.
    47  - [`pd`](https://github.com/tikv/pd) - Placement driver for TiKV.
    48  - [`shellhub`](https://github.com/shellhub-io/shellhub) - ShellHub enables teams to easily access any Linux device behind firewall and NAT.
    49  - [`lorawan-stack`](https://github.com/TheThingsNetwork/lorawan-stack) - The Things Network Stack for LoRaWAN V3
    50  - [`gin-jwt`](https://github.com/appleboy/gin-jwt) - This is a JWT middleware for Gin framework.
    51  - [`gofight`](https://github.com/appleboy/gofight) - Testing API Handler written in Golang.
    52  - [`Beaver`](https://github.com/Clivern/Beaver) - A Real Time Messaging Server.
    53  - [`ggz`](https://github.com/go-ggz/ggz) - An URL shortener service written in Golang
    54  - [`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.
    55  
    56  *Open a PR to add your project*.
    57  
    58  <p align="center">
    59    <img src="./assets/demo.svg" alt="" width="700">
    60  </p>
    61  
    62  <!-- TOC -->
    63  
    64  - [revive](#revive)
    65    - [Usage](#usage)
    66      - [Bazel](#bazel)
    67      - [Text Editors](#text-editors)
    68      - [Continuous Integration](#continuous-integration)
    69      - [Linter Aggregators](#linter-aggregators)
    70        - [golangci-lint](#golangci-lint)
    71      - [Installation](#installation)
    72      - [Command Line Flags](#command-line-flags)
    73      - [Sample Invocations](#sample-invocations)
    74      - [Comment Annotations](#comment-annotations)
    75      - [Configuration](#configuration)
    76      - [Default Configuration](#default-configuration)
    77      - [Custom Configuration](#custom-configuration)
    78      - [Recommended Configuration](#recommended-configuration)
    79    - [Available Rules](#available-rules)
    80    - [Configurable rules](#configurable-rules)
    81      - [`var-naming`](#var-naming)
    82    - [Available Formatters](#available-formatters)
    83      - [Friendly](#friendly)
    84      - [Stylish](#stylish)
    85      - [Default](#default)
    86      - [Plain](#plain)
    87      - [Unix](#unix)
    88      - [SARIF](#sarif)
    89    - [Extensibility](#extensibility)
    90      - [Custom Rule](#custom-rule)
    91        - [Example](#example)
    92      - [Custom Formatter](#custom-formatter)
    93    - [Speed Comparison](#speed-comparison)
    94      - [golint](#golint)
    95      - [revive](#revive)
    96    - [Overriding colorization detection](#overriding-colorization-detection)
    97    - [Contributors](#contributors)
    98    - [License](#license)
    99  
   100  <!-- /TOC -->
   101  
   102  ## Usage
   103  
   104  Since the default behavior of `revive` is compatible with `golint`, without providing any additional flags, the only difference you'd notice is faster execution.
   105  
   106  `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.
   107  
   108  ### Bazel
   109  
   110  If you want to use revive with Bazel, take a look at the [rules](https://github.com/atlassian/bazel-tools/tree/master/gorevive) that Atlassian maintains.
   111  
   112  ### Text Editors
   113  
   114  - Support for VSCode in [vscode-go](https://github.com/Microsoft/vscode-go/pull/1699).
   115  - Support for GoLand via [File Watchers](https://dev.to/s0xzwasd/configure-revive-go-linter-in-goland-2ggl).
   116  - Support for Atom via [linter-revive](https://github.com/morphy2k/linter-revive).
   117  - Support for vim via [dense-analysis/ale](https://github.com/dense-analysis/ale).
   118  
   119  ```vim
   120  let g:ale_linters = {
   121  \   'go': ['revive'],
   122  \}
   123  ```
   124  
   125  ### GitHub Actions
   126  
   127  - [Revive Action](https://github.com/marketplace/actions/revive-action) with annotation support
   128  
   129  ### Continuous Integration
   130  
   131  [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)
   132  
   133  ### Linter aggregators
   134  
   135  #### golangci-lint
   136  To enable `revive` in `golangci-lint` you need to add `revive` to the list of enabled linters:
   137  
   138  ```yaml
   139  # golangci-lint configuration file
   140  linters:
   141     enable:
   142       - revive
   143  ```
   144  Then `revive` can be configured by adding an entry to the `linters-settings` section of the configuration, for example:
   145  
   146  ```yaml
   147  # golangci-lint configuration file
   148  linters-settings:
   149    revive:
   150      ignore-generated-header: true
   151      severity: warning
   152      rules:
   153        - name: atomic
   154        - name: line-length-limit
   155          severity: error
   156          arguments: [80]
   157        - name: unhandled-error
   158          arguments : ["fmt.Printf", "myFunction"]
   159  ```
   160  
   161  The above configuration enables three rules of `revive`: _atomic_, _line-length-limit_ and _unhandled-error_ and pass some arguments to the last two.
   162  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.
   163  
   164  Please notice that if no particular configuration is provided, `revive` will behave as `go-lint` does, i.e. all `go-lint` rules are enabled (the [Available Rules table](#available-rules) details what are the `go-lint` rules). When a configuration is provided, only rules in the configuration are enabled.
   165  
   166  ### Installation
   167  
   168  ```bash
   169  go get -u github.com/mgechev/revive
   170  ```
   171  
   172  ### Command Line Flags
   173  
   174  `revive` accepts three command line parameters:
   175  
   176  - `-config [PATH]` - path to config file in TOML format, defaults to `$HOME/revive.toml` if present.
   177  - `-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.
   178  - `-formatter [NAME]` - formatter to be used for the output. The currently available formatters are:
   179  
   180    - `default` - will output the failures the same way that `golint` does.
   181    - `json` - outputs the failures in JSON format.
   182    - `ndjson` - outputs the failures as stream in newline delimited JSON (NDJSON) format.
   183    - `friendly` - outputs the failures when found. Shows summary of all the failures.
   184    - `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.
   185    - `checkstyle` - outputs the failures in XML format compatible with that of Java's [Checkstyle](https://checkstyle.org/).
   186  
   187  ### Sample Invocations
   188  
   189  ```shell
   190  revive -config revive.toml -exclude file1.go -exclude file2.go -formatter friendly github.com/mgechev/revive package/...
   191  ```
   192  
   193  - The command above will use the configuration from `revive.toml`
   194  - `revive` will ignore `file1.go` and `file2.go`
   195  - The output will be formatted with the `friendly` formatter
   196  - The linter will analyze `github.com/mgechev/revive` and the files in `package`
   197  
   198  ### Comment Directives
   199  
   200  Using comments, you can disable the linter for the entire file or only range of lines:
   201  
   202  ```go
   203  //revive:disable
   204  
   205  func Public() {}
   206  //revive:enable
   207  ```
   208  
   209  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.
   210  
   211  With `revive:disable-next-line` and `revive:disable-line` you can disable `revive` on a particular code line.
   212  
   213  You can do the same on a rule level. In case you want to disable only a particular rule, you can use:
   214  
   215  ```go
   216  //revive:disable:unexported-return
   217  func Public() private {
   218    return private
   219  }
   220  //revive:enable:unexported-return
   221  ```
   222  
   223  This way, `revive` will not warn you for that you're returning an object of an unexported type, from an exported function.
   224  
   225  You can document why you disable the linter by adding a trailing text in the directive, for example
   226  
   227  ```go
   228  //revive:disable Until the code is stable
   229  ```
   230  ```go
   231  //revive:disable:cyclomatic High complexity score but easy to understand
   232  ```
   233  
   234  You can also configure `revive` to enforce documenting linter disabling directives by adding
   235  
   236  ```toml
   237  [directive.specify-disable-reason]
   238  ```
   239  
   240  in the configuration. You can set the severity (defaults to _warning_) of the violation of this directive
   241  
   242  ```toml
   243  [directive.specify-disable-reason]
   244      severity = "error"
   245  ```
   246  
   247  ### Configuration
   248  
   249  `revive` can be configured with a TOML file. Here's a sample configuration with explanation for the individual properties:
   250  
   251  ```toml
   252  # When set to false, ignores files with "GENERATED" header, similar to golint
   253  ignoreGeneratedHeader = true
   254  
   255  # Sets the default severity to "warning"
   256  severity = "warning"
   257  
   258  # Sets the default failure confidence. This means that linting errors
   259  # with less than 0.8 confidence will be ignored.
   260  confidence = 0.8
   261  
   262  # Sets the error code for failures with severity "error"
   263  errorCode = 0
   264  
   265  # Sets the error code for failures with severity "warning"
   266  warningCode = 0
   267  
   268  # Configuration of the `cyclomatic` rule. Here we specify that
   269  # the rule should fail if it detects code with higher complexity than 10.
   270  [rule.cyclomatic]
   271    arguments = [10]
   272  
   273  # Sets the severity of the `package-comments` rule to "error".
   274  [rule.package-comments]
   275    severity = "error"
   276  ```
   277  
   278  By default `revive` will enable only the linting rules that are named in the configuration file.
   279  For example, the previous configuration file makes `revive` to enable only _cyclomatic_ and _package-comments_ linting rules.
   280  
   281  To enable all available rules you need to add:
   282  
   283  ```toml
   284  enableAllRules = true
   285  ```
   286  
   287  This will enable all available rules no matter of what rules are named in the configuration file.
   288  
   289  To disable a rule, you simply mark it as disabled in the configuration.
   290  For example:
   291  
   292  ```toml
   293  [rule.line-length-limit]
   294      Disabled = true
   295  ```
   296  When enabling all rules you still need/can provide specific configurations for rules.
   297  The following files is an example configuration were all rules are enabled, with exception to those that are explicitly disabled, and some rules are configured with particular arguments:
   298  
   299  ```toml
   300  severity = "warning"
   301  confidence = 0.8
   302  errorCode = 0
   303  warningCode = 0
   304  
   305  # Enable all available rules
   306  enableAllRules = true
   307  
   308  # Disabled rules
   309  [rule.blank-imports]
   310      Disabled = true
   311  [rule.file-header]
   312      Disabled = true
   313  [rule.max-public-structs]
   314      Disabled = true
   315  [rule.line-length-limit]
   316      Disabled = true
   317  [rule.function-length]
   318      Disabled = true
   319  
   320  # Rule tunning
   321  [rule.argument-limit]
   322      Arguments = [5]
   323  [rule.cyclomatic]
   324      Arguments = [10]
   325  [rule.cognitive-complexity]
   326      Arguments = [7]
   327  [rule.function-result-limit]
   328      Arguments = [3]
   329  ```
   330  
   331  ### Default Configuration
   332  
   333  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`).
   334  
   335  ```shell
   336  revive -config defaults.toml github.com/mgechev/revive
   337  ```
   338  
   339  This will use the configuration file `defaults.toml`, the `default` formatter, and will run linting over the `github.com/mgechev/revive` package.
   340  
   341  ### Custom Configuration
   342  
   343  ```shell
   344  revive -config config.toml -formatter friendly github.com/mgechev/revive
   345  ```
   346  
   347  This will use `config.toml`, the `friendly` formatter, and will run linting over the `github.com/mgechev/revive` package.
   348  
   349  ### Recommended Configuration
   350  
   351  The following snippet contains the recommended `revive` configuration that you can use in your project:
   352  
   353  ```toml
   354  ignoreGeneratedHeader = false
   355  severity = "warning"
   356  confidence = 0.8
   357  errorCode = 0
   358  warningCode = 0
   359  
   360  [rule.blank-imports]
   361  [rule.context-as-argument]
   362  [rule.context-keys-type]
   363  [rule.dot-imports]
   364  [rule.error-return]
   365  [rule.error-strings]
   366  [rule.error-naming]
   367  [rule.exported]
   368  [rule.if-return]
   369  [rule.increment-decrement]
   370  [rule.var-naming]
   371  [rule.var-declaration]
   372  [rule.package-comments]
   373  [rule.range]
   374  [rule.receiver-naming]
   375  [rule.time-naming]
   376  [rule.unexported-return]
   377  [rule.indent-error-flow]
   378  [rule.errorf]
   379  [rule.empty-block]
   380  [rule.superfluous-else]
   381  [rule.unused-parameter]
   382  [rule.unreachable-code]
   383  [rule.redefines-builtin-id]
   384  ```
   385  
   386  ## Available Rules
   387  
   388  List of all available rules. The rules ported from `golint` are left unchanged and indicated in the `golint` column.
   389  
   390  | Name                  | Config | Description                                                      | `golint` | Typed |
   391  | --------------------- | :----: | :--------------------------------------------------------------- | :------: | :---: |
   392  | [`context-keys-type`](./RULES_DESCRIPTIONS.md#context-key-types)   |  n/a   | Disallows the usage of basic types in `context.WithValue`.       |   yes    |  yes  |
   393  | [`time-naming`](./RULES_DESCRIPTIONS.md#time-naming)         |  n/a   | Conventions around the naming of time variables.                 |   yes    |  yes  |
   394  | [`var-declaration`](./RULES_DESCRIPTIONS.md#var-declaration)     |  n/a   | Reduces redundancies around variable declaration.                |   yes    |  yes  |
   395  | [`unexported-return`](./RULES_DESCRIPTIONS.md#unexported-return)   |  n/a   | Warns when a public return is from unexported type.              |   yes    |  yes  |
   396  | [`errorf`](./RULES_DESCRIPTIONS.md#errorf)              |  n/a   | Should replace `errors.New(fmt.Sprintf())` with `fmt.Errorf()`   |   yes    |  yes  |
   397  | [`blank-imports`](./RULES_DESCRIPTIONS.md#blank-imports)       |  n/a   | Disallows blank imports                                          |   yes    |  no   |
   398  | [`context-as-argument`](./RULES_DESCRIPTIONS.md#context-as-argument) |  n/a   | `context.Context` should be the first argument of a function.    |   yes    |  no   |
   399  | [`dot-imports`](./RULES_DESCRIPTIONS.md#dot-imports)         |  n/a   | Forbids `.` imports.                                             |   yes    |  no   |
   400  | [`error-return`](./RULES_DESCRIPTIONS.md#error-return)        |  n/a   | The error return parameter should be last.                       |   yes    |  no   |
   401  | [`error-strings`](./RULES_DESCRIPTIONS.md#error-strings)       |  n/a   | Conventions around error strings.                                |   yes    |  no   |
   402  | [`error-naming`](./RULES_DESCRIPTIONS.md#error-naming)        |  n/a   | Naming of error variables.                                       |   yes    |  no   |
   403  | [`exported`](./RULES_DESCRIPTIONS.md#exported)            |  n/a   | Naming and commenting conventions on exported symbols.           |   yes    |  no   |
   404  | [`if-return`](./RULES_DESCRIPTIONS.md#if-return)           |  n/a   | Redundant if when returning an error.                            |   yes    |  no   |
   405  | [`increment-decrement`](./RULES_DESCRIPTIONS.md#increment-decrement) |  n/a   | Use `i++` and `i--` instead of `i += 1` and `i -= 1`.            |   yes    |  no   |
   406  | [`var-naming`](./RULES_DESCRIPTIONS.md#var-naming)          |  whitelist & blacklist of initialisms   | Naming rules.                                                    |   yes    |  no   |
   407  | [`package-comments`](./RULES_DESCRIPTIONS.md#package-comments)    |  n/a   | Package commenting conventions.                                  |   yes    |  no   |
   408  | [`range`](./RULES_DESCRIPTIONS.md#range)               |  n/a   | Prevents redundant variables when iterating over a collection.   |   yes    |  no   |
   409  | [`receiver-naming`](./RULES_DESCRIPTIONS.md#receiver-naming)     |  n/a   | Conventions around the naming of receivers.                      |   yes    |  no   |
   410  | [`indent-error-flow`](./RULES_DESCRIPTIONS.md#indent-error-flow)   |  n/a   | Prevents redundant else statements.                              |   yes    |  no   |
   411  | [`argument-limit`](./RULES_DESCRIPTIONS.md#argument-limit)      |  int   | Specifies the maximum number of arguments a function can receive |    no    |  no   |
   412  | [`cyclomatic`](./RULES_DESCRIPTIONS.md#cyclomatic)          |  int   | Sets restriction for maximum Cyclomatic complexity.              |    no    |  no   |
   413  | [`max-public-structs`](./RULES_DESCRIPTIONS.md#max-public-structs)  |  int   | The maximum number of public structs in a file.                  |    no    |  no   |
   414  | [`file-header`](./RULES_DESCRIPTIONS.md#file-header)         | string | Header which each file should have.                              |    no    |  no   |
   415  | [`empty-block`](./RULES_DESCRIPTIONS.md#empty-block)         |  n/a   | Warns on empty code blocks                                       |    no    |  yes   |
   416  | [`superfluous-else`](./RULES_DESCRIPTIONS.md#superfluous-else)    |  n/a   | Prevents redundant else statements (extends [`indent-error-flow`](./RULES_DESCRIPTIONS.md#indent-error-flow)) |    no    |  no   |
   417  | [`confusing-naming`](./RULES_DESCRIPTIONS.md#confusing-naming)    |  n/a   | Warns on methods with names that differ only by capitalization   |    no    |  no   |
   418  | [`get-return`](./RULES_DESCRIPTIONS.md#get-return)          |  n/a   | Warns on getters that do not yield any result                    |    no    |  no   |
   419  | [`modifies-parameter`](./RULES_DESCRIPTIONS.md#modifies-parameter)  |  n/a   | Warns on assignments to function parameters                      |    no    |  no   |
   420  | [`confusing-results`](./RULES_DESCRIPTIONS.md#confusing-results)   |  n/a   | Suggests to name potentially confusing function results          |    no    |  no   |
   421  | [`deep-exit`](./RULES_DESCRIPTIONS.md#deep-exit)           |  n/a   | Looks for program exits in funcs other than `main()` or `init()` |    no    |  no   |
   422  | [`unused-parameter`](./RULES_DESCRIPTIONS.md#unused-parameter)    |  n/a   | Suggests to rename or remove unused function parameters          |    no    |  no   |
   423  | [`unreachable-code`](./RULES_DESCRIPTIONS.md#unreachable-code)    |  n/a   | Warns on unreachable code                                        |    no    |  no   |
   424  | [`add-constant`](./RULES_DESCRIPTIONS.md#add-constant)        |  map   | Suggests using constant for magic numbers and string literals    |    no    |  no   |
   425  | [`flag-parameter`](./RULES_DESCRIPTIONS.md#flag-parameter)      |  n/a   | Warns on boolean parameters that create a control coupling       |    no    |  no   |
   426  | [`unnecessary-stmt`](./RULES_DESCRIPTIONS.md#unnecessary-stmt)    |  n/a   | Suggests removing or simplifying unnecessary statements          |    no    |  no   |
   427  | [`struct-tag`](./RULES_DESCRIPTIONS.md#struct-tag)          |  n/a   | Checks common struct tags like `json`,`xml`,`yaml`               |    no    |  no   |
   428  | [`modifies-value-receiver`](./RULES_DESCRIPTIONS.md#modifies-value-receiver) |  n/a   | Warns on assignments to value-passed method receivers        |    no    |  yes  |
   429  | [`constant-logical-expr`](./RULES_DESCRIPTIONS.md#constant-logical-expr)   |  n/a   | Warns on constant logical expressions                        |    no    |  no   |
   430  | [`bool-literal-in-expr`](./RULES_DESCRIPTIONS.md#bool-literal-in-expr)|  n/a   | Suggests removing Boolean literals from logic expressions        |    no    |  no   |
   431  | [`redefines-builtin-id`](./RULES_DESCRIPTIONS.md#redefines-builtin-id)|  n/a   | Warns on redefinitions of builtin identifiers                    |    no    |  no   |
   432  | [`function-result-limit`](./RULES_DESCRIPTIONS.md#function-result-limit) |  int | Specifies the maximum number of results a function can return    |    no    |  no   |
   433  | [`imports-blacklist`](./RULES_DESCRIPTIONS.md#imports-blacklist)   | []string | Disallows importing the specified packages                     |    no    |  no   |
   434  | [`range-val-in-closure`](./RULES_DESCRIPTIONS.md#range-val-in-closure)|  n/a   | Warns if range value is used in a closure dispatched as goroutine|    no    |  no   |
   435  | [`range-val-address`](./RULES_DESCRIPTIONS.md#range-val-address)|  n/a   | Warns if address of range value is used dangerously |    no    |  no   |
   436  | [`waitgroup-by-value`](./RULES_DESCRIPTIONS.md#waitgroup-by-value)  |  n/a   | Warns on functions taking sync.WaitGroup as a by-value parameter |    no    |  no   |
   437  | [`atomic`](./RULES_DESCRIPTIONS.md#atomic)              |  n/a   | Check for common mistaken usages of the `sync/atomic` package    |    no    |  no   |
   438  | [`empty-lines`](./RULES_DESCRIPTIONS.md#empty-lines)   | n/a | Warns when there are heading or trailing newlines in a block              |    no    |  no   |
   439  | [`line-length-limit`](./RULES_DESCRIPTIONS.md#line-length-limit)   | int    | Specifies the maximum number of characters in a line             |    no    |  no   |
   440  | [`call-to-gc`](./RULES_DESCRIPTIONS.md#call-to-gc)   | n/a    | Warns on explicit call to the garbage collector    |    no    |  no   |
   441  | [`duplicated-imports`](./RULES_DESCRIPTIONS.md#duplicated-imports) | n/a  | Looks for packages that are imported two or more times   |    no    |  no   |
   442  | [`import-shadowing`](./RULES_DESCRIPTIONS.md#import-shadowing)   | n/a    | Spots identifiers that shadow an import    |    no    |  no   |
   443  | [`bare-return`](./RULES_DESCRIPTIONS.md#bare-return) | n/a  | Warns on bare returns   |    no    |  no   |
   444  | [`unused-receiver`](./RULES_DESCRIPTIONS.md#unused-receiver)   | n/a    | Suggests to rename or remove unused method receivers    |    no    |  no   |
   445  | [`unhandled-error`](./RULES_DESCRIPTIONS.md#unhandled-error)   | []string   | Warns on unhandled errors returned by funcion calls    |    no    |  yes   |
   446  | [`cognitive-complexity`](./RULES_DESCRIPTIONS.md#cognitive-complexity)          |  int   | Sets restriction for maximum Cognitive complexity.              |    no    |  no   |
   447  | [`string-of-int`](./RULES_DESCRIPTIONS.md#string-of-int)          |  n/a   | Warns on suspicious casts from int to string            |    no    |  yes   |
   448  | [`string-format`](./RULES_DESCRIPTIONS.md#string-format)          |  map   | Warns on specific string literals that fail one or more user-configured regular expressions            |    no    |  no   |
   449  | [`early-return`](./RULES_DESCRIPTIONS.md#early-return)          |  n/a   | Spots if-then-else statements that can be refactored to simplify code reading            |    no    |  no   |
   450  | [`unconditional-recursion`](./RULES_DESCRIPTIONS.md#unconditional-recursion)          |  n/a   | Warns on function calls that will lead to (direct) infinite recursion |    no    |  no   |
   451  | [`identical-branches`](./RULES_DESCRIPTIONS.md#identical-branches)          |  n/a   | Spots if-then-else statements with identical `then` and `else` branches       |    no    |  no   |
   452  | [`defer`](./RULES_DESCRIPTIONS.md#defer)          |  map   |  Warns on some [defer gotchas](https://blog.learngoprogramming.com/5-gotchas-of-defer-in-go-golang-part-iii-36a1ab3d6ef1)       |    no    |  no   |
   453  | [`unexported-naming`](./RULES_DESCRIPTIONS.md#unexported-naming)          |  n/a   |  Warns on wrongly named un-exported symbols       |    no    |  no   |
   454  | [`function-length`](./RULES_DESCRIPTIONS.md#function-length)          |  n/a   |  Warns on functions exceeding the statements or lines max |    no    |  no   |
   455  | [`nested-structs`](./RULES_DESCRIPTIONS.md#nested-structs)          |  n/a   |  Warns on structs within structs |    no    |  no   |
   456  
   457  ## Configurable rules
   458  
   459  Here you can find how you can configure some of the existing rules:
   460  
   461  ### `var-naming`
   462  
   463  This rule accepts two slices of strings, a whitelist and a blacklist of initialisms. By default the rule behaves exactly as the alternative in `golint` but optionally, you can relax it (see [golint/lint/issues/89](https://github.com/golang/lint/issues/89))
   464  
   465  ```toml
   466  [rule.var-naming]
   467    arguments = [["ID"], ["VM"]]
   468  ```
   469  
   470  This way, revive will not warn for identifier called `customId` but will warn that `customVm` should be called `customVM`.
   471  
   472  ## Available Formatters
   473  
   474  This section lists all the available formatters and provides a screenshot for each one.
   475  
   476  ### Friendly
   477  
   478  ![Friendly formatter](/assets/formatter-friendly.png)
   479  
   480  ### Stylish
   481  
   482  ![Stylish formatter](/assets/formatter-stylish.png)
   483  
   484  ### Default
   485  
   486  The default formatter produces the same output as `golint`.
   487  
   488  ![Default formatter](/assets/formatter-default.png)
   489  
   490  ### Plain
   491  
   492  The plain formatter produces the same output as the default formatter and appends URL to the rule description.
   493  
   494  ![Plain formatter](/assets/formatter-plain.png)
   495  
   496  ### Unix
   497  
   498  The unix formatter produces the same output as the default formatter but surrounds the rules in `[]`.
   499  
   500  ![Unix formatter](/assets/formatter-unix.png)
   501  
   502  ### SARIF
   503  The `sarif`  formatter produces outputs in SARIF, for _Static Analysis Results Interchange Format_, a standard JSON-based format for the output of static analysis tools defined and promoted by [OASIS](https://www.oasis-open.org/).
   504  
   505  Current supported version of the standard is [SARIF-v2.1.0](https://docs.oasis-open.org/sarif/sarif/v2.1.0/csprd01/sarif-v2.1.0-csprd01.html
   506  ).
   507  
   508  ## Extensibility
   509  
   510  The tool can be extended with custom rules or formatters. This section contains additional information on how to implement such.
   511  
   512  **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/).
   513  
   514  ### Custom Rule
   515  
   516  Each rule needs to implement the `lint.Rule` interface:
   517  
   518  ```go
   519  type Rule interface {
   520  	Name() string
   521  	Apply(*File, Arguments) []Failure
   522  }
   523  ```
   524  
   525  The `Arguments` type is an alias of the type `[]interface{}`. The arguments of the rule are passed from the configuration file.
   526  
   527  #### Example
   528  
   529  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:
   530  
   531  ```toml
   532  [rule.ban-struct-name]
   533    arguments = ["Foo"]
   534  ```
   535  
   536  With the snippet above we:
   537  
   538  - Enable the rule with name `ban-struct-name`. The `Name()` method of our rule should return a string which matches `ban-struct-name`.
   539  - 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.
   540  
   541  A sample rule implementation can be found [here](/rule/argument-limit.go).
   542  
   543  ### Custom Formatter
   544  
   545  Each formatter needs to implement the following interface:
   546  
   547  ```go
   548  type Formatter interface {
   549  	Format(<-chan Failure, Config) (string, error)
   550  	Name() string
   551  }
   552  ```
   553  
   554  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.
   555  
   556  For a sample formatter, take a look at [this file](/formatter/json.go).
   557  
   558  ## Speed Comparison
   559  
   560  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:
   561  
   562  ### golint
   563  
   564  ```shell
   565  time golint kubernetes/... > /dev/null
   566  
   567  real    0m54.837s
   568  user    0m57.844s
   569  sys     0m9.146s
   570  ```
   571  
   572  ### revive
   573  
   574  ```shell
   575  # no type checking
   576  time revive -config untyped.toml kubernetes/... > /dev/null
   577  
   578  real    0m8.471s
   579  user    0m40.721s
   580  sys     0m3.262s
   581  ```
   582  
   583  Keep in mind that if you use rules which require type checking, the performance may drop to 2x faster than `golint`:
   584  
   585  ```shell
   586  # type checking enabled
   587  time revive kubernetes/... > /dev/null
   588  
   589  real    0m26.211s
   590  user    2m6.708s
   591  sys     0m17.192s
   592  ```
   593  
   594  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.
   595  
   596  ## Overriding colorization detection
   597  
   598  By default, `revive` determines whether or not to colorize its output based on whether it's connected to a TTY or not.
   599  This works for most use cases, but may not behave as expected if you use `revive` in a pipeline of commands,
   600  where STDOUT is being piped to another command.
   601  
   602  To force colorization, add `REVIVE_FORCE_COLOR=1` to the environment you're running in. For example:
   603  
   604  ```shell
   605  REVIVE_FORCE_COLOR=1 revive -formatter friendly ./... | tee revive.log
   606  ```
   607  
   608  ## Contributors
   609  
   610  [<img alt="mgechev" src="https://avatars.githubusercontent.com/u/455023?v=4&s=117" width="117">](https://github.com/mgechev) |[<img alt="chavacava" src="https://avatars.githubusercontent.com/u/25788468?v=4&s=117" width="117">](https://github.com/chavacava) |[<img alt="renovate-bot" src="https://avatars.githubusercontent.com/u/25180681?v=4&s=117" width="117">](https://github.com/renovate-bot) |[<img alt="xuri" src="https://avatars.githubusercontent.com/u/2809468?v=4&s=117" width="117">](https://github.com/xuri) |[<img alt="morphy2k" src="https://avatars.githubusercontent.com/u/4280578?v=4&s=117" width="117">](https://github.com/morphy2k) |[<img alt="dshemin" src="https://avatars.githubusercontent.com/u/11780307?v=4&s=117" width="117">](https://github.com/dshemin) |
   611  :---: |:---: |:---: |:---: |:---: |:---: |
   612  [mgechev](https://github.com/mgechev) |[chavacava](https://github.com/chavacava) |[renovate-bot](https://github.com/renovate-bot) |[xuri](https://github.com/xuri) |[morphy2k](https://github.com/morphy2k) |[dshemin](https://github.com/dshemin) |
   613  
   614  [<img alt="Clivern" src="https://avatars.githubusercontent.com/u/1634427?v=4&s=117" width="117">](https://github.com/Clivern) |[<img alt="gsamokovarov" src="https://avatars.githubusercontent.com/u/604618?v=4&s=117" width="117">](https://github.com/gsamokovarov) |[<img alt="tymonx" src="https://avatars.githubusercontent.com/u/8367378?v=4&s=117" width="117">](https://github.com/tymonx) |[<img alt="bernhardreisenberger" src="https://avatars.githubusercontent.com/u/5809300?v=4&s=117" width="117">](https://github.com/bernhardreisenberger) |[<img alt="markelog" src="https://avatars.githubusercontent.com/u/945528?v=4&s=117" width="117">](https://github.com/markelog) |[<img alt="tamird" src="https://avatars.githubusercontent.com/u/1535036?v=4&s=117" width="117">](https://github.com/tamird) |
   615  :---: |:---: |:---: |:---: |:---: |:---: |
   616  [Clivern](https://github.com/Clivern) |[gsamokovarov](https://github.com/gsamokovarov) |[tymonx](https://github.com/tymonx) |[bernhardreisenberger](https://github.com/bernhardreisenberger) |[markelog](https://github.com/markelog) |[tamird](https://github.com/tamird) |
   617  
   618  [<img alt="mapreal19" src="https://avatars.githubusercontent.com/u/3055997?v=4&s=117" width="117">](https://github.com/mapreal19) |[<img alt="Aragur" src="https://avatars.githubusercontent.com/u/11004008?v=4&s=117" width="117">](https://github.com/Aragur) |[<img alt="s0xzwasd" src="https://avatars.githubusercontent.com/u/29286703?v=4&s=117" width="117">](https://github.com/s0xzwasd) |[<img alt="yangdiangzb" src="https://avatars.githubusercontent.com/u/16643665?v=4&s=117" width="117">](https://github.com/yangdiangzb) |[<img alt="petethepig" src="https://avatars.githubusercontent.com/u/662636?v=4&s=117" width="117">](https://github.com/petethepig) |[<img alt="quasilyte" src="https://avatars.githubusercontent.com/u/6286655?v=4&s=117" width="117">](https://github.com/quasilyte) |
   619  :---: |:---: |:---: |:---: |:---: |:---: |
   620  [mapreal19](https://github.com/mapreal19) |[Aragur](https://github.com/Aragur) |[s0xzwasd](https://github.com/s0xzwasd) |[yangdiangzb](https://github.com/yangdiangzb) |[petethepig](https://github.com/petethepig) |[quasilyte](https://github.com/quasilyte) |
   621  
   622  [<img alt="grongor" src="https://avatars.githubusercontent.com/u/972493?v=4&s=117" width="117">](https://github.com/grongor) |[<img alt="jamesmaidment" src="https://avatars.githubusercontent.com/u/2050324?v=4&s=117" width="117">](https://github.com/jamesmaidment) |[<img alt="johnrichardrinehart" src="https://avatars.githubusercontent.com/u/6321578?v=4&s=117" width="117">](https://github.com/johnrichardrinehart) |[<img alt="very-amused" src="https://avatars.githubusercontent.com/u/44382255?v=4&s=117" width="117">](https://github.com/very-amused) |[<img alt="mathieu-aubin" src="https://avatars.githubusercontent.com/u/15820228?v=4&s=117" width="117">](https://github.com/mathieu-aubin) |[<img alt="michalhisim" src="https://avatars.githubusercontent.com/u/764249?v=4&s=117" width="117">](https://github.com/michalhisim) |
   623  :---: |:---: |:---: |:---: |:---: |:---: |
   624  [grongor](https://github.com/grongor) |[jamesmaidment](https://github.com/jamesmaidment) |[johnrichardrinehart](https://github.com/johnrichardrinehart) |[very-amused](https://github.com/very-amused) |[mathieu-aubin](https://github.com/mathieu-aubin) |[michalhisim](https://github.com/michalhisim) |
   625  
   626  [<img alt="pa-m" src="https://avatars.githubusercontent.com/u/5503106?v=4&s=117" width="117">](https://github.com/pa-m) |[<img alt="paul-at-start" src="https://avatars.githubusercontent.com/u/5486775?v=4&s=117" width="117">](https://github.com/paul-at-start) |[<img alt="paco0x" src="https://avatars.githubusercontent.com/u/6123425?v=4&s=117" width="117">](https://github.com/paco0x) |[<img alt="ridvansumset" src="https://avatars.githubusercontent.com/u/26631560?v=4&s=117" width="117">](https://github.com/ridvansumset) |[<img alt="Jarema" src="https://avatars.githubusercontent.com/u/7369771?v=4&s=117" width="117">](https://github.com/Jarema) |[<img alt="vkrol" src="https://avatars.githubusercontent.com/u/153412?v=4&s=117" width="117">](https://github.com/vkrol) |
   627  :---: |:---: |:---: |:---: |:---: |:---: |
   628  [pa-m](https://github.com/pa-m) |[paul-at-start](https://github.com/paul-at-start) |[paco0x](https://github.com/paco0x) |[ridvansumset](https://github.com/ridvansumset) |[Jarema](https://github.com/Jarema) |[vkrol](https://github.com/vkrol) |
   629  
   630  [<img alt="haya14busa" src="https://avatars.githubusercontent.com/u/3797062?v=4&s=117" width="117">](https://github.com/haya14busa) |[<img alt="sina-devel" src="https://avatars.githubusercontent.com/u/61763643?v=4&s=117" width="117">](https://github.com/sina-devel) |[<img alt="techknowlogick" src="https://avatars.githubusercontent.com/u/164197?v=4&s=117" width="117">](https://github.com/techknowlogick) |
   631  :---: |:---: |:---: |
   632  [haya14busa](https://github.com/haya14busa) |[sina-devel](https://github.com/sina-devel) |[techknowlogick](https://github.com/techknowlogick) |
   633  
   634  ## License
   635  
   636  MIT