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.
- SublimeLinter plugin.
 - vim-go with the 
:GoMetaLintercommand. - syntastic (vim) 
let g:syntastic_go_checkers = ['gometalinter'] - Atom linter plugin.
 - Emacs Flycheck checker.
 - Go for Visual Studio Code.
 
- go vet - Reports potential errors that otherwise compile.
 - go vet --shadow - Reports variables that may have been unintentionally shadowed.
 - gotype - Syntactic and semantic analysis similar to the Go compiler.
 - deadcode - Finds unused code.
 - gocyclo - Computes the cyclomatic complexity of functions.
 - golint - Google's (mostly stylistic) linter.
 - varcheck - Find unused global variables and constants.
 - structcheck - Find unused struct fields.
 - aligncheck - Warn about un-optimally aligned structures.
 - errcheck - Check that error return values are used.
 - dupl - Reports potentially duplicated code.
 - ineffassign - Detect when assignments to existing variables are not used.
 - interfacer - Suggest narrower interfaces that can be used.
 - unconvert - Detect redundant type conversions.
 - goconst - Finds repeated strings that could be replaced by a constant.
 - gosimple - Report simplifications in code.
 - staticcheck - Statically detect bugs, both obvious and subtle ones.
 
Disabled by default (enable with --enable=<linter>):
- testify - Show location of failed testify assertions.
 - test - Show location of test failures from the stdlib testing module.
 - gofmt -s - Checks if the code is properly formatted and could not be further simplified.
 - goimports - Checks missing or unreferenced package imports.
 - lll - Report long lines (see 
--line-length=N). - misspell - Finds commonly misspelled English words.
 - unused - Find unused variables.
 
Additional linters can be added through the command line with --linter=NAME:COMMAND:PATTERN (see below).
There are two options for installing gometalinter.
- Install a stable version, eg. 
go get -u gopkg.in/alecthomas/gometalinter.v1. I will generally only tag a new stable version when it has passed the Travis regression tests. The downside is that the binary will be calledgometalinter.v1. - Install from HEAD with: 
go get -u github.com/alecthomas/gometalinter. This has the downside that changes to gometalinter may break. 
Install gometalinter:
$ go get -u github.com/alecthomas/gometalinter
Install all known linters:
$ gometalinter --install
Installing:
  structcheck
  aligncheck
  deadcode
  gocyclo
  ineffassign
  dupl
  golint
  gotype
  goimports
  errcheck
  varcheck
  interfacer
  goconst
  gosimple
  staticcheck
  unused
  misspell
  lll
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.
gometalinter now supports a JSON configuration file which can be loaded via
--config=<file>. The format of this file is determined by the Config struct
in main.go.
Refer to the corresponding command-line flags for documentation.
Here is an example configuration file:
{
  "DisableAll": true,
  "Enable": ["deadcode", "unconvert"]
}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
There are two main problems running in a CI:
Linters break, causing(this is no longer an issue as all linters are vendored).gometalinter --install --updateto errorgometalinteradds a new linter.
There is no great solution to 1, but for 2, the best option is to disable all linters, then explicitly enable the ones you want:
gometalinter --disable-all --enable=errcheck --enable=vet --enable=vetshadow ...
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.
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.
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:
go get -u github.com/alecthomas/gometalinter
gometalinter --install
If you're lucky, this will fix the problem.
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.
Failing all else, if the problem looks like a bug please file an issue and
include the output of gometalinter --debug.
Additional linters can be configured via the command line:
$ gometalinter --linter='vet:go tool vet -printfuncs=Infof,Debugf,Warningf,Errorf {path}:PATH:LINE:MESSAGE' .
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:9::warning: unused global variable unusedGlobal (varcheck)
stutter.go:13::warning: unused struct field MyStruct.Unused (structcheck)
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 (deadcode)
gometalinter supports checkstyle
compatible XML output format. It is tiggered with --checkstyle flag:
gometalinter --checkstyle
Checkstyle format can be used to integrate gometalinter with Jenkins CI with the help of Checkstyle Plugin.