🔥 ~6x faster, stricter, configurable, extensible, and beautiful drop-in replacement for golint

Overview

Build Status

revive

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.


Logo by Georgi Serev

Here's how revive is different from golint:

  • Allows to enable or disable rules using a configuration file.
  • Allows 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 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.

Who uses Revive

  • tidb - TiDB is a distributed HTAP database compatible with the MySQL protocol
  • grafana - The tool for beautiful monitoring and metric analytics & dashboards for Graphite, InfluxDB & Prometheus & More
  • etcd - Distributed reliable key-value store for the most critical data of a distributed system
  • ferret - Declarative web scraping
  • gopass - The slightly more awesome standard unix password manager for teams
  • gitea - Git with a cup of tea, painless self-hosted git service
  • excelize - Go library for reading and writing Microsoft Excel™ (XLSX) files
  • aurora - aurora is a web-based Beanstalk queue server console written in Go
  • soar - SQL Optimizer And Rewriter
  • gorush - A push notification server written in Go (Golang)a
  • dry - dry - A Docker manager for the terminal.
  • go-echarts - The adorable charts library for Golang
  • reviewdog - Automated code review tool integrated with any code analysis tools regardless of programming language
  • rudder-server - Privacy and Security focused Segment-alternative, in Golang and React.
  • sklearn - A partial port of scikit-learn written in Go.
  • protoc-gen-doc - Documentation generator plugin for Google Protocol Buffers.
  • llvm - Library for interacting with LLVM IR in pure Go.
  • jenkins-library - Jenkins shared library for Continuous Delivery pipelines by SAP.
  • pd - Placement driver for TiKV.
  • shellhub - ShellHub enables teams to easily access any Linux device behind firewall and NAT.
  • lorawan-stack - The Things Network Stack for LoRaWAN V3
  • gin-jwt - This is a JWT middleware for Gin framework.
  • gofight - Testing API Handler written in Golang.
  • Beaver - A Real Time Messaging Server.
  • ggz - An URL shortener service written in Golang
  • Codeac.io - Automated code review service integrates with GitHub, Bitbucket and GitLab (even self-hosted) and helps you fight technical debt.

Open a PR to add your project.

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.

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.

Bazel

If you want to use revive with Bazel, take a look at the rules that Atlassian maintains.

Text Editors

let g:ale_linters = {
\   'go': ['revive'],
\}

GitHub Actions

Continuous Integration

Codeac.io - Automated code review service integrates with GitHub, Bitbucket and GitLab (even self-hosted) and helps you fight technical debt. Check your pull-requests with revive automatically. (free for open-source projects)

Installation

go get -u github.com/mgechev/revive

Command Line Flags

revive accepts three command line parameters:

  • -config [PATH] - path to config file in TOML format, defaults to $HOME/revive.toml if present.

  • -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.
    • ndjson - outputs the failures as stream in newline delimited JSON (NDJSON) 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.
    • checkstyle - outputs the failures in XML format compatible with that of Java's Checkstyle.

Sample Invocations

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

Comment Directives

Using comments, you can disable the linter for the entire file or only range of lines:

//revive:disable

func Public() {}
//revive:enable

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.

With revive:disable-next-line and revive:disable-line you can disable revive on a particular code line.

You can do the same on a rule level. In case you want to disable only a particular rule, you can use:

//revive:disable:unexported-return
func Public() private {
  return private
}
//revive:enable:unexported-return

This way, revive will not warn you for that you're returning an object of an unexported type, from an exported function.

You can document why you disable the linter by adding a trailing text in the directive, for example

//revive:disable Until the code is stable
//revive:disable:cyclomatic High complexity score but easy to understand

You can also configure revive to enforce documenting linter disabling directives by adding

[directive.specify-disable-reason]

in the configuration. You can set the severity (defaults to warning) of the violation of this directive

[directive.specify-disable-reason]
    severity = "error"

Configuration

revive can be configured with a TOML file. Here's a sample configuration with explanation for the individual properties:

# When set to false, 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"

Default Configuration

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/revive

This will use the configuration file defaults.toml, the default formatter, and will run linting over the github.com/mgechev/revive package.

Custom Configuration

revive -config config.toml -formatter friendly github.com/mgechev/revive

This will use config.toml, the friendly formatter, and will run linting over the github.com/mgechev/revive package.

Recommended Configuration

The following snippet contains the recommended revive configuration that you can use in your project:

ignoreGeneratedHeader = false
severity = "warning"
confidence = 0.8
errorCode = 0
warningCode = 0

[rule.blank-imports]
[rule.context-as-argument]
[rule.context-keys-type]
[rule.dot-imports]
[rule.error-return]
[rule.error-strings]
[rule.error-naming]
[rule.exported]
[rule.if-return]
[rule.increment-decrement]
[rule.var-naming]
[rule.var-declaration]
[rule.package-comments]
[rule.range]
[rule.receiver-naming]
[rule.time-naming]
[rule.unexported-return]
[rule.indent-error-flow]
[rule.errorf]
[rule.empty-block]
[rule.superfluous-else]
[rule.unused-parameter]
[rule.unreachable-code]
[rule.redefines-builtin-id]

Available Rules

List of all available rules. The rules ported from golint are left unchanged and indicated in the golint column.

Name Config Description golint Typed
context-keys-type n/a Disallows the usage of basic types in context.WithValue. yes yes
time-naming n/a Conventions around the naming of time variables. yes yes
var-declaration n/a Reduces redundancies around variable declaration. yes yes
unexported-return n/a Warns when a public return is from unexported type. yes yes
errorf n/a Should replace errors.New(fmt.Sprintf()) with fmt.Errorf() yes yes
blank-imports n/a Disallows blank imports yes no
context-as-argument n/a context.Context should be the first argument of a function. yes no
dot-imports n/a Forbids . imports. yes no
error-return n/a The error return parameter should be last. yes no
error-strings n/a Conventions around error strings. yes no
error-naming n/a Naming of error variables. yes no
exported n/a Naming and commenting conventions on exported symbols. yes no
if-return n/a Redundant if when returning an error. yes no
increment-decrement n/a Use i++ and i-- instead of i += 1 and i -= 1. yes no
var-naming whitelist & blacklist of initialisms Naming rules. yes no
package-comments n/a Package commenting conventions. yes no
range n/a Prevents redundant variables when iterating over a collection. yes no
receiver-naming n/a Conventions around the naming of receivers. yes no
indent-error-flow n/a Prevents redundant else statements. yes no
argument-limit int Specifies the maximum number of arguments a function can receive no no
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 yes
superfluous-else n/a Prevents redundant else statements (extends indent-error-flow) no no
confusing-naming n/a Warns on methods with names that differ only by capitalization no no
get-return n/a Warns on getters that do not yield any result no no
modifies-parameter n/a Warns on assignments to function parameters no no
confusing-results n/a Suggests to name potentially confusing function results no no
deep-exit n/a Looks for program exits in funcs other than main() or init() no no
unused-parameter n/a Suggests to rename or remove unused function parameters no no
unreachable-code n/a Warns on unreachable code no no
add-constant map Suggests using constant for magic numbers and string literals no no
flag-parameter n/a Warns on boolean parameters that create a control coupling no no
unnecessary-stmt n/a Suggests removing or simplifying unnecessary statements no no
struct-tag n/a Checks common struct tags like json,xml,yaml no no
modifies-value-receiver n/a Warns on assignments to value-passed method receivers no yes
constant-logical-expr n/a Warns on constant logical expressions no no
bool-literal-in-expr n/a Suggests removing Boolean literals from logic expressions no no
redefines-builtin-id n/a Warns on redefinitions of builtin identifiers no no
function-result-limit int Specifies the maximum number of results a function can return no no
imports-blacklist []string Disallows importing the specified packages no no
range-val-in-closure n/a Warns if range value is used in a closure dispatched as goroutine no no
range-val-address n/a Warns if address of range value is used dangerously no no
waitgroup-by-value n/a Warns on functions taking sync.WaitGroup as a by-value parameter no no
atomic n/a Check for common mistaken usages of the sync/atomic package no no
empty-lines n/a Warns when there are heading or trailing newlines in a block no no
line-length-limit int Specifies the maximum number of characters in a line no no
call-to-gc n/a Warns on explicit call to the garbage collector no no
duplicated-imports n/a Looks for packages that are imported two or more times no no
import-shadowing n/a Spots identifiers that shadow an import no no
bare-return n/a Warns on bare returns no no
unused-receiver n/a Suggests to rename or remove unused method receivers no no
unhandled-error []string Warns on unhandled errors returned by funcion calls no yes
cognitive-complexity int Sets restriction for maximum Cognitive complexity. no no
string-of-int n/a Warns on suspicious casts from int to string no yes
early-return n/a Spots if-then-else statements that can be refactored to simplify code reading no no
unconditional-recursion n/a Warns on function calls that will lead to (direct) infinite recursion no no
identical-branches n/a Spots if-then-else statements with identical then and else branches no no
defer map Warns on some defer gotchas no no
unexported-naming n/a Warns on wrongly named un-exported symbols no no
function-length n/a Warns on functions exceeding the statements or lines max no no

Configurable rules

Here you can find how you can configure some of the existing rules:

var-naming

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)

[rule.var-naming]
  arguments = [["ID"], ["VM"]]

This way, revive will not warn for identifier called customId but will warn that customVm should be called customVM.

Available Formatters

This section lists all the available formatters and provides a screenshot for each one.

Friendly

Friendly formatter

Stylish

Stylish formatter

Default

The default formatter produces the same output as golint.

Default formatter

Plain

The plain formatter produces the same output as the default formatter and appends URL to the rule description.

Plain formatter

Unix

The unix formatter produces the same output as the default formatter but surrounds the rules in [].

Unix formatter

Extensibility

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).

Custom Rule

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.

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:

[rule.ban-struct-name]
  arguments = ["Foo"]

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.

A sample rule implementation can be found here.

Custom Formatter

Each formatter needs to implement the following interface:

type Formatter interface {
	Format(<-chan Failure, Config) (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.

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

time golint kubernetes/... > /dev/null

real    0m54.837s
user    0m57.844s
sys     0m9.146s

revive

# no type checking
time revive -config untyped.toml kubernetes/... > /dev/null

real    0m8.471s
user    0m40.721s
sys     0m3.262s

Keep in mind that if you use rules which require type checking, the performance may drop to 2x faster than golint:

# type checking enabled
time revive kubernetes/... > /dev/null

real    0m26.211s
user    2m6.708s
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.

Overriding colorization detection

By default, revive determines whether or not to colorize its output based on whether it's connected to a TTY or not. This works for most use cases, but may not behave as expected if you use revive in a pipeline of commands, where STDOUT is being piped to another command.

To force colorization, add REVIVE_FORCE_COLOR=1 to the environment you're running in. For example:

REVIVE_FORCE_COLOR=1 revive -formatter friendly ./... | tee revive.log

Contributors

mgechev chavacava renovate-bot xuri dshemin gsamokovarov
mgechev chavacava renovate-bot xuri dshemin gsamokovarov
morphy2k tymonx markelog tamird mapreal19 Clivern
morphy2k tymonx markelog tamird mapreal19 Clivern
AragurDEV bernhardreisenberger yangdiangzb quasilyte jamesmaidment johnrichardrinehart
AragurDEV bernhardreisenberger yangdiangzb quasilyte jamesmaidment johnrichardrinehart
mathieu-aubin michalhisim pa-m paul-at-start liaoishere ridvansumset
mathieu-aubin michalhisim pa-m paul-at-start liaoishere ridvansumset
Jarema vkrol haya14busa
Jarema vkrol haya14busa

License

MIT

Issues
  • Add SemVer releases

    Add SemVer releases

    Is your feature request related to a problem? Please describe. The idiomatic way to create software is to publish releases when required (fix, new feature, api break...). There is currently no versioning for revive.

    Describe the solution you'd like

    I would like to suggest https://github.com/astrocorp42/rocket to automate GitHub releases. Thus We can automate releasing and binaries publishing. Furthermore it would enable automated Docker publishing which is great for users of services like drone.io.

    It would requires a Makefile (for example: https://github.com/astrocorp42/rocket/blob/master/Makefile), to build revive.

    Describe alternatives you've considered https://github.com/goreleaser/goreleaser but it mix too many things (build + publishing).

    opened by skerkour 18
  • blank-imports and constant-logical-error do not support cgo

    blank-imports and constant-logical-error do not support cgo

    Describe the bug When using CGO an import "C" is required to active cgo (and import/define C code). The blank-imports check does not accept this and throws the following warning:

    blank-imports: a blank import should be only in a main or test package, or have a comment justifying it (revive)

    To Reproduce

    Consider this main.go file:

    package main
    
    import "unsafe"
    
    // #include <stdlib.h>
    import "C"
    
    func main() {
    	cStr := C.CString("test")
    
    	C.free(unsafe.Pointer(cStr))
    }
    

    Run revive for this file and the waring appears for the import "C" line.

    Expected behavior There should not be a warning for this file.

    Desktop (please complete the following information):

    • OS: Arch Linux
    • go version go1.17.7 linux/amd64
    opened by veger 17
  • Package-wide analysis

    Package-wide analysis

    Hi @mgechev, I would love to develop some rules that need package-wide analysis (e.g. unused-function) but I do not see how to implement the analysis pattern required by these kind of rules.

    I've developed one package-wide rule (confusing-naming). A raw description of the rule is: create a global registry of names, and for each linted file: a) enrich that list, and b) check new names vs those in the list. Because two names are similar (confusing) no matter the order in which we find them, checks are independent of: the order in which package files are analyzed, and the global progress of the analysis.

    That is not the case of, for example, unused-function: checks can be done only when all files in the package were analyzed (it is not possible to flag a function as unused until all files of the package have been analyzed). These kind of rules need something like a reduce phase after been applied to all package's files.

    My understanding is that rules are applied as follows:

    for each file in the package
      go { 
        for each rule
          rule.Apply(file)
        send failures
      }
    

    Files are concurrently analyzed (and that is good :+1: ), thus at rule-level it is impossible to have information of the global (package-level) progress of the analysis.

    Is my understanding wrong? Do you see how to implement a rule like unused-function without modifying the linter logic?

    opened by chavacava 17
  • panic: unable to type check

    panic: unable to type check

    Describe the bug We've seen a transient panic in revive in our CI job (it did not occur when the job was retried).

    revive -exclude vendor/... -formatter friendly -config .revive.toml ./...
     panic: unable to type check [redacted file A]:[redacted file A]:3:8: could not import [redacted pkg B] (can't find import: [redacted pkg B])
     goroutine 123 [running]:
     github.com/mgechev/revive/rule.(*EmptyBlockRule).Apply(0x9e06d0, 0xc000f70b80, 0x0, 0x0, 0x0, 0x9e06d0, 0x0, 0x0)
        /go/src/github.com/mgechev/revive/rule/empty-block.go:23 +0x20e
     github.com/mgechev/revive/lint.(*File).lint(0xc000f70b80, 0xc0003b6800, 0x27, 0x40, 0x0, 0x3fd0000000000000, 0xc000030a40, 0x7, 0xc00007dfb0, 0x1, ...)
        /go/src/github.com/mgechev/revive/lint/file.go:108 +0x3b6
     github.com/mgechev/revive/lint.(*Package).lint.func1(0xc0003b6800, 0x27, 0x40, 0x0, 0x3fd0000000000000, 0xc000030a40, 0x7, 0xc00007dfb0, 0x1, 0x1, ...)
        /go/src/github.com/mgechev/revive/lint/package.go:173 +0xb5
     created by github.com/mgechev/revive/lint.(*Package).lint
        /go/src/github.com/mgechev/revive/lint/package.go:172 +0x179
    

    https://github.com/mgechev/revive/blob/1da965b65f8a0e3aa83cd9d6d38153a32f308960/rule/empty-block.go#L23

    To Reproduce

    I couldn't reproduce the issue - it worked when I retried the job. Could it have been caused by some network issue when getting the package from our internal git repo?

    Expected behavior Expected to see better error message describing why it couldn't find the import.

    Desktop (please complete the following information):

    • Version of Go: 1.14.2
    opened by martin-sucha 16
  • panic: assertion failed [recovered]

    panic: assertion failed [recovered]

    Describe the bug revive panics.

    To Reproduce Steps to reproduce the behavior:

    1. I updated revive go get -u github.com/mgechev/revive
    2. I run it with the following flags & configuration file:
    # flags
    
    ~/.gotools/bin/revive -config=$HOME/.revive.toml ./...
    
    # config file
    ignoreGeneratedHeader = false
    severity = "warning"
    confidence = 0.8
    errorCode = 0
    warningCode = 0
    
    [rule.blank-imports]
    [rule.context-as-argument]
    [rule.context-keys-type]
    [rule.dot-imports]
    [rule.error-return]
    [rule.error-strings]
    [rule.error-naming]
    #[rule.exported]
    [rule.if-return]
    [rule.increment-decrement]
    #[rule.var-naming]
    [rule.var-declaration]
    [rule.package-comments]
    [rule.range]
    #[rule.receiver-naming]
    [rule.time-naming]
    [rule.unexported-return]
    [rule.indent-error-flow]
    [rule.errorf]
    

    Expected behavior No panic.

    Logs

    [...]
    vendor/github.com/apache/thrift/lib/go/thrift/server_socket.go:92:9: if block ends with a return statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary)
    panic: assertion failed [recovered]
    	panic: assertion failed
    
    goroutine 1315 [running]:
    go/types.(*Checker).handleBailout(0xc0005b6870, 0xc008cab800)
    	/usr/local/go/src/go/types/check.go:236 +0x98
    panic(0x12b3600, 0x1370730)
    	/usr/local/go/src/runtime/panic.go:513 +0x1b9
    go/types.assert(...)
    	/usr/local/go/src/go/types/errors.go:18
    go/types.(*Checker).recordTypeAndValue(0xc0005b6870, 0x0, 0x0, 0x3, 0x1374960, 0xc02fead160, 0x0, 0x0)
    	/usr/local/go/src/go/types/check.go:281 +0x279
    go/types.(*Checker).exprInternal(0xc0005b6870, 0xc02fed4e00, 0x13755a0, 0xc00a1ca800, 0x1374960, 0xc02fead160, 0x100b3c3)
    	/usr/local/go/src/go/types/expr.go:1164 +0x17c4
    go/types.(*Checker).rawExpr(0xc0005b6870, 0xc02fed4e00, 0x13755a0, 0xc00a1ca800, 0x1374960, 0xc02fead160, 0x100ba38)
    	/usr/local/go/src/go/types/expr.go:969 +0x81
    go/types.(*Checker).exprWithHint(0xc0005b6870, 0xc02fed4e00, 0x13755a0, 0xc00a1ca800, 0x1374960, 0xc02fead160)
    	/usr/local/go/src/go/types/expr.go:1597 +0x73
    go/types.(*Checker).indexedElts(0xc0005b6870, 0xc005257a00, 0x1c, 0x20, 0x1374960, 0xc02fead160, 0xffffffffffffffff, 0x1374960)
    	/usr/local/go/src/go/types/expr.go:939 +0x1e2
    go/types.(*Checker).exprInternal(0xc0005b6870, 0xc02fed4d00, 0x13755a0, 0xc00a1cb600, 0x0, 0x0, 0x101e728)
    	/usr/local/go/src/go/types/expr.go:1158 +0x1759
    go/types.(*Checker).rawExpr(0xc0005b6870, 0xc02fed4d00, 0x13755a0, 0xc00a1cb600, 0x0, 0x0, 0xc00028cd80)
    	/usr/local/go/src/go/types/expr.go:969 +0x81
    go/types.(*Checker).multiExpr(0xc0005b6870, 0xc02fed4d00, 0x13755a0, 0xc00a1cb600)
    	/usr/local/go/src/go/types/expr.go:1575 +0x58
    go/types.(*Checker).expr(0xc0005b6870, 0xc02fed4d00, 0x13755a0, 0xc00a1cb600)
    	/usr/local/go/src/go/types/expr.go:1569 +0x49
    go/types.(*Checker).varDecl(0xc0005b6870, 0xc011a03180, 0xc01ca5d008, 0x1, 0x1, 0x0, 0x0, 0x13755a0, 0xc00a1cb600)
    	/usr/local/go/src/go/types/decl.go:425 +0x1b7
    go/types.(*Checker).objDecl(0xc0005b6870, 0x1378080, 0xc011a03180, 0x0, 0xc008cab700, 0x0, 0x8)
    	/usr/local/go/src/go/types/decl.go:244 +0x83c
    go/types.(*Checker).packageObjects(0xc0005b6870)
    	/usr/local/go/src/go/types/resolver.go:542 +0x26f
    go/types.(*Checker).checkFiles(0xc0005b6870, 0xc00d253000, 0x1e, 0x20, 0x0, 0x0)
    	/usr/local/go/src/go/types/check.go:250 +0xa5
    go/types.(*Checker).Files(0xc0005b6870, 0xc00d253000, 0x1e, 0x20, 0xc00d0c47d0, 0xc00a68f030)
    	/usr/local/go/src/go/types/check.go:241 +0x49
    go/types.(*Config).Check(0xc00d0c68c0, 0xc010c98d17, 0x5, 0xc0021ccd40, 0xc00d253000, 0x1e, 0x20, 0xc00d0c4730, 0x101e728, 0xc0094dd940, ...)
    	/usr/local/go/src/go/types/api.go:351 +0x11a
    github.com/mgechev/revive/lint.(*Package).TypeCheck(0xc0021ccd80, 0xc0094dd940, 0xc011429880)
    	/Users/sandbox/.gotools/src/github.com/mgechev/revive/lint/package.go:80 +0x351
    github.com/mgechev/revive/rule.(*TimeNamingRule).Apply(0x15813c0, 0xc01240f740, 0x0, 0x0, 0x0, 0x1581568, 0x0, 0x0)
    	/Users/sandbox/.gotools/src/github.com/mgechev/revive/rule/time-naming.go:25 +0xb6
    github.com/mgechev/revive/lint.(*File).lint(0xc01240f740, 0xc00019e700, 0x10, 0x10, 0x0, 0x3fe999999999999a, 0xc0000146e0, 0x7, 0xc00000f710, 0x0, ...)
    	/Users/sandbox/.gotools/src/github.com/mgechev/revive/lint/file.go:100 +0x36a
    github.com/mgechev/revive/lint.(*Package).lint.func1(0xc00019e700, 0x10, 0x10, 0x0, 0x3fe999999999999a, 0xc0000146e0, 0x7, 0xc00000f710, 0x0, 0x0, ...)
    	/Users/sandbox/.gotools/src/github.com/mgechev/revive/lint/package.go:157 +0x94
    created by github.com/mgechev/revive/lint.(*Package).lint
    	/Users/sandbox/.gotools/src/github.com/mgechev/revive/lint/package.go:156 +0x173
    

    Desktop (please complete the following information):

    • OS: macOS 10.13
    • Go 1.11

    Additional context The repository tested is https://github.com/pingcap/tidb.

    opened by l2dy 14
  • struct-tag rule false-positive on json inline tag

    struct-tag rule false-positive on json inline tag

    Describe the bug struct-tag produces warning for json inline tag struct-tag: unknown option 'inline' in JSON tag (revive)

    To Reproduce Steps to reproduce the behavior:

    1. add
    type Beta struct {
        Alpha `json:",inline"`
    }
    
    1. Run revive with struct-tag rule enabled
    opened by finnan444 12
  • new rule: nested-structs

    new rule: nested-structs

    Please, describe in details what's your motivation for this PR

    Nested structs are awful to look at and I want to disallow them entirely in my projects.

    Did you add tests?

    Yes.

    Does your code follows the coding style of the rest of the repository?

    Yes.

    Does the Travis build passes?

    TBD

    Closes #529

    opened by rdeusser 11
  • Expose the ability to enable all rules

    Expose the ability to enable all rules

    Hello, and thanks for the linter. I have a feature request.

    Right now, it appears that the only way that users can enable all rules and disable one rule is to manually specify every single existing rule into the config except for the one specific one that they don't want.

    This is tedious, and not very future proof. Meaning that when you guys add a new useful rule, I don't want to have to manually do research and find out which specific new rule that you added, and then manually add that new rule to my config in order to stay up-to-date. I just want to upgrade my version of golangci-lint and automatically get the latest and greatest linting without having to change my config.

    As an analogy, golangci-lint allows this kind of workflow with the following YML config:

    linters:
      enable-all: true
      disable:
        # These linters are deprecated
        - interfacer
        - maligned
        - scopelint
    
    feature request 
    opened by Zamiell 11
  • Rules documentation

    Rules documentation

    Is your feature request related to a problem? Please describe. Some warning/error messages generated by rules are not enough to clearly understand what is wrong in the code or, more important, why.

    Linters are a good source of knowledge for beginners, we can learn from reported warnings/errors.

    For example, a warning use i++ instead of i += 1 does not provide any clue about why we should prefer i++

    Describe the solution you'd like Add a document that describes the spirit of rules. The document may also describe rule configuration details.

    Describe alternatives you've considered

    Java's FindBugs checks documentation is a good example.

    opened by chavacava 11
  • Using golangci-lint is there a way to disable a single revive's rule?

    Using golangci-lint is there a way to disable a single revive's rule?

    I'm using golangci-lint 1.40.1.

    Is there a way to disable a single revive's rule?

    Such as:

    linters-settings:
      revive:
        rules:
          - name: exported
            deactivate: true
    

    This doesn't work right now.

    opened by frederikhors 10
  • Is it possible for revive to return a non-zero exit code when there are issues and zero if not?

    Is it possible for revive to return a non-zero exit code when there are issues and zero if not?

    I'd like to run revive in some sort of automated test during build. However I found that it returns zero in any case. This makes it more complicated to check result of running the tool.

    opened by inliquid 9
  • error-strings function list should be user configurable

    error-strings function list should be user configurable

    Is your feature request related to a problem? Please describe.

    Our code-base has error strings that are not being checked by error-strings.

    Describe the solution you'd like

    Currently, error-strings uses a hardcoded list of functions that it checks. We use an internal package for generating errors that is not covered by the list. It would be nice there was a configuration option to add additional functions.

    Describe alternatives you've considered

    Potentially, we could write our own Ruleguard rule or use another linting package. We could also rename our internal package to errors, which I think would end up working given the current error functions we have and my understanding of how error-strings works.

    enhancement good first issue 
    opened by oschwald 0
  • False positive on const missing comment

    False positive on const missing comment

    Describe the bug False positive : exported const TTLkey should have comment (or a comment on this block) or be unexported

    To Reproduce

    const (
    	TTLKey       = "ttl"    // Tome to live key
    )
    

    When the comment is above it, it won't complain, but when it is after it (same line) it complains.

    Using revive 1.2.1 Command: revive -formatter friendly -exclude ./vendor/... ./...

    bug 
    opened by MarcelXia 3
  • Deprecate the use of words Whitelist and Blacklist

    Deprecate the use of words Whitelist and Blacklist

    Overview

    The words whitelist and blacklist been used for years, but with current events we are questioning if we could some more inclusive terms.

    Question

    I was wonder if you would be opposed to deprecating the use of the words blacklist and whitelist in this repository?

    Suggestion

    I would like to get feed back on either addressing the whole repo

    Whitelist https://github.com/mgechev/revive/search?q=whitelist Blacklist https://github.com/mgechev/revive/search?q=blacklist

    Or just address it with the rules naming and config words. The approach is to mirror the old config with a new config. The old config would echo out a deprecation message for a future version.

    Config changes https://github.com/mgechev/revive/blob/a67ecdd7ba96272124152b280054d16368e774ac/config/config.go

    if you are not opposed to the idea, I may have someone that can address this. I just wanted to get your feedback first before we would submit a PR.

    opened by dschveninger 2
  • New Rule for warning when fields are not set when initialising a struct

    New Rule for warning when fields are not set when initialising a struct

    Is your feature request related to a problem? Please describe. Given the nature of Go there is a lot of translating one struct to another (eg, Create Payload to an Update Payload or simliar). I'm always frustrated when I'm adding new fields, and have to manually remember each mapping function I have. Often times a mapper is forgotten without any visible warnings, and only discovered once a bug is encountered.

    Describe the solution you'd like I would love to have a rule that warns if there are any unset fields in a struct initialisation. The rule would only kick in place when one or more fields are defined.

    No Warning:

    type MyStruct struct {
       FirstName string
       LastName string
    }
    
    var ex MyStruct = MyStruct{}
    

    Warning:

    type MyStruct struct {
       FirstName string
       LastName string
    }
    
    var ex MyStruct = MyStruct{ FirstName: "Hello" }
    

    Describe alternatives you've considered I've looked around for solutions, but writing a custom linter seems like the only option here without changing the code structures to rely on generated code or similar solutions.

    enhancement 
    opened by johan-lejdung 2
  • Different results when removing the GOCACHE and pkgs directories

    Different results when removing the GOCACHE and pkgs directories

    Describe the bug

    This is more of a "i need a better idea on how to debug this" bug reports because i do have a reproducer, but it involves our monorepo (which i can't just send out).

    The bug of this issue is that the output of revive is not deterministic for one specific problem. The following Revive config enables the rule that finds the reported problem.

    [rule.range-val-address]
            Disabled = false
    

    Which leads to the following problem in the reproducer i am currently reducing:

    tt.go:20:15: suspicious assignment of 'p'. range-loop variables always have the same address

    The problem appears deterministically in our CI but it does not appear locally on my machine right away. I need to do some steps to reproduce it but then it is again deterministically reporting the problem.

    revive --config config.toml tt.go # Does not report a problem.
    rm -rf $GOCACHE pkg/
    revive --config ok.toml tt.go # Suddenly reports a problem.
    go install $our-project/...
    revive --config config.toml tt.go # Does not report a problem.
    

    First i thought it is a race, but when i compile Revive with the race detector on, there is no race anymore with the latest changes. So i ran out of ideas on what the problem is.

    One idea i had was that this must have something to do with how packages are loaded to resolve types because i reduce the code down to:

    func prepareTestsForValidation(tests []*model.ProjectTest) {
            for _, test := range tests {
                    for _, p := range test.Result.Problems {
                            problem := &p.Problem
                            problem.Message = "abc"
                    }
            }
    }
    

    "model" is an import identifier. When i copy the types directly into the same file as the reduce code, Revive does not report a problem anymore.

    Expected behavior

    I would expected to always have the same problem.

    Desktop:

    • OS: SUSE LEAP 15.3 locally and Ubuntu 20.04 in the CI which runs in Kubernetes+latest Docker
    • Version of Go: 1.18.0
    enhancement 
    opened by zimmski 5
Releases(v1.2.1)
Owner
Minko Gechev
Working on Angular at Google. Previously co-founder & CTO of Rhyme.com (acquired by Coursera) 🇧🇬🇺🇸
Minko Gechev
Sloc, Cloc and Code: scc is a very fast accurate code counter with complexity calculations and COCOMO estimates written in pure Go

Sloc Cloc and Code (scc) A tool similar to cloc, sloccount and tokei. For counting physical the lines of code, blank lines, comment lines, and physica

Ben Boyter 3.5k Jun 29, 2022
Jenkins tracer is used to record all the Jenkins job environment variables and metrics, and send them to Elasticsearch

Jenkins Tracer Jenkins tracer is used to record all the jenkins job variables like record the build duration, build variables, repository metadata, et

Misbahul Ardani 3 Apr 22, 2021
Clean architecture validator for go, like a The Dependency Rule and interaction between packages in your Go projects.

Clean Architecture checker for Golang go-cleanarch was created to keep Clean Architecture rules, like a The Dependency Rule and interaction between mo

Robert Laszczak 604 Jun 23, 2022
Manage your repository's TODOs, tickets and checklists as config in your codebase.

tickgit ??️ tickgit is a tool to help you manage latent work in a codebase. Use the tickgit command to view pending tasks, progress reports, completio

Augmentable 276 Jun 3, 2022
depth is tool to retrieve and visualize Go source code dependency trees.

depth is tool to retrieve and visualize Go source code dependency trees. Install Download the appropriate binary for your platform from the Rele

Kyle Banks 759 Jun 22, 2022
A reference for the Go community that covers the fundamentals of writing clean code and discusses concrete refactoring examples specific to Go.

A reference for the Go community that covers the fundamentals of writing clean code and discusses concrete refactoring examples specific to Go.

Lasse Martin Jakobsen 2.2k Jun 30, 2022
Tool to populate your code with traceable and secure error codes

Essential part of any project, especially customer facing is proper and secure error handling. When error happens and customer reports it, it would be nice to know the context of the error and where it exactly occured.

vs 52 Apr 1, 2022
A Golang tool that does static analysis, unit testing, code review and generate code quality report.

goreporter A Golang tool that does static analysis, unit testing, code review and generate code quality report. This is a tool that concurrently runs

360 Enterprise Security Group, Endpoint Security, inc. 3k Jun 26, 2022
[mirror] Performance measurement, storage, and analysis.

Go performance measurement, storage, and analysis tools This subrepository holds the source for various packages and tools related to performance meas

Go 307 Jun 15, 2022
A GitLab API client enabling Go programs to interact with GitLab in a simple and uniform way

go-gitlab A GitLab API client enabling Go programs to interact with GitLab in a simple and uniform way NOTE Release v0.6.0 (released on 25-08-2017) no

Xanzy 1.7k Jun 27, 2022
Fast division, modulus and divisibility checks in Go for divisors known only at runtime.

fastdiv Fast division, modulus and divisibility checks for divisors known only at runtime via the method of: "Faster Remainder by Direct Computation:

null 99 May 17, 2022
Bundle k6 with extensions as fast and easily as possible

xk6bundler xk6bundler is a CLI tool and GitHub Action makes bundle k6 with extensions as fast and easily as possible. Features Build for multiple targ

Iván Szkiba 8 Jan 28, 2022
octocov is a tool for collecting code metrics (code coverage, code to test ratio and test execution time).

octocov is a tool for collecting code metrics (code coverage, code to test ratio and test execution time).

Ken’ichiro Oyama 84 Jun 12, 2022
Refactoring and code transformation tool for Go.

gopatch is a tool to match and transform Go code. It is meant to aid in refactoring and restyling.

Uber Go 469 Jun 23, 2022
The Golang linter that checks that there is no simultaneous return of `nil` error and an invalid value.

nilnil Checks that there is no simultaneous return of nil error and an invalid value. Installation & usage $ go install github.com/Antonboom/[email protected]

Anton Telyshev 10 Jun 23, 2022
Act as part of the business code and will report aqua scan report after application installed

starboard-report This repo aim to enrich the functionality of starboard. Starboard integrates security tools into the Kubernetes environment, so that

null 17 Nov 25, 2021
Go linter that checks types that are json encoded - reports unsupported types and unnecessary error checks

Checks types passed to the json encoding functions. Reports unsupported types and reports occations, where the check for the returned error can be omited.

Lucas Bremgartner 26 Jun 17, 2022
Go client for the Foreign exchange rates and currency conversion API moneybag

fixer Go client for Fixer.io (Foreign exchange rates and currency conversion API) You need to register for a free access key if using the default Fixe

Shingirai Chanakira 0 Nov 25, 2021