The State of Go Dependency Management

Written by tejasmanohar | Published 2017/02/25
Tech Story Tags: golang | dependencies | google | programming | software-engineering

TLDRvia the TL;DR App

Ever since Go caught significant attention outside of Google, dependency management has been a hot topic.

Initially, there was no dependency management beyond go get, which loads source files off origin/master to your system-wide [$GOPATH](https://github.com/golang/go/wiki/GOPATH). With internal dependencies, this often works since everyone is expected to use the latest version. However, for teams with 3rd-party dependencies, this was unacceptable due to mismatches, conflicts, breaking changes, and more so a number of ad hoc approaches emerged, e.g.

  • committing a project-specific $GOPATH
  • git submodules (and variations)
  • tools that automated switching between project-specific $GOPATH like [gvm](https://github.com/moovweb/gvm) and [gb](https://github.com/constabulary/gb)

Eventually, folks realized we needed something better… something that was consistent and actually kept track of actual versions (commit SHAs, tags) that code committed was on… something that was simple. To “solve” this need, the most popular solution — [godep](https://github.com/tools/godep) — rose to popularity. Godep allowed you to “easily”

  • pin dependencies in your $GOPATH to a project
  • copy dependencies from a project to your $GOPATH
  • browse what dependencies are pinned via Godeps.json

Though Godep was an immense improvement over existing methods, it certainly didn’t solve everything. It had a number of problems.

For one, Godep had a number of bugs, quirks, and inconsistencies that frustrated its users. Many people believe this killed the project. I disagree.

Most of these “quirks” were because Godep still revolved around $GOPATH. To update a project’s dependency, you’d have to update it in your $GOPATH via go get -u github.com/some/dep, and then, copy it from your $GOPATH to your project’s Godeps/ via godep save github.com/some/dep. Since most developers work out of $GOPATH, this was annoying when you were modifying a dependency in $GOPATH. Additionally, since most developers have a single $GOPATH, updating dependencies of multiple projects using different versions of dependencies concurrently was overwhelming.

By Go 1.5 (mid-2015), there were a number of different practices but no standards. So the Go team realized it was time to step in by drafting the “vendor experiment”. With the experiment enabled, Go’s import preferred the vendor folder to $GOPATH/src. In Go 1.6, the vendor experiment was enabled by default. Immediately, numerous tools blew up, e.g.

  • glide, an opinionated, heavy, and “modern” package management system… very similar to ruby’s gems
  • govendor, a happy in-between… my personal favorite, though it has arguably strange naming/syntax conventions
  • gvt, a simple vendoring tool… the godep of vendor
  • … and many, many more

Not to undermine what it takes to integrate something like this into the core toolchain, but beyond the 4-page proposal and hype, “vendor” didn’t introduce much that wasn’t already around. godep build already did everything it proposed and more.

Note that when “go get” fetches a new dependency it never places it in the vendor directory. In general, moving code into or out of the vendor directory is the job of vendoring tools, not the go command.— From Go 1.5 Vendor Experiment proposal

In fact, vendor didn’t even come with a tool to manage the dependencies or get them in vendor/ in the first place. However, what it did was provide the community with a standard of how and where dependencies should be managed. And, apparently, that’s often enough to get the ball rolling in a software community.

Vendoring in Go is still very broken. Fortunately, the Go team is working on a new tool — [dep](https://github.com/golang/dep) — that should improve things significantly. So far, all the problems I’ve had with Go dependencies are solved in their features and user stories documents. Of course, there’s no guarantee that these features will be solved in the initial release, but it’s great to know that the team recognizes and is interested in solving them. From supporting forks to transitive dependencies to multiple versions of the same dependency to supporting private proxies, I’m really excited for dep.

Go is for simplicity. Simplicity is for productivity. Not having to fight dependencies will be a huge plus! 🎉

Hacker Noon is how hackers start their afternoons. We’re a part of the @AMIfamily. We are now accepting submissions and happy to discuss advertising & sponsorship opportunities.

To learn more, read our about page, like/message us on Facebook, or simply, tweet/DM @HackerNoon.

If you enjoyed this story, we recommend reading our latest tech stories and trending tech stories. Until next time, don’t take the realities of the world for granted!


Published by HackerNoon on 2017/02/25