How to package dependencies in Golang

(written by lawrence krubner, however indented passages are often quotes). You can contact lawrence at:, or follow me on Twitter.

Very interesting, as I’m a fan of the idea of “vendoring”:

An attempt to fix packaging in Go:

Manul is a vendoring utility for Go programs.

What’s the reason for yet another utility?

Because all other vendor utilities suffer from the following:

Some wrap the go binary and spoof the GOPATH env variable. You will have a non-go-gettable project which needs additional software in order to compile and run;

Some copy the source code of dependencies into the vendor directory:

It will be nearly impossible to find anything using GitHub Search, because you will get many false-positive results;
Updating dependencies will require manual intervention and committing a lot of modified lines straight into the main repo;
You will not be able to tell what version of dependency your project is using will by looking at repository; you have to keep versions in the additional ambiguous file with vendors associated with commits.
Various architecture problems:

Impossible to update all or specific vendored dependencies;
Impossible to rollback vendored dependencies to specific version;
Impossible to remove unused vendored dependencies;
Impossible to lock version of vendored dependency.

And an interesting bit of criticism:

As someone who has thought Go was a poor choice for almost any project for a long time and argued that many times, I used to come up against the argument that Go package management was superior to other languages. Six months ago I said:
> Packaging and deployment aren’t problems in Go OR Python if you’re only solving trivial problems.
> With a larger project, you might have an easier time packaging and deploying Go code, but that’s largely because there are no libraries to package. Admittedly packaging can be a pain in Python, but that’s usually because of poor choices in dependencies. Packaging Python with a few mature dependencies isn’t hard in my experience. It’s the projects where some idiot has pulled in every 0.x versioned library in pip that are hard to package. When Go has as wide a variety of libraries as Python people will run into the same problems in Go.
> You could argue that at least for now Go doesn’t allow you to shoot yourself in the foot that way, but I’d rather have the option.
> I’m not defending Python in particular here. I’d say the same things I’ve said here about any mature language with extensive libraries.
> If you’re espousing Go because of easy packaging and deployment, I strongly suggest that you consider whether that’s actually a feature Go will have long term, and whether you’re currently paying for that feature by having no libraries available to you. The only lesson I would take away from Go’s easy packaging is to only use mature dependencies that pull their weight.
And in a different post:
> give it a decade and Go packaging will be just as miserable as packaging in any other language.
I’ve been coming up against that argument a lot less lately. It looks like my prediction is coming true a bit ahead of schedule.

Post external references

  1. 1