in which projects may be more easily compiled and distributed

leiningen portrait

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.

Dependency Management

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 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 :dev-dependencies key for things that shouldn't be pulled in at production or included in the standalone jar; the syntax is the same.

Publishing with Clojars

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.

Coming Soon...

Soon after the 0.5.0 release, Alex along with Dan Larkin (of the wonderful Clojure JSON library fame) started diving in and adding features. 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.

« older | 2009-11-26T06:28:10Z | newer »