I use Buildr partially because it has the best Scala support of any build tool, but also because it has all of the dependency-managing goodness of Maven and then some. For example, Buildr makes it almost trivial to use artifacts which aren't in a repository. You can specify the URL of a zip or tarball to download, out of which Buildr will extract the relevant JAR file and install it into your local repository. For libraries which are in a Maven repository, Buildr is by far the easiest way to install them on your project's classpath. For example:
repositories.remote << 'http://repo1.maven.org/maven2'
define 'my-project' do
compile.with 'commons-cli:commons-cli:jar:1.0'
end
After installing that in your buildfile
and placing your sources in src/main/java
, just run:
$ buildr
Buildr will take care of downloading the Commons CLI dependency, compiling your sources and running all tests (if any). As an extra bonus, it will perform all of these tasks quite a bit faster than Maven would have (really, Buildr performs exceptionally well).
What really puts the icing on the cake is how easy it is to define ad hoc tasks. Buildr is built on top of Rake, which means that anything you can do with Rake, you can do in exactly the same way with Buildr. For example, let's say that I wanted to define a task to generate documentation for my project using ReStructured Text. Buildr doesn't have a built-in task for that, but I can easily define one of my own:
define 'my-project' do
task :rst do
system 'rst2html', _('README.rst'), _('README.html') \
or fail 'Unable to invoke rst2html.'
end
end
With this, I can invoke the following from any subdirectory of the project:
$ buildr my-project:rst
Buildr takes care of canonicalizing the paths (that's what the mysterious _
method handles). I could even change things up a bit using Rake file task magic so that the rst
task only runs if the README.rst
file has changed since the last rebuild:
define 'my-project' do
file _('README.html') => _('README.rst') do
system 'rst2html', _('README.rst'), _('README.html') \
or fail 'Unable to invoke rst2html.'
end
task :rst => [ file _('README.html') ]
end
It's hard to overstate just how powerful and useful this is in practice. I used to be a die-hard Ant user, not because I liked the tool, but because it was standard and I had yet to see anything better. Maven was (and is) too complicated and too restrictive. Imagine trying something like the above in Maven. You would have to write an entire plugin, just for that!
The only problem with Buildr is the fact that it isn't very widely used, and so a) not a lot of people have it installed, and b) not a lot of people know how to use it. It's not a difficult tool, but it's harder than Ant if that's what your dev team already knows. Fortunately, both of these problems are easily remedied given enough time and exposure.
If you think about it, the question isn't "Why use Buildr?", it's really "Why use anything else?" The advantages afforded by Buildr are so substantial, I really can't see myself going with any other tool, at least not when I have a choice.