Thursday, February 19, 2009

Can Has Build for Java

While not sleeping this morning, I thought through some ideas I'd had in the past on build systems. Ant is too manual, and coding in XML is a pain. Maven is too unreliable, and it sure requires a lot of configuration and magical incantations for a convention-based system. I want minimal dependencies, real convention-over-configuration, and a sane way to extend.

For the moment, I'm affectionately calling my (hypothetical) system "Can Has Build". Here's what a basic project directory structure looks like:

project-name/
build.jar <-- the Can Has Build main jar (which is very small and executable)
lib/ <-- jars needed for build and at runtime go here
src/ <-- source folder for which the class files will go in your jar
test/ <-- source folder for unit tests


After running the build (which by default does a clean build all, since your IDE is probably doing incremental compiling for play-as-you-go anyway; I think build systems are primarily for making a final product, so it's all right to be slow):

project-name/
build.jar
lib/
out/ <-- not 100% sure what to call this ("test" and "target" both start with "t")
project-name.jar <-- or maybe project-name-SNAPSHOT.jar
test-results/
...
src/
test/


All you need for this to work is a JDK and "java -jar build.jar". Can Has figures out everything else on its own.

Say you want to specify a version number? Then add a "project.xml" under your project dir:

project-name/
project.xml
... all else as before ...


Why XML? Because I know XML better than properties files, and I think most other devs do, too, and it allows for hierarchical data if needed, but to give an idea of what I think would go in here at first, here's an example:

<project
name="Can Has Build"
jar-name="build"
version="0.0.0.0.0.0.1-SNAPSHOT"
version-jar-name="false"
main="canhas.build.Builder"
/>


I mean, is that so bad? I can imagine JRE version requirements and so on, too.

So, say I want custom tools in my build such as Test Tool X or Parser Generator Z or Class Bundler/Renamer Q? Or my own custom script? I envision a "build" subdir:

project-name/
build/
lib/ <-- jars needed just at build time
src/ <-- source code for custom build scripts
tools/ <-- auto-registered tools that can filter the automatic build process
... all else as before ...


Or something like that. Again, this is convention-over-configuration. These custom tools should get picked up automatically by "java -jar build.jar".

I've also considered conventions for grouping related projects and easy specification of dependencies between them, but I'll forgo commenting on that right now. In any case, all 3rd-party libraries would need added manually. That's the reliability thing.

So, the summary, Can Has (which doesn't exist, so feel free to make it) has the following features:
  • No dependence on someone else's server being up.
  • No configuration needed for basic builds.
  • No dependencies except a JDK (or just JRE if you bundle your own compiler under "build/").

2 comments:

  1. A good idea. The simplicity of it makes it very appealing. I too am a fan of including libraries rather than being dependent on a repository. I would certainly be interested in such an approach.

    I have a question which is customised tasks?

    How would I perform a non build task, with this system? For example I usually like to build a wrapper exe for an application. At the moment I use an Ant task to build the executable.

    Ant solves this problem becuase whilst it might not have all to tools you need, you can either make your own Ant Task, or use a system call to generate the result thereby covering them from having to support every tool available.

    If the Can Has Build system supported custom tasks, I think it would be a stronger concept.

    ReplyDelete
  2. Robert, thanks very much for the feedback. I did actually cover custom tasks, but it's easy to get things lost in a long post. Look at the section on the "build" subdir. I figure that there's a convention-based way to get your extensions automatically registered, and you'd simply code them against a normal Java API. (Of course, that also means you could write your extension any JVM language you want, so long as you include the jars/whatever for that language in your project.)

    ReplyDelete