Going the extra mile: golint and go vet
Go has a lot of awesome tools to help install packages and write readable, safe and correct code. Some are already well-known and widely used, such as
go get or
gofmt, but there are other gems hiding under the
go command umbrella, or standing on their own in the go.tools repository or in the official github account.
Lately, we started running two complementary tools on our codebase: golint and go vet.
Go with style
The linter cares about coding style. The README file in the repository says it best:
Golint differs from gofmt. Gofmt reformats Go source code, whereas
golint prints out style mistakes.
Golint differs from govet. Govet is concerned with correctness, whereas
golint is concerned with coding style. Golint is in use at Google, and it
seeks to match the accepted style of the open source Go project.
So it will catch issues such as missing comments on exported symbols (or even badly formatted comments), variable naming that doesn’t follow the conventional Go style, useless specification of variable types when it can be inferred, etc. Most of its rules are based on the style guide available in the Go wiki.
Vetted code is better code
go vet can find actual errors in the code. From the command’s documentation:
Vet examines Go source code and reports suspicious constructs, such as Printf
calls whose arguments do not align with the format string. Vet uses heuristics
that do not guarantee all reports are genuine problems, but it can find errors
not caught by the compilers.
go vet starts where the compiler ends, and catches subtle issues that may easily pass through code review and unit testing.
Printf-style errors are one of those, but for example it also reports position-based struct literals (non-keyed fields) when the struct belongs to an external package, since this creates a careless dependency on the internals of the package that exports the struct (order cannot be changed without breaking the outside code, let alone adding new fields).
We are still toying with different ways to run those checks automatically. One option is to configure it on a
pre-commit hook in the git repository. We list the messages returned by
golint as information only, because it can have plenty of false positives.
go vet can have false positives too, so it should not be a blocker to a commit, but both outputs can be very useful to have on a regular basis, and git commit can’t be avoided, so that’s an interesting place to run this.
The important takeaway though is that those tools do exist, that they are complementary to the other tools you may already be using, and that they help write more readable and safer Go code.
July 10, 2014