Sunday, March 23, 2014

Maybe Go without dependency management can be a good thing

Within the Go community, there are at least two frequently discussed issues:

  1. Generics
  2. Dependency Management
My purpose here isn't to advocate either side on either issue, but I do want to suggest one perspective on the lack of an official Go dependency manager.

Decentralized Sources

The go get command goes straight to the source. It's nice that there's (practically) not really any single point of failure that could ruin everyone's go get. While a central repository of packages and their dependencies could solve the dependency management problem, it also can be the bottleneck. Remember what happened to npm a few weeks ago? (Check out the comments on that link. Holy moly!)

Then there's all this other security jazz and downtime that you have to worry about.

And no central repo == no agendas; nobody saying what you are and aren't allowed to publish/distribute (aside from the usual licenses and copyrights we're used to).

I realize that a central repo isn't necessarily the only possible solution, but not having one definitely has its perks.

Go projects stay actively updated

Yes, with no dependency manager, it can be a pain if a library your dependency uses suddenly changes and breaks your code, all the way from two or three dependencies upstream. I've actually never been bitten by something like this. But I hear it happens: either from an intentional API change (major version) or an accidental bug.

The fact is, people still need their code to work. Fortunately, open source projects are easy to contribute to. When an upstream dependency has a breaking change or a new bug, all its downstream users are very quickly motivated to fix it and stop using the deprecated API. This means that projects -- especially popular ones -- generally stay updated as frequently as its dependencies.

Worst-case scenario, somebody forks the project to keep the old, "working" version. One global search+replace later, you're done.

I find the idea of regularly-updated Go projects very appealing. (I know too many Python, C++, and PHP projects which are dead in the water.)

Careful development and deployment

You have a lot of power. Think twice before you type git push origin master and hit Enter. Those hundreds of projects which depend on your package are at your command and mercy. Your push, or your merge into master, may have far-reaching effects.

This encourages developers to use good source control habits: branch for feature development and bug fixes or testing, and merge carefully into master.

It also means you should plan your projects with solid semantic versioning. Decide what 1.0 looks like and stick to it (timelines are irrelevant here). When you introduce 1.0, don't break it. Sure, add stuff for 1.1 and 1.2, but don't break master until 2.0. And if you have enough users, make sure to tell them about it somehow.

As Go is a meticulously engineered, carefully crafted language (mostly), and so should its projects be. Forethought about design and deployment has allowed The Go Authors to stick tightly to their versioning guarantee: Go 1 will have absolutely no breaking changes. And everyone has been happy.

Basically, the Go project is itself a good example of how to develop and deploy your own Go projects.

Just Go with it

Fortunately, this isn't Node or PHP: your production applications are executed from compiled binaries, not straight, interpreted source code. Those binaries doesn't rely on what go get currently goes and gets. Meaning: your production apps are safe (should be safe) from willy-nilly 3rd-party developers that deploy a breaking change upstream. On the occasion that this does happen, you have time. You won't deploy a broken app. You can't compile code that doesn't build, so it won't get into production.

Admittedly, I'm not too passionate about finding a package management solution for Go. I think a few of the unofficial ones are interesting and clever. But for now, I've been totally fine just writing Go code, and when I need a package, I go get it. And I'm a happy little gopher.