Glide 0.7.0 Now With SemVer and Auto Flattening

With the release of Glide 0.7.0 come a number of changes. I'd like to highlight the two major useful changes of semantic version support and automatic dependency flattening.

Semantic Version Support

Versioning packages in Go is a problem. Let me illustrate this with three examples.

  1. I was recently looking at Kubernetes, its dependencies, and the dependencies of its dependencies. There are numerous cases where the same dependency is imported, the version specified is different, and the version is a commit id. Can you decipher what should be going on?
  2. I was looking at a project importing Kubernetes. The version specified was a commit id. Since Kubernetes releases versions I was wondering what version was being used. After a little searching I found it was a commit between two versions. When projects have stable releases when is it a good idea to use a commit between releases?
  3. What if you found an application using the version f9885acc8cd1403afcd09570c89a009e8bd1dc19 of OpenSSL. Would you think it was a good idea to use that application? Would you know what vulnerabilities had been fixed? This is theoretical since no one does that. That commit id happens to be vulnerable to Heartbleed. With versions it's pretty easy to see if a release is after the fixed version. When using commit ids it's not.

Semantic Versioning (SemVer) is a nice way to version packages and applications. Not only is it widely used it has a versioned spec making it easy to write support for.

Glide now supports SemVer and you can use constraints. For example, for a version you can specify 1.2.x (which is >= 1.2.0, < 1.3.0), ^1.2.3 (which is >= 1.2.3, < 2.0.0), and a host of other options. Glide will try to pick the latest release to meet the constraint. The SemVer handling is through the github.com/Masterminds/semver package. In the documentation you can see the supported syntax and even use it in your own applications.

Of course, you can still specify a branch, tag, or commit id. Those have a higher priority than attempting to figure out the right semantic version.

Automatic Dependency Flattening

Go works best when there is only one import location for a package in a build. This is best seen in the $GOPATH which is one location. With vendor/ directory support there's an opportunity for packages to import packages that import packages and the dependencies are in the corresponding vendor/ directories.

Different packages can import different versions and objects created in one package location are going to have an issue working with the same package in another import location. To illustrate this I've put an example online that you can clone and fail to run.

And it's worth noting that each separate import location is included in the resulting build binary. This can easily lead to binary bloat.

Glide now flattens dependencies to a top level vendor/ folder unless the dependency has chosen to self manage the dependencies. In addition to Glide managed projects, this also works with Godep, GPM, and gb managed projects when flattening. You can import packages managed by different tools.

Building Practical Solutions

We're attempting to build Glide to be a practical tool solving real problems. Given the fragmentation of package management in Go that means working with packages managed with multiple tools. Using the new vendor support in Go means we learn practical ways to work with these packages and try to come up with useful solutions.

If you want to contribute to this or you have some insight please drop by the issue queues or find us in IRC (#masterminds room on Freenode). We're happy to talk and welcomes pull requests and feedback.