Go comes with a
go tool – the standard way to fetch, build, and install Go packages and commands. It uses code repositories URLs like
github.com/AlekSi/nut for import paths. This is clean and clear solution, but there are two problems with this approach.
First, it doesn't support package versioning –
go get always installs latest version. If someone wants to install previous one, he/she has to use
bzr manually. Therefore, package authors are forced to maintain backward compatibility since first commit. If they want to change or remove some existing API, they should use a new import path. In practice, most authors don't really care about it. Change logs are also seldom.
Second, also in practice, many authors are moving their code to other places (for example, from Google Code to GitHub), renaming repositories (
web) or just deleting them (at the time of this writing many links in Go Projects Dashboard are dead). Yes, it's a social problem, but we still should deal with it.
So how can we solve those problems? Big companies typically have special repositories for third-party code. Once imported there, code is never deleted. And they have a budget to fix their world of dependencies. So,
go get probably works okay for
google/... packages. Smaller companies and individual developers are able to fork all third-party packages or bundle them with their application and take pain of updating them only when needed. But what should package authors do if they want to use other packages?..
Central repository for versioned packages, similar to PyPI for Python, RubyGems.org for Ruby, NPM for Node.js and Packagist for PHP solves those problems. Published packages (called "nuts") are never deleted, and versioning schema allows to install exact version, or version matching pattern (like
2.*.*). Some metadata like package name and documentation is stored in Go package itself, the rest is in small file called
So – let's work together for a better Go ecosystem!