The number of tools for statically checking Go source for errors and warnings
is impressive.
This is a tool that concurrently runs a whole bunch of those linters and
normalises their output to a standard format:
<file>:<line>:[<column>]: <message> (<linter>)
eg.
stutter.go:9::warning: unused global variable unusedGlobal (varcheck)
stutter.go:12:6:warning: exported type MyStruct should have comment or be unexported (golint)
It is intended for use with editor/IDE integration.
Installing
Binary Releases
To install the latest stable release:
curl -L https://git.io/vp6lP | sh
Alternatively you can install a specific version from the releases list.
Homebrew
brew tap alecthomas/homebrew-tap
brew install gometalinter
Additional linters can be added through the command line with --linter=NAME:COMMAND:PATTERN (see below).
Configuration file
gometalinter now supports a JSON configuration file called .gometalinter.json that can
be placed at the root of your project. The configuration file will be automatically loaded
from the working directory or any parent directory and can be overridden by passing
--config=<file> or ignored with --no-config. The format of this file is determined by
the Config struct in config.go.
The configuration file mostly corresponds to command-line flags, with the following exceptions:
Linters defined in the configuration file will overlay existing definitions, not replace them.
"Enable" defines the exact set of linters that will be enabled (default
linters are disabled). --help displays the list of default linters with the exact names
you must use.
Here is an example configuration file:
{
"Enable": ["deadcode", "unconvert"]
}
If a .gometalinter.json file is loaded, individual options can still be overridden by
passing command-line flags. All flags are parsed in order, meaning configuration passed
with the --config flag will override any command-line flags passed before and be
overridden by flags passed after.
Format key
The default Format key places the different fields of an Issue into a template. this
corresponds to the --format option command-line flag.
A comment directive at the same indentation level as a statement it
immediately precedes will also suppress any linter messages in that entire
statement.
eg. In this example all messages for SomeFunc() will be suppressed.
// nolintfuncSomeFunc() {
}
Implementation details: gometalinter now performs parsing of Go source code,
to extract linter directives and associate them with line ranges. To avoid
unnecessary processing, parsing is on-demand: the first time a linter emits a
message for a file, that file is parsed for directives.
Quickstart
Install gometalinter (see above).
Run it:
$ cd example
$ gometalinter ./...
stutter.go:13::warning: unused struct field MyStruct.Unused (structcheck)
stutter.go:9::warning: unused global variable unusedGlobal (varcheck)
stutter.go:12:6:warning: exported type MyStruct should have comment or be unexported (golint)
stutter.go:16:6:warning: exported type PublicUndocumented should have comment or be unexported (golint)
stutter.go:8:1:warning: unusedGlobal is unused (deadcode)
stutter.go:12:1:warning: MyStruct is unused (deadcode)
stutter.go:16:1:warning: PublicUndocumented is unused (deadcode)
stutter.go:20:1:warning: duplicateDefer is unused (deadcode)
stutter.go:21:15:warning: error return value not checked (defer a.Close()) (errcheck)
stutter.go:22:15:warning: error return value not checked (defer a.Close()) (errcheck)
stutter.go:27:6:warning: error return value not checked (doit() // test for errcheck) (errcheck)
stutter.go:29::error: unreachable code (vet)
stutter.go:26::error: missing argument for Printf("%d"): format reads arg 1, have only 0 args (vet)
Gometalinter also supports the commonly seen <path>/... recursive path
format. Note that this can be very slow, and you may need to increase the linter --deadline to allow linters to complete.
FAQ
Exit status
gometalinter sets two bits of the exit status to indicate different issues:
Bit
Meaning
0
A linter generated an issue.
1
An underlying error occurred; eg. a linter failed to execute. In this situation a warning will also be displayed.
eg. linter only = 1, underlying only = 2, linter + underlying = 3
What's the best way to use gometalinter in CI?
There are two main problems running in a CI:
Linters break, causing gometalinter --install --update to error (this is no longer an issue as all linters are vendored).
gometalinter adds a new linter.
I have solved 1 by vendoring the linters.
For 2, the best option is to disable all linters, then explicitly enable the
ones you want:
How do I make gometalinter work with Go 1.5 vendoring?
gometalinter has a --vendor flag that just sets GO15VENDOREXPERIMENT=1, however the
underlying tools must support it. Ensure that all of the linters are up to date and built with Go 1.5
(gometalinter --install --force) then run gometalinter --vendor .. That should be it.
Why does gometalinter --install install a fork of gocyclo?
I forked gocyclo because the upstream behaviour is to recursively check all
subdirectories even when just a single directory is specified. This made it
unusably slow when vendoring. The recursive behaviour can be achieved with
gometalinter by explicitly specifying <path>/.... There is a
pull request open.
Many unexpected errors are being reported
If you see a whole bunch of errors being reported that you wouldn't expect,
such as compile errors, this typically means that something is wrong with your
Go environment. Try go install and fix any issues with your go installation,
then try gometalinter again.
Gometalinter is not working
That's more of a statement than a question, but okay.
Sometimes gometalinter will not report issues that you think it should. There
are three things to try in that case:
1. Update to the latest build of gometalinter and all linters
curl -L https://git.io/vp6lP | sh
If you're lucky, this will fix the problem.
2. Analyse the debug output
If that doesn't help, the problem may be elsewhere (in no particular order):
Upstream linter has changed its output or semantics.
gometalinter is not invoking the tool correctly.
gometalinter regular expression matches are not correct for a linter.
Linter is exceeding the deadline.
To find out what's going on run in debug mode:
gometalinter --debug
This will show all output from the linters and should indicate why it is
failing.
3. Report an issue.
Failing all else, if the problem looks like a bug please file an issue and
include the output of gometalinter --debug.
How do I filter issues between two git refs?
revgrep can be used to filter the output of gometalinter
to show issues on lines that have changed between two git refs, such as unstaged changes, changes in
HEAD vs master and between master and origin/master. See the project's documentation and -help
usage for more information.
go get -u github.com/bradleyfalzon/revgrep/...
gometalinter |& revgrep # If unstaged changes or untracked files, those issues are shown.
gometalinter |& revgrep # Else show issues in the last commit.
gometalinter |& revgrep master # Show issues between master and HEAD (or any other reference).
gometalinter |& revgrep origin/master # Show issues that haven't been pushed.
Checkstyle XML format
gometalinter supports checkstyle
compatible XML output format. It is triggered with --checkstyle flag:
gometalinter --checkstyle
Checkstyle format can be used to integrate gometalinter with Jenkins CI with the
help of Checkstyle Plugin.
请发表评论