Package Versions in Go
∞The title is a bit misleading, but I like this approach to versioning/dependency management.
In this system, every library has a name, which is a string like “foo” or “bar”, and a version, which is an integer. This is a marked contrast with most other systems, where the version is a string or some more complicated data structure. The Amiga’s rough equivalent of dlopen has a signature like this:
loadLibrary(name string, minVersion int)
The idea there is to be as simple as possible but no simpler.
And, to make updates work:
For this to work, there is a strict social contract that library authors have to abide by: don’t break existing users. The rules are, 1) all changes must be compatible, and 2) increment the version number in every release. […]
So what if your Amiga library does need to make a backwards-incompatible change? After all, it’s not always possible to predict how a library will be used in the future. What once was a good design might prove problematic some day. In that case, you pick a new name. Period. If your library is “foo” you can call it “foo2” or “bar” or whatever else you can think of. It is, mechanically, a whole new library now. Clients then must opt in to your new library by changing their loadLibrary call to specify the new name. They will pick up new versions implicitly and automatically, but they’ll only pick up a new library explicitly and consciously.
I like this very much! It’s simple, makes things explicit, and (tries to) avoid breaking libraries.
You don’t even need to make it a function, it’s enough if the version manager uses the same scheme. minVersion
, and new library names on breaking changes.