Some Tools For Go That You Might Not Know Yet
Year’s end is coming closer. Time to clean up repositories and polishing up the toolset. All the well-known tools have been installed already–is there anything else to add to the toolbox?
Here are a few useful tools that you might not have in your toolbox yet:
binstale. They have nothing in
common except that each of them solves a particular problem well.
interfacer: Should I rather use an interface here?
interfacer has a very specific
purpose: It looks at the parameters of your functions and points out
those that you could replace by an interface type.
Maybe you have heard of the following advice: A function should expect an interface and return a specific type. I fail to remember where I came across that rule, and the precise wording might also be different, but the point is that if a function parameter is an interface then the function is much more versatile and can, for example, receive a mock type when used in a unit test.
So whenever you feel you have missed an opportunity to have one of your
functions receive an interface rather then a struct, run
and it will tell you if you did.
Imagine that one day, you start writing a BBQ sensor library for
controlling the temperature of your Thanksgiving turkey. The library
Alerter interface consisting of function
Alerter, and a
Sensor struct that implements
A couple hours and few thousand lines later (yes, you feel productive
this day) you define a function
sensorAlert that expects a
struct and calls its
You vaguely remember that
Alert belongs to some interface but you can’t
remember which one. You’re too lazy to search for it (and after all,
it is already 11pm), so you run
$ interfacer bbq.go
and get this advice:
bbq.go:15:18: s can be Alerter
You quickly fix the
sensorAlert function and go to bed, knowing that
you now can easily pass some
MockSensor struct to
you’ll write the tests tomorrow.
zb: Take some shortcuts to the go toolchain
After you finished some work on your latest project, you run
gometalinter. It takes some time to finish, and you discover that some
of the lint tools have descended into the vendor directory, and now the
output is cluttered with lots of useless messages.
Then you run
go build, only to observe that some tests failed. Aw,
forgot to run
While you fix this, you realize how time is passing, and you wish your tools were faster and a bit smarter.
zb to the rescue.
In contrast to the previous tool,
zb is a little Swiss army knife.
It provides a bunch of commands that shall speed up your
write/build/test cycle. Some of its highlights:
- It speeds up builds by running concurrent
go installcommands where possible.
- It speeds up tests and lint tools by caching the results.
- It remembers calling
go generatein case you forgot.
- It is aware of the
vendordirectory and keeps some operations out of
vendor(like, for example, linting).
I cannot list all of the available commands here; otherwise I would just end up rephrasing the README file here. If you got curious, just head over to zb’s README and have a look.
Caveat: The author describes the tool as opinionated, and I would tend to agree. On the other hand, there is no obligation to use all of the available commands. Just pick the ones you find useful and that don’t get in the way of your workflow.
realize: Trigger your toolchain via Ctrl-S
The standard go tools -
go test, etc. are quick and
uncomplicated, but as your projects get larger and more complex, you
start wishing for some kind of automation that triggers all builds and
tests each time you save a source file.
realize is your friend.
fmt, etc. is just a matter of
flipping some boolean switches in a config file (as opposed to
specifying the complete command line).
Plus, you can add custom commands for pre- and post-processing, set paths to ignore, choose to save output, log, or error streams from the build, and more.
And besides a colorful shell output (where you can quickly tell
successful builds from failed builds by the color),
realize also has a
Web UI to monitor all of your build processes in one browser window.
binstale: Are my binaries up to date?
Do you know if the binaries in your
$GOPATH/bin directory are still up
go get happily installs binary after binary, but then they
start collecting dust. And at one point you remember you once installed
that nice tool that helped you doing xyz for you, and eventually you
find it in
$GOPATH/bin, but starting it fails with some
incomprehensible error message.
You are pretty sure it worked without flaws back then, so maybe the binary got stale? You decide to try updating the source code.
You run a recursive search in
$GOPATH/bin to find a repository of
the same name as the binary. Eventually you find the repository and
go get on it. This fixes your binary, and you feel relieved…
…until you realize that there could be dozens, if not hundreds, of
stale binaries in your
This little gem tells you in an instant whether a given go-gettable binary needs updating.
1 2 3
$ binstale realize realize STALE: github.com/tockins/realize (build ID mismatch)
And if you have a minute or two, it does the same for all of your binaries.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
$ binstale CanvasStreamTest STALE: github.com/cryptix/CanvasStreamTest (build ID mismatch) Go-Package-Store STALE: github.com/shurcooL/Go-Package-Store (build ID mismatch) aligncheck STALE: github.com/alecthomas/gometalinter/vendor/src/github.com/opennota/check/cmd/aligncheck (build ID mismatch) STALE: github.com/opennota/check/cmd/aligncheck (build ID mismatch) asmfmt STALE: github.com/klauspost/asmfmt/cmd/asmfmt (build ID mismatch) balancedtree STALE: github.com/appliedgo/balancedtree (build ID mismatch) benchcmp STALE: code.google.com/p/go.tools/cmd/benchcmp (build ID mismatch) STALE: golang.org/x/tools/cmd/benchcmp (build ID mismatch) benchstat STALE: rsc.io/benchstat (build ID mismatch) binstale STALE: github.com/shurcooL/binstale (build ID mismatch) bug STALE: github.com/driusan/bug (build ID mismatch) ...
You might have noticed that some binaries have more than one
matching repository (aligncheck and benchcmp in the above
sample output). For this reason,
binstale currently does not
auto-update any binaries. But updating is just a matter of copying
and pasting the repository path to
go get -u and you’re done.
These are only a few examples from a steadily growing base of useful command line tools written to make a developer’s life easier.
If you have an idea for a cool tool, don’t hesitate to sit down and write it. But first, be sure to check the public repositories - the tool you have in mind might already exist somewhere, thanks to a thriving Go community.