Revisiting Clojure Nix packaging#
Fri, 31 Aug 2018 12:43:27 +0000
Slightly over a year ago I wrote about how to build a Clojure project with Nix and this week I had occasion to refer back to it because I want to have a production-style dogfood build of Epsilon
It's a bit simpler now than it was then, because in the intervening
time Clojure has added Deps and CLI
tools which gives us a simple
readable EDN file in which we can list our project's immediate
dependencies (see here deps.edn for
Epsilon ) and
a function resolve-deps
that we can call to get the transitive
dependencies
We embed this function call into a script which dumps a JSON file with
the same information, and then whenever we add or update deps.edn
we run
$ CLJ_CONFIG=. CLJ_CACHE=. nix-shell -p clojure jre --run \ "clojure -R:build -C:build -Srepro -Sforce -m nixtract generated/nix-deps.json"
(Note that the clojure
command will fail silently if it cannot find
a java runtime on the path, or if the current directory contains a
malformed deps.edn
file. Each of these problems took me a while to
find - I tell you this so that you may learn from my mistakes)
The second half of the puzzle - build time - is not much changed from
how we did it last time around, though I did take the opportunity to
make it use the generic builder instead of making its own
builder.sh
.
Probably I should point out that this downloads all the dependencies
into /nix/store
as JARs and builds a classpath so the JRE can find
them - it doesn't make an uberjar. This fits my current use case,
because I want to run it on a NixOS box and separate jars provides at
least the possibility that some of them might be shared by more than
one app. I will obviously have to come back to this if/when I need to
build an uberjar for distribution.
Also, if you are doing advanced things with CLJS external libraries (like, Node dependencies and stuff) then this will not help and you are on your own. There is a name for the (CL)JS dependency ecosystem, it's a compound word in which the first part is the collective noun for a collection of stars, and the second part rhymes with "duck"