For Gant 0.4 we want to add abstractions as known from Maven, like project layout, build lifecycle, dependencies, etc ...
We want to make Gant 0.4 a powerful build DSL for Java projects, which is a bliss to use. I for myself have grown more and more unhappy with Maven2. Its basic concepts make changing requirements often so hard to implement. Many other things could be said here. We might create an own Wiki page for this. Yet I'm grateful to Maven for being a pioneer in creating a DSL for Java builds. We are going to use many of its concepts. But we think Groovy is a much more suitable base for a build DSL than XML :)
We think this build DSL is also very important for Groovy. Martin Fowler for example is blogging a lot about new ways of doing a build (based on Ruby). The advantages of having a build DSL based on a dynamic language are so enormous, that it won't take long, that more and more people discover this. There are good Ruby projects out there for doing Java builds. This is going to become for many people the first contact with a dynamic language. So Groovy should have something competitive in its stack.
We are at the very beginning and are thinking about how our DSL should look like and which features should be covered by it.
This is a snippet of a Mail from Russel Winder and my reply:
I wonder if the best way of working is to say:
1. The goal is to replace the need for Maven and Ant as drivers, but
use all the Ant tasks and the Maven repository.
Agreed. See section on dependency handling above.
2. We use a few exemplar projects as foci for discussing what the Gant
scripts should look like.
I like this idea very much. The respective projects should be complex enough. Anybody reading this, who is responsible for a build of some open source project and would like to join?
A friend of mine knows the nutch search engine project very well including its build. He says they have a complex ant based build but does not think there is any interest from the nutch commiters in changing there build. But as a guinea pig, why not. We could at least have a look at it.
One thing that we might add to this, is an additional folder for integration tests (This is also supposed to be added with Maven 2.1).
Lifecycle:
Alternative 1: The Maven way
Maven defines a lifecycle and allows to attach plugins to a lifecycle phase. Depending on the project type (jar, war, ...) there is an immutable set of plugins attached to a lifecycle. Project specific customizations is only possible by adding plugins to the lifecycle.
If we would go for this concept, we should at least make it highly and easily configurable.
Alternative 2: The Rake way
We would have tasks corresponding to lifecycle phases. The tasks are in dependency relations to each other. Each task is executed only once. The Gant dependency mechanism should be sufficient to achieve this goal. Of course Rake goes beyond that.
I think the Maven way is flawed. At least in it current incarnation and at least for one major reason. In Maven there are two ways to execute a task (plugin). Either attached to the lifecycle or calling it directly. If for a direct call a plugin needs prerequisite work, it has to manually call for example the compile lifecycle before it does its work. But if you attach this plugin goal to the lifecycle, the compile lifecycle is executed twice. Therefore you need two goals. One for direct calls, the other when attaching it to the lifecycle. Take for example a look at the assembly plugin.
I favor the Rake way. We should also have a look at buildr (which is based on Rake) how it implements its lifecycle handling.
Dependency handling:
1.) I very much like the way how dependencies are defined in buildr. You define them as part of your script like "LOG4J = log4j:log4j:jar:1.2.14". This allows arbitrary grouping of them in variables, lists, .... By this grouping you can express very good how dependencies are related to each other.
2.) I would like to distinguish between using existing specifications (repository layout) vs. using existing implementations (e.g. Maven Ant tasks).
a.) I would like to use the Maven2 repository layout and the way Maven2 describes dependencies. A dependency is described with groupid:artifactId:type:version and assumed to be available at a location that maps this to a path as known from Maven2. The remote Maven repo at ibiblio should be the default remote repo to be used.
b.) I would not like to use the Maven Ant Tasks for dependency handling or anything else (see also subsection 3.). If you use it you have to swallow all the Maven handling of dependencies, scopes and snapshots.
3.) Transitive dependencies
a.) Even if we support transitive dependencies we definitely should offer a mechanism for disabling them.
b.) If we support transitive dependencies, I don't like the way this is done by Maven2. The policy for resolving dependencies and dealing with version conflicts is carved in stone and is changing with future versions (even with minor releases). The current policies are flawed in my opinion. As the Maven Ant task for retrieving dependencies offers no way to disabled or configure transitive dependency handling, I personally would not use them. The Ivy implementation is much more configurable. We can define our own policy and don't depend one the (volatile) Maven policy. If we use a tool for dependency handling I would go for Ivy. If we don't support transitive dependencies, just for getting/putting dependencies to/from the repository, it might be simple enough not to rely on an external tool for this. The transitive dependency issue deserves a wiki page on its own. But I think the importance of the issue should not be overestimated.
4.) Snapshots and scope
Maven introduces the concept of snapshots and scopes of dependencies. I would leave them out for the first iteration. If we implement snapshots, I think I prefer the common Ivy way of dealing with this (See
http://incubator.apache.org/ivy/doc/bestpractices.html section:Dealing with integration versions). I would not support the scope concept as used by Maven.
Conclusions
My idea would be to implement a build system with a Maven2 project layout (including multiple subprojects depending on each other) and a a lifecycle task handling based on Gant tasks. I think having a good DSL for those issues would be the most important thing. On top of that a simple dependency handling for the first release might do. That would be good enough to convince many people to migrate from Ant and Maven. Another question is whether we should start to implement a Groovy Rake as a base for our build system. This would be at least partly in competition to using Ant task (Competition in the sense of different approaches. In a Rake like style the task would not be responsible for checking if a class needs to be compiled. Which is what the Ant task is doing.) But I see no reason why those approaches can't coexist.
Russel knows such an incredible amount of different build systems. I can't wait on getting his detailed input.