So build tools have been a long-standing pain point when working on Clojure projects. Most projects have used JVM-centric tools like ant or maven, which are far more complicated than what you need to build Clojure, and on top of that must be configured with XML. It could be made to work, and in the case of projects with significant dependencies it was much better than doing it by hand, but it was a pain.
Last week I launched Leiningen, which is a project that brings a native build tool to Clojure. It seems to have people pretty excited about it, which leads me to believe I'm far from the only one who's been feeling the pain here. It's configured using a Clojure file called project.clj like the sample below.
(defproject leiningen "1.0.0-SNAPSHOT" :description "A build tool designed not to set your hair on fire." :main leiningen.core :dependencies [[org.clojure/clojure "1.1.0-alpha-SNAPSHOT"] [org.clojure/clojure-contrib "1.0-SNAPSHOT"] [ant/ant-launcher "1.6.2"] [org.apache.maven/maven-ant-tasks "2.0.10"]] :dev-dependencies [[org.clojure/swank-clojure "1.0"]])
Update: Leiningen now has a tutorial that is much more comprehensive than this.
This one's pretty straightforward: lein test searches the test/ directory for namespaces and runs the tests in each.
Running lein jar will compile your code and package it
up as a .jar file. If you specify a
:main class in
your project config, this will be an executable jar with the class
you specified. If you just want to compile your code, there's
a compile task for that too. Alternatively if you want
to build a standalone jar that includes all your project's
dependencies for easier distribution, you can do that
with lein uberjar.
This is the fun part. Rather than tracking down and downloading
all your dependency jars manually (or worse: checking them
in to your source repository), Leiningen provides
a deps task to automatically download them and place
them in the lib/ directory. This uses some Maven code under the
covers, but don't panic—you won't have to see a bit of XML
unless you want to. It pulls from the central Maven repositories
by default as well as
from Clojure's nightly builds
and http://clojars.org. Clojars
has built-in search, but if you want to pull a library from the
central repository, you can search for it
on Jarvana. You can also specify
development dependencies with the
key for things that shouldn't be pulled in at production or
included in the standalone jar; the syntax is the same.
By a stroke of luck I dropped hints about Leiningen the week before I made a public announcement only to find out that Alex Osborne was approaching the same problem from the other direction. He'd been cooking up a web site and service for hosting Clojure libraries independently of my work on Leiningen, and we started talking about ways to integrate the two. So now Leiningen makes it easy to publish jars publicly via Clojars so other projects can depend on them. The day after announcing Clojars, Alex was interviewed on InfoQ about the site and how it interacts with Leiningen, so I was thrilled to see both our projects getting exposure so quickly.
Soon after the 0.5.0 release, Alex along
with Dan Larkin (of the wonderful Clojure JSON
library fame) started diving in and adding
We've got a
few more tasks on the plate targeted for a 1.0 release, but
should be right around the corner. Update: Leiningen
1.0 released. If you'd like to say hi or drop a line, there's
a #leiningen channel on freenode as well as a mailing
list. If you found this useful, you should take a look at the Clojure PluralSight screencast.
Logo by Loren Broach.