Buildr Review

I should start this post off by apologizing to the Buildr folks for taking so long to write up this review. I should also point out that I am currently attempting to contribute to this project, I don’t believe that sways my opinion at all since I choose to contribute after I reviewed the product. Now onto the review…

Like Raven, Buildr, is a build tool written in the Ruby language, that builds on top of Rake. Where Buildr differs from Raven is that it actually attempts to create a DSL specific to Building Projects apart from Rake. This may seem confusing, Buildr uses Rake to accomplish it’s tasks but exposes this through it’s own declarative/procedural hybrid language. At first I was turned off by this, because I was familiar with Rake and I was comfortable with writing in the Rake syntax, however after allowing myself to adjust to the Buildr syntax I find it is much more productive.

For those who are currently using Maven there is good news, you can move to Buildr without changing your repository. You simply have to change your build file from a Maven pom file to a Buildr build file.

Like the Raven Review I will now address each point I discussed in the pre-review outline.

Compile Java

As I said in the Raven review compiling is a trivial task, and just like Raven, Buildr keeps it trivial, so much so if you follow the Maven directory conventions and want the code to be compiled using the version of Java set at JAVA_HOME then you don’t have to type anything, aside from creating the generic Buildfile. To create the default build file you have to type Buildr in the folder you wish you create the file. The default build file will look something like this:


# Generated by Buildr 1.2.5, change to your liking
# Version number for this release
VERSION_NUMBER = "1.0.0"
# Version number for the next release
NEXT_VERSION = "1.0.1"
# Group identifier for your projects
GROUP = "project1"
COPYRIGHT = ""

# Specify Maven 2.0 remote repositories here, like this:
repositories.remote << "http://www.ibiblio.org/maven2/"

desc "The Project1 project"
define "project1" do

  project.version = VERSION_NUMBER
  project.group = GROUP
  manifest["Implementation-Vendor"] = COPYRIGHT
end

The file uses the current folder name to define a couple items in this file. All the Project1 references would be replaced with whatever the name of the folder you are currently in. At this point you have a working Buildfile, and can run any of the standard Buildr commands on your project.

  • clean
  • compile
  • upload
  • install
  • javadoc
  • package
  • test
  • uninstall

The Ruby community seems to implement convention over configuration better than Java as they understand sometimes you need to configure. Just like Raven you can set any of the paths for src or target. Whereas in a Maven you have to adjust your existing projects to their standard. That being said I would say it seems that the Maven suggested directory stucture makes a lot of sense, but if you currently have a different directory stucture you wouldn't be required to change it to use Buildr or Raven.

The Buildr community has developed the compile task a little more than Raven, meaning all compile attributes are avaiable. In addition Buildr uses the RJB to instantiate the Java Standard Library class responsible for compiling a java class file, instead of realying on a system call, like Raven does. This approach seems a little more reliable, unfortunately it makes it relient on JAVA_HOME being set as an environment variable, and RJB currently doesn't have a facade for JRuby, so where Raven will work out of the box with MRI Ruby or JRuby. Buildr will currently only work with MRI Ruby, although I have seen on the forums that a few people are working on making a JRuby fix. Also Buildr requires atleast Java 1.5 be set at JAVA_HOME whereas Raven only required a version of Java be defined in the PATH.

Package compiled Java into jar

I wish there was more stuff to say about this topic but it amazingly easy. In your project definition you need to add one line:


package :jar

You can set additional information using the with, include or exclude commands, but those are outside of the scope of this review. There is a lot of power in the pacakage command, and it will only get better. For instance if you want to package a war instead of a jar you have to change :jar to :war. The output will automatically be put in target. The naming convention is [project name]-[version].[type].

Compile Flex Source Code into Flash Library (swc)

Just like Raven, Buildr, was created to make building Java projects. Unlike Raven there seems to be an interest in expanding the language to incorporate other languages. Aside from myself working on Flex integration, I know there is currently a developer working on Scala integration. My original stab at Flex integration worked for the purposes of the Proof of Concept I was putting together, but after chatting awhile in the Buildr Google Group I got a feel for how the creator intends other languages to be integrated.
The end result if you are compiling flex and your src is in /src/main/flex there is only one line of code you need to add to your flex project:


package :swc

This is a little ackward since there is no explicit compile step before packaging, but you will define all your "compile options" like dependencies, target and source. But as long as you don't care what is happening behind the scenes and just trust that it does what it needs to, to accomplish what you request, there should be no problem.

Compile Flex Source Code into Flash Application (swf)

This works exactly like compiling a swc but you tell it to package type :swf, and you point the source to the Main.mxml. By default the /src/main/flex/Main.mxml is used, but you can override this using the from method on the compile task.

Retrieve and/or Build Dependencies from Other Projects/Third Party Libraries

Defining dependencies seems to makes a lot more sense in Buildr than in Raven. To define a dependency you simply add it to the compile task like so:


compile.with('com.danielroop.project2.jar')

The with method can be called multiple times, or you can pass an array to the method.


compile.with(['com.danielroop.project2.jar', 'org.apache.axis2:axis2:jar:1.2'])

The first element in the array will look locally for the jar, and the second is an artifact definition. Anyone familiar with Maven should recognize the syntax. This will look through all the repositories defined for the project for the axis artifact version 1.2, in this case this ia a jar. You can also define a project as a dependencies, and the only time I see this useful is if you nest projects withint a single Buildfile. For instance one for java, one for flex, and then the encompasing project will use the two children projects as dependencies to build a war.

By default the ibilio repository is included for your project, but you can and probalby should setup your own local repository, that will house all your person artifacts. You can use artifactory or some other maven repository to run the server, then you can add by appending the repository location to the repositories array.


repositories.remote << "http://localhost/maven"

Conclusion

Overall I believe that Buildr is a much more likely to become the defacto ruby build language, than Raven. If simply because of the active community that Raven seems to lack. So if you are up to replacing the trainwreck that is Maven 2 then I would encourage you to look into Buildr.

I do however believe the project needs some work. So to wrap it all up I will point out a couple things that I would like to see addressed.

  1. Formal Language Integration Strategy

    Currently I have been trying to base my implementaiton strategy for Flex on what was done by Scala. Which is working for now, but I would like to see a document describing some best practices for how to utilize the build DSL that has been developer for Buildr for other languages.

  2. Project Type Definition

    I go back and forth on this one, but I believe it might be necessary to define what type a project is. Currently the system is decided based on file types, which seems like it will not be robut enough, but time will tell.

  3. war type integration

    This may simply be the world I am coming from but I see a need for specialzed wars. Meaning wars for specifc langues. In my case I am looking for a Flex and Coldfusion war. This would allow me to set some property so all the coldfusion libraries would be included. I might just not understand the whole war/jar system enough to figure this out through normal dependencies.

  4. Is it BuildR or Buildr

    I personally like the project a lot more when I thought it was BuildR. I am just tired of the whole Flickr naming convention.

That wraps this review up. I hope this helps you in your decision making process when evaluating build tools. I will continue to post updates on my site as I maintain and update the flex integration into Buildr.

This entry was posted in build and tagged , , . Bookmark the permalink.

6 Responses to Buildr Review

Leave a Reply to Daniel Roop Cancel reply

Your email address will not be published. Required fields are marked *