I recently got back from the Clojure Conj conference in Raleigh. The sessions were great, but the main highlight for me was meeting with the developers of Cake (an alternate Clojure build tool) and discussing how we could collaborate on the future of build tools in Clojure. As was announced elsewhere, we will be taking some features from Cake and merging them into Leiningen 2.0 as well as just having more hackers involved in development efforts.
The development of Leiningen 1.x pretty much just fell out of the usage patterns we saw during my time at Sonian as an early adopter of Clojure. We used Maven for eight months, tried to make it work, and then took our experience from the pain we saw there to Leiningen. Some features (especially checkout dependencies) arose directly from finding certain operations with multi-module Maven builds extremely cumbersome. But in general nearly everything about Leiningen so far has been obvious. I wouldn't say it practically wrote itself, but once the central model of a project map and resolving/applying tasks from defns was established, the only really tricky thing was being strict about establishing a narrow scope and knowing when to avoid adding features.
"Version 2" is the most dangerous phase in a software project's life.
So now we're digging into the question of what bigger-picture changes could be made to improve Leiningen if we leave backwards-compatibility out of it. The biggest improvement we've seen implemented so far is switching over dependency resolution to the Aether library via Chas Emerick's Pomegranate library. Aether is a library that contains all the dependency management features from Maven extracted into an independent module—basically designed with exactly Leiningen's use case in mind.
But there's more coming. Cake has had the ability to run project code in the same process as the build tool, significantly speeding up many operations, which is in the process of being ported over to Leiningen. I've been working on explicitly delimiting the parts of Leiningen that comprise its public API as part of a separate "leiningen-core" library which other tools can depend upon. We're looking at adding something like "profiles" do bundle up configuration sets which can be activated in given contexts.
With all these ideas flying around I hope we can buckle down and get some solid design discussions resulting in well-factored features. If you've been looking to contribute, now is a great time. Join the #leiningen channel on Freenode and hop on the mailing list.