Brief overview of package management in Go — pre and post Go modules.

Package management is one of the things Go has always missed. One of the major drawbacks of the previous (pre 1.11) go get was lack of support for managing dependency versions and enabling reproducible builds. The community has developed package managers and tools like Glide, dep, and  many others serving as de-facto solutions for versioning dependencies.

“I use go get for production builds.” — said no one ever.

Go’s implementation of package management traces its origins back to Google (which has a giant monolithic repository for all their source code). Let’s break down what’s wrong with ‘pre-go module’ package management tooling.

  1. Versioning dependencies.
  2. Vendoring dependencies.
  3. The necessity of GOPATH.

Versioning Dependencies

go get by default didn’t support module versioning. The idea behind the first version of go’s package management was — no need for module versioning, no need for 3rd-party module repositories, you build everything from your current branch.

Pre Go 1.11, adding a dependency meant cloning that dependency’s source code repo in your GOPATH. That was about it. There was no concept of versions. Rather, it always pointed to the current master branch at the time of cloning. Another major issue cropped up when different projects needed different versions of a dependency — which wasn’t possible either.

Vendoring Dependencies

Package vendoring is commonly referred to as the case where dependent packages are stored in the same place as your project. That usually means your dependencies are checked into your source management system, such as Git.

Consider this case — A uses dependency B, which uses a feature of dependency C introduced in version 1.5 of C, B must be able to ensure that A’s build uses C 1.5 or later. Pre Go 1.5, there was no mechanism for carrying dependency code alongside commands without rewriting import paths.

#tutorial #go #webdev #go programming #golang

Package Management in Go
1.50 GEEK