Maven Snapshots
Or: How to use Maven snapshots without setting your hair on fire.
Ever depended on a Clojure library with a version that ended in
-SNAPSHOT
? That's what's called a Maven snapshot.
Maven snapshots are a handy tool to provide pre-release builds to those who are interested. In contrast to proper releases a SNAPSHOT release can be "updated". And that's where the trouble comes in.
Let's say you depend on a snapshot because it contains a fix you
recently contributed to your favorite open source project. A
week later another fix is added and released under the same
0.1.0-SNAPSHOT
version.
Now it turns out that second fix contained a minor bug. No big deal, it's a pre-release after all. The problem with all this however is that you (Maven) will automatically use the new SNAPSHOT, no action required. A dependency you use in your project changes without you being aware of it. Suddenly stuff breaks. You wonder what happened. Did you change anything? No? Frustration ensues.
Because of this for a long time I thought SNAPSHOTS are evil and
instead of using them library authors should release development
builds with a qualifier like 0.1.0-alpha1
. I still
think this is a good practice and try to adhere to it myself as
much as possible.
In the meantime there is another way to safely depend on Maven snapshots though.
Whenever you push a SNAPSHOT version to a Maven repository (like
Clojars) it does not actually overwrite the previously uploaded
jar but creates a separate jar with a version like this:
0.1.0-20170301.173959-4
. Once the upload is
complete it merely changes the SNAPSHOT version to point to that
release. All previous releases are still available (by default
Maven repos only keep the latest SNAPSHOT version but Clojars
keeps them all).
This means instead of depending on a mutable version you can now depend on an immutable version. Oh do we love immutability.
[group-id/project-id "0.1.0-20170301.173959-4"]
Finding these version identifiers isn't the easiest thing but basically:
- you go to the page of a jar on Clojars, e.g. adzerk/boot-cljs
- in the sidebar that lists recent versions, click "Show All Versions"
- versions page you can find a note at the bottom that leads you to the Maven repository
- if you click on a SNAPSHOT version there you get to a page that lists all the stable identifiers for that version
To get to the Maven repo page directly you can also just put a
repo.
subdomain in front of a given Clojars project
url:
https://clojars.org/adzerk/boot-cljs/
https://repo.clojars.org/adzerk/boot-cljs/
^^^^
And they depend on SNAPSHOTs happily ever after.