In the Go toolchain there is a convenient way to install and use external packages. If a feature isn’t in the standard library and is common there’s likely a package you can easy reference and install with go get
to provide you with what you need.
But, what version of that package are you using? Is it a stable release? Is there a newer version with a bugfix or security update? How can you tell?
By Default You Don’t Know
When you use go get
to retrieve a package it doesn’t get the latest tagged version. Instead it grabs the latest code. For example, if you get a package from Github that has a default branch of master
it’s going to grab the latest commit from master
.
Do you want the latest commit or the latest stable release?
The package is retrieved over HTTP and the commit reference, tag, or other information isn’t stored locally.
Why It Matters
There are a variety of reasons to care about the version you’re using. Here are just a few.
- Software engineers use a variety of development styles. Some will keep the working tree in fine working order at all times. Others may have a project that passes all tests but you should only use the releases. And, others will have broken packages from time to time. Sometimes they are ok with that. Releases are a point when everyone agrees it’s a package to be used. If it’s not release worthy it may be an alpha or beta. You know what you’re getting.
- Version tracking for bugs and security issues. You often need that. Does the version you’re using have a security issue? Is the bug you’re encountering an issue or fixed in a newer release? If you aren’t tracking the versions how are you to know? If you work for an organization that uses audits how do you handle those?
- API breaking changes happen in software. If you’re using semantic versioning you know you need to bump the major version to signify the change. If you aren’t tracking or referencing versions how do you manage these? How do you install the previous version if you want that for the moment?
There are many more reasons than these for controlling and tracking the versions.
Vendoring Doesn’t Solve This
In Go package conversations I’ve been in the topic of package handling often turns into one about whether to vendor or not. In this case, whether you vendor or not doesn’t matter. Using many tools, including go get
, with or without vendoring will not help you with the version of the packages you’re using.
Oh the tools
If you’ve used tools for other languages such as pip, composer, npm, gem, bundler, or one of the many others you’re likely familiar with specifying the version you want to use. While Go itself doesn’t handle versions when using go get
there are others tools out there for you.
First, many of these tools add value but don’t deal with versions. For example godep, one of the more popular package managers, will save a revision as a hash. But, what version did you initially install for it to save? And, if you had to audit the installed versions will you know which tagged, released, or otherwise controlled version you’re using?
A recent popular addition is gb. It has some nice features and things I plan to roll into my own work. If you’re using gb, do you know what versions of which projects you’re using? There is a gb vendor
command with sub-commands to install by tag, branch, and so forth. If you had to audit what someone else installed and vendored could you? This information isn’t in a configuration file.
I’m not here to criticize. I’m here to raise the issue because I hope everyone thinks this through and chooses the correct level of control they need. And, that everyone would be aware of the level of control they need. It’s different for different projects.
There are some tools that allow you to control your package version. I’m presently using and working on glide which is similar to npm, composer, pip, and others like it. There are several other tools that help with this as well. The wiki on the Github for the Go project has a listing with of package managers.
The one takeaway from this post I’d like everyone to have is an awareness of package versions and their needs to manage them.