Gant 0.4 - Creating a powerful DSL for building Java projects

View: New views
20 Messages — Rating Filter:   Alert me  
< Prev | 1 - 2 - 3 | Next >

Re: Gant 0.4 - Creating a powerful DSL for building Java projects

by hdockter :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On May 22, 2007, at 2:49 PM, Tom Nichols wrote:

> On 5/22/07, Hans Dockter <mail@...> wrote:
>> I wonder how Ivy plays together with the Maven based ibiblio
>> repository. Does it use it only for the jars? Or does it try to
>> evaluate the dependency information in the pom.xml as well?
>
> IIRC, There is a separate Ivy repo that basically holds the Ivy "POMs"
> for artifacts, but the artifacts themselves are still in the Maven
> repo.
> http://www.jaya.free.fr/ivyrep/
> But it seems to me that there is a lot less there than what is in
> Maven.  I believe Ivy will read Maven POMs in the absence of Ivy
> files.  But in that case it would seem Ivy is limited to the same
> information that Maven is.

At least I hope Ivy makes its easy to create a different module with  
a new set of dependencies and just use the Maven repo for getting the  
jar.

This is another reason why we should definitely allow disabling of  
transitive dependency handling and just use the Maven repo for  
getting the jars.. We can model them anyway via variables and lists  
(see my former mails). And for many people this might be good enough.  
It has the additional advantage of having a complete overview in the  
build script of all the dependencies involved and their relationships.

But if transitive dependency handling is so much wanted by our users  
we gonna try offering them Ivy. We can issue warnings and tell them  
that we (I) don't think that this is so important. If it starts to  
bother them, they can disable it. The major benefit of our tool is  
anyway something else.

>
> Not sure if this has already been asked but -- Maven comes with
> _a_lot_ of good stuff.  Is it so fundamentally broken that it would
> not be worth fixing?  I mean, help fix Maven and build on top of that,
> or start from scratch while still trying to use the Maven repo and
> POMs for dependency handling...  It sounds like a lot of people think
> Maven is a lot cause at this point :(
>

We might ask what this 'lot of good stuff' is.

Maven has created a lot of infrastructure code. They modeled a build  
DSL with XML, including inheritance property handling, XDoclet style  
configuration for plugins. They have implemented their own IoC  
container for some reasons. All this is stuff we don't need or want.

- Dependency handling: We have discussed this. The Maven dependency  
handling is seriously flawed.
- Plugin-Architecture: We definitely don't want to use this. Try to  
enforce the simple rule that a certain system property is set. Have  
fun with the Maven enforcer plugin. In Groovy this is a one liner.  
Actually we want to go the opposite direction. If people want to have  
a stronger separation between the logic of a task and the calling of  
it, well we offer them classes, methods and closures. ;)
- Lifecycle handling: In my original email, I have pointed out why I  
prefer a different way of dealing with it than Maven does.
- The set of existing plugins for Maven: What is the delta between  
the Maven plugins vs. Ivy + Ant tasks? I don't think the delta is  
significant. We just to have write simple wrappers for the Ant task,  
which configure the Ant tasks with our project data. Looking at:  
http://maven.apache.org/plugins Which one would not be easy to  
implement with the help of Ant/Ivy? Probably the assembly plugin.  
Anything else which is relevant?

Looking at this. Why should we use Maven2 as a base? I can't see any  
major advantage but a lot of disadvantages. I consider this as a no go.

- Hans


---------------------------------------------------------------------
To unsubscribe from this list please visit:

    http://xircles.codehaus.org/manage_email


Re: Gant 0.4 - Creating a powerful DSL for building Java projects

by hdockter :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On May 22, 2007, at 3:44 PM, Tom Nichols wrote:

> On 5/22/07, Hans Dockter <mail@...> wrote:
>> Finally, some goodies from the Maven dependency handling:
>>
>> 1.) Let's say you want to use dom4j. You want to use the xpath  
>> functionality
>> of dom4j. Dom4j needs Jaxen for supporting this. As not everybody  
>> uses the
>> xpath functionality, Jaxen is an optional dependency of dom4j.
> ....
>> You have to declare Jaxen as a first level dependency and the build
>> expresses no longer, that Jaxen is used in this project only as a  
>> dependency
>> of dom4j. Yak!!!! Welcome back in the jar hell!
>>
>> 2.) Let's say you want to use dom4j and some other project. Let's  
>> say you
>> want to use an XPP reader with dom4j. As this is an optional  
>> dependency, you
>> have to do the same as above. Now imagine the other project has a non
>> optional dependency to xpp3_min. Either you end up with xpp3 and  
>> xpp3_min (a
>> subset of xpp3) in your classpath. Or you have to do say:
> ...
>
> So for optionals you need to specify a direct dependency, and for
> modules with different names, you have to add an exclude for one of
> them.  Yes, I can see how this is a pain (especially if several
> dependencies used xpp_min), but I don't feel it's a show-stopper.  I
> think I'd still rather add some excludes than have no transitive
> dependency handling.
>
> How does buildr deal with this?  It still must use the Maven POMs.

It does not use the POM. It only uses the conventions, how to find a  
dependency described by groupId:artifactId:type:version in the  
repository.

See the discussion here: http://groups.google.com/group/buildr-talk/ 
browse_thread/thread/6ac4ab049c0ba2e9

>
> Maven has some other things that I don't necessarily like, such as
> limited scopes and the inability to have multiple top-level source
> folders.  But Maven's dependency handling isn't all that bad.
>
> How about this --
> Would it be reasonable to make this functionality pluggable?  i.e.
> Allow Maven to handle it, or allow Ivy or some other strategy?

I think we should try Ivy and make it pluggable.

>
> To be honest, I'm not very familiar with Maven's internals _at_all_
> and I don't think I could contribute much more than this discussion to
> the development effort.  So I understand how much my words are worth.
> But I just hate to see things re-invented unless they have to be.
>

See my response to your other email.

- Hans

---------------------------------------------------------------------
To unsubscribe from this list please visit:

    http://xircles.codehaus.org/manage_email


Re: Gant 0.4 - Creating a powerful DSL for building Java projects

by hdockter :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On May 22, 2007, at 3:23 PM, Jochen Theodorou wrote:

>
> I guess we wouldn't use the maven repo if it were not such a good  
> source of jars.
>
> bye blackdrag
>

It is a good source for jars. The language (Maven2 poms) to describe  
the dependencies is insufficient and leads to serious problems. I  
think with Ivy you can create your own modules for describing the  
transitive dependencies and just use the Maven repo for the jars.  
Then your dependency descriptions are fine. But it makes some work,  
which you could also invest in just declaring the dependencies via  
variables and lists. For many people this is good enough I think.

To present one of the earlier examples again:

JMOCK = group("jmock", "jmock-
cglib", :under=>"jmock", :version=>"1.1.0")
JUNIT = "junit:junit:jar:3.8.1"
TEST_DEPS = [JMOCK, JUNIT]

Our tool would use this information to just get the above jars from  
the remote repo.

I'm fine with offering both options to our users (Ivy and simple  
declaration in the build script). We have to come up with a nice  
syntax to offer a unified handling.

- Hans



---------------------------------------------------------------------
To unsubscribe from this list please visit:

    http://xircles.codehaus.org/manage_email


Re: Gant 0.4 - Creating a powerful DSL for building Java projects

by Russel Winder :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Mon, 2007-05-21 at 22:08 +0200, Hans Dockter wrote:

> For Gant 0.4 we want to add abstractions as known from Maven, like
> project layout, build lifecycle, dependencies, etc ...

In terms of goals, I would say something more like the following:

Gant is currently a very lightweight wrapper around AntBuilder that
provides an easy way of specifying targets.  It provides a way of
programming dependencies between targets and some standard command line
processing.  Currently, Gant follows the Ant model of requiring the
tasks to manage file-level dependencies, so it follows the Ant
tradition, it does not follow the Make, Rake, Rant, Scons tradition --
where the system calculates relationships and dependencies between files
and other things and triggers actions to ensure dependencies are met.

There is an essential dichotomy between the Ant and Make traditions that
I think has to be recognized and used as a basis for planning.  In
particular, Raven and Buildr are based on Rake, from the Make tradition,
and build on that a mechanism for scripting Ant tasks.  This seems to be
a valuable integration of the two traditions.  The downside is that it
is entirely Java build focused, and not build focused -- that is left to
Rant, SCons, Waf.

> 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 :)

Some important points here.

1.  Gant appears to be focusing only on Java/Groovy builds.
2.  The Maven repository is a massive resource.
3.  Internal DSLs are the way forward for build systems.

[ . . . ]

> > 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.

I am not sure it is necessary to actually work with real projects, but
we need to create a set of highly stripped down test projects that we
can amend in order to drive the way that the Gant scripts look.

I wonder if we should start by creating a set of test projects in the
Gant Subversion store?

> Project Layout:

> I like the project layout used by Maven2. It is defined
> here: http://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html
> 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).

I have a problem with the core structure, but only a small one.  Calling
the code directory src/{main,test}/java has led to a situation where for
other languages you have src/{main,test}/groovy.  The source code is
partitioned by language in order to allow the plugins to know what to
do.  I wonder if all the source code should just appear in
src/{main,test}/code and let the suffixes of the files determine
language as they do for all other tools?
 

> 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.
What are the real purposes of the lifecycle states?  I think they are
two-fold:

1.  The provide a set of standard useful targets that mean every project
is the same.
2.  They provide a mechanism for scheduling the behaviour of the
plugins.
 
I would suggest that for Gant, 1 is good and 2 is irrelevant.

> 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.

With rigidity comes pain.

> I favor the Rake way. We should also have a look at buildr (which is
> based on Rake) how it implements its lifecycle handling.

Buildr is interesting because is provides a declarative layer over an
imperative infrastructure.  This means it can harness the power and
flexibility that means that the default rigidity does not create pain.

> 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.

Isn't this just a notation for saying which version of which jar is a
primary dependency.  Maybe I am missing something, but I don't see
anything special here.  Necessary yes, special no.

> 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.  
I think I must be missing something about this issue.  Using the Maven
repository is I think absolutely necessary.  It is too big a resource to
ignore.  Even Ivy recognizes this :-)  However, relying only on the
Maven repository is a bad idea.  So making alternatives to the Maven
repository strikes me as a good idea though in the main the Maven
repository will be providing most of the material.

> 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.
I think I may be misunderstanding the currently conventional use of the
term "transitive dependency" here, or at least its implementation in
Maven and Ivy.

To me "transitive dependency" is all about a project specifying its
primary dependencies and then the repository management ensuring that
there is closure over all necessary dependencies.

The example I have is the Solaris package management system, the RPM
package management system for Red hat and Fedora and the Debian package
management system for Debian and Ubuntu.  If you load a package with the
Debian packaging system, then it ensures that there is closure over all
dependencies.  If you use the Solaris packaging system it just loads the
package and the system administrator has to work out what other packages
need loading.  The word crap springs to mind.  This is why yum has to do
so much work to manage the RPMs.

In a project, I want to specify only the things I actually depend on.
The build system then has to be responsible for ensuring all the
dependencies are met.  The question is how to do this and what is being
shipped in a package.  This is by definition platform dependent.
Fedora, Ubuntu, Debian, Windows all have different strategies for
installing jars and for managing the default classpath.  So a build
system has to understand deployment and packaging in a way that Maven
fails to do.  I don't know how Buildr handles this just now.  Of course
there is the versions problem, which most people solve by shipping
copies of jar files, which leads to classpath/jar hell, which leads to
pain, which leads to suffering.  

> 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.

I am not sure about snapshots, I rather like the idea of having a
"bleeding edge" mechanism of working with the latest in everything.  But
then I used to run a mix of Debian Testing and Debian Unstable so
clearly I am a sucker for punishment :-)

Scopes in Maven are, I think, a way of managing the lifecycle and hence
classpaths.  It strikes me as useful to be able to say which jars are
required at which stage of working so that the classpath can be the
minimal required.  The problem with Ant is it is all too easy to just
load all the dependencies into a single classpath and use it all of the
time.  This strikes me as hiding away many dependency problem.  By
correctly scoping when a dependency is needed, you control the classpath
and so raise problems and issues early.
 

> 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.
Working with the Maven 2 standard layout has the advantage of making it
easy for Maven projects to switch.  So from a marketing perspective this
is a good idea.  Ant based projects are not a problem so there is no
barrier there.  Of course there is the Maven 1 / Maven 2 structure
differences.  I am assuming we go with the Maven 2 structure and worry
about Maven 1 later?
 
--
Russel.
====================================================
Dr Russel Winder                +44 20 7585 2200
41 Buckmaster Road              +44 7770 465 077
London SW11 1EN, UK             russel@...


signature.asc (196 bytes) Download Attachment

Re: Gant 0.4 - Creating a powerful DSL for building Java projects

by Russel Winder :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Mon, 2007-05-21 at 16:24 -0400, Tom Nichols wrote:

> This sounds great.  One comment I have:
>
> I would _very_much_ like to have some sort of transitive dependency
> handling.  I use Maven2, and have never run into issues where
> transitive handling was a problem.  Not to say problems don't exist --
> I've read it a million times so I won't try to deny it.  But when I
> use Ant I use the Maven antlibs -- I personally would rather have
> Maven's (transitive) dependency handling than none at all.  I started
> looking into Ivy but it felt too configuration heavy so I gave up.
> Maybe I didn't stick with it long enough.
I have to admit I am not that familiar with the Maven 2 vs Ivy
differences on the issue of transitive dependencies (assuming we mean
the same thing by the term transitive dependencies).

I think we have to require the build system to calculate the closure
over all dependencies, it cannot be the responsibility of the project to
handle this.  However, it becomes the responsibility of the build system
to be transparent about what is happening and why so that the any
problems and errors are clear when a system gets built.

> But that's my take on the matter.
> Thanks.
> -Tom

--
Russel.
====================================================
Dr Russel Winder                +44 20 7585 2200
41 Buckmaster Road              +44 7770 465 077
London SW11 1EN, UK             russel@...


signature.asc (196 bytes) Download Attachment

Re: Gant 0.4 - Creating a powerful DSL for building Java projects

by Russel Winder :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Mon, 2007-05-21 at 22:54 +0200, Hans Dockter wrote:

> I knew that transitive dependencies is going to become a controversial
> issue :)

> If we implement it, I think transitive dependencies should be
> expressed via a terminology we offer in our DSL. By that we could for
> example take the weight from a heavy Ivy configuration :)

Is there an `if' here?  What is the alternative?

Why does a transitive dependency need a notation, it is calculated by
the build system internally.

> But I really don't want to become dependent on the Maven
> _implementation_. They offer one and only one way of handling
> dependencies (e.g. how to resolve version conflicts). They are not
> configurable. The policy how Maven resolves transitive dependencies
> has changed for example from Maven 2.0.5 to 2.0.6. I could write quite
> a bit about Maven's dependencies handling. But I'd rather ask Russel
> to set up a wiki page for this, where we can gather bad existing ideas
> and good ideas.

You have far more knowledge of the Maven system that I do, so if it has
a problem then we have a problem.

The point of a wiki is that it is a socially structured device.  Please
feel free to start the page!
 

> My main concern is, to offer some automagic which sounds good on first
> sight. But when it comes to complex builds it shows its ugly head.
> This is what really puts people off with Maven2. And I want to promise
> those people that they will have a completely different experience
> when using our tool. So rather no automagic than a flawed automagic.
>
> We might come up with something that offers a more modest but reliable
> support for transitive dependency handling. For example a tool that
> outputs the transitive dependencies on the console and you can copy
> them if you like into your build script.
This sounds to me like the wrong solution.  I think I begin to see the
problem you are driving at.  This means we need a data structure that
specifies information that is then used to condition the dependency
calculations.  If Maven 2 is not capable of supporting this then we need
something different.  I wonder what Buildr does on this?

> My problem with Ivy is, that I haven't used it. I have just read its
> documentation. It makes a very good impression to me and seems to
> offer a better solution for dependency handling than Maven2 (which I
> have used a lot in complex scenarios). But I would like to have more
> experience with Ivy.

Ivy has been pushed by a lot of people for a long time on the Groovy
lists.  The original intention of the rewrite of the Groovy core build
system was to use Ant+Ivy.  However, it just seemed easier to use Ant
+Maven.  So there is clearly an issue here.  The Ant Maven plugins are
easier to get started with.

--
Russel.
====================================================
Dr Russel Winder                +44 20 7585 2200
41 Buckmaster Road              +44 7770 465 077
London SW11 1EN, UK             russel@...


signature.asc (196 bytes) Download Attachment

Re: Gant 0.4 - Creating a powerful DSL for building Java projects

by Russel Winder :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Tue, 2007-05-22 at 00:19 +0200, Jochen Theodorou wrote:

> As  I was encouraging a build tool written in Groovy but never had the
> time to really help with Gant I feel a bit guilty ;) Anyway I had of
> course some "fantasies" about how such a tool should be and some maven
> things don't fit that. One of that is the project layout and plugins. I
> very much dislike the maven way of forcing people to make additional
> directories for plugins that are used in the build and additional
> directories to separate what the developer thought belongs together. I
> guess it is no problem to help if the developer keeps a certain layout,
> but he should be able to change that very easily.

Fantasies are good ;-)

Maven plugins are not good.

> My basic idea of a lifecycle that time was to have simple method calls:
>
> def build() {
>    init()
>    compile()
>    test()
>    jar()
>    deploy()
> }

If the lifecycle is fixed then there is no need to program it per se.
Also of course you need entry points, hence the idea of targets rather
than just functions.

> where each method can be overwritten and add things to the lifecycle...
> Now I know that will not fit, since these lifecycly methods do need
> additional informations like descriptions and "task" dependencies. I
> guess one diea back then was to have a set of fixed top level methods
> for that like
>
> def compile(){
>    meta {
>      description "call javac task from ant to compiles all java files"
>      compilation from:".java", to:".class"
>    }
>    action {
>      ant.javac(...)
>    }
> }
This could be made to work but I suspect you end up with a single
program.  A build specification has to be constructed along the lines of
an event driven system:  a build specification offers a set of things to
do to the user, and the user then selects what is to be done.  The
single flow of control of the above examples don't really work.

> well, something like that. meta and action would be special methods
> activated depending on the phase the build is. Other methods would be
> allowed too, marking normal dependencies for the task. Well that was my
> idea back then.. of course with some defaults for each method so that
> someone could write a class like that:
>
> class CleanAlwaysBuild extends DefaultBuild {
>     def build() {
>      clean()
>      super.build()
>    }
> }
The original Gant specifications were class based but the general
response of users was that they wanted script based.  Of course a script
is a class so there are possibilities for using inheritance.

[ . . . ]

> but maybe you guys should point out some things that are good. In any
> case you should point out what Gant can do and what not.. I mean there
> must be a reason why 0.4 should be so different... or should it be not
> so different and I misunderstood something?

I don't think 0.4 is going to be so different in terms of the low-level
infrastructure -- though I could be wrong -- it is more about what do we
add to the current system so that the scripts people write can be made
easier.

> yes, that is exactly what I have a problem with... why a java sub
> directory? There is more than just java. why a filters directory? I
> enver really figured out what that is useful for. having src/main and
> src/test is ok... even though I would not name that directory main...
> anyway. Just try to make it not too complicated to have mixed content
> and a different directory structure, then all should be fine.

In a sense the Maven 1 structure was better than the Maven 2 structure.
This is especially trying when trying to use javadoc.  Javadoc expects
package.html in the Java source tree, but Maven 2 doesn't really like
this.

> > *Dependency handling:*
>
> use Ivy configured from the build script (no or optional XML)

Actually I wonder if we shouldn't just have a notation that decouples
things from a particular Ivy or Maven implementation?

> > 3.) Transitive dependencies
>
> is a must I would say.

Definitely.

> > a.) Even if we support transitive dependencies* we definitely should
> > offer a mechanism for disabling them.
>
> why?

They might perhaps need to be conditioned.  In order to be able to
create a deployment system for Fedora 4, or Ubuntu 6.10 as opposed to
the latest release, a project will need to specify particular jars to
compile against.

This implies being able to create data structures that specify which
jars are in the class path and don't need to be distributed.

> I think Ivy is not very big.

True.   :-)

> > The transitive
> > dependency issue deserves a wiki page on its own. But I think the
> > importance of the issue should not be overestimated.
>
> well... it will certainly work without that feature too, you will then
> have to define all jars instead of the jars you use directly.

I really cannot imagine having to manually specify all the jars and
their internal dependencies, this is the job of the jars and the
manifests.

> > 4.) Snapshots and scope
> > Maven introduces the concept of snapshots and scopes of dependencies. I
> > would leave them out for the first iteration.
>
> I think the idea of having scopes is a good one.. but I am sure it is
> not needed at first. Of course I wouldn't do that completely like maven.
> I do not like the idea of having a fixed lifecycle and using the names
> and scopes form such a fixed cycle doesn't fit a lifecycle that is not
> fixed. For example the idea I described above a scope could be defined
> by the name of the method we are in or a list consisting of all
> lifecycle method names...  if a list, then you could setup a kind of
> inheritance between scopes and if you need only one scope you define it
> for the top level method, "build" then.
Best to design with it in first than have to add it in later.  I agree
that there are problems with a fixed lifecycle but for a Java/Groovy
project what are the differences from:

        initialize
        validate
        compile
        compile-tests
        test
        package
        install
        deploy

--
Russel.
====================================================
Dr Russel Winder                +44 20 7585 2200
41 Buckmaster Road              +44 7770 465 077
London SW11 1EN, UK             russel@...


signature.asc (196 bytes) Download Attachment

Re: Gant 0.4 - Creating a powerful DSL for building Java projects

by Russel Winder :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Tue, 2007-05-22 at 09:14 +0200, Hans Dockter wrote:

> See later for directory layout. Re your second point. For me it is
> clear: No plugins! This artificial separation makes no point for our
> approach. Often it makes the build less expressive and a paint to
> maintain. We don't need plugins, we offer good old tasks (targets) in
> the build script. Groovy offers all that is necessary if one wants to
> decouple build logic . We don't have to care about that.

Well, no plugins in the Maven 2 sense anyway.  I guess this is really a
question of what plugins means for a given system, and what they are
there to achieve.

> I think I would like to move away from the Maven concept of an
> external lifecycle object were you attach actions to. I'd rather have
> lifecycle taks that depend on each other. Those dependencies set up an
> implicit lifecycle. See my comments on lifecycle in my original mail.

Is it really the case that the lifecycle is that bad.  From an internal
implementation perspective it is not great but from a user perspective?
The idea that all I need to know to get a build is that there are a
number of target names and that these have a known relationship is very
good.  This is one of the big wins for Maven.  Maven's problem was not
the idea of lifecycle, it was the problems it got itself into trying to
do everything else.

> So far Gant is no DSL for building Java projects. There is no
> terminology for source folder, test folder, lifecycle, packaging, ....
> We want to introduce this. I think the 'why' and the advantages of
> such a build DSL are pretty obvious. So Gant 0.4 will hopefully offer
> many more things than Gant 0.3. This build DSL is the most prominent
> goal for 0.4. But there is more that can be done. What Rake offers is
> very appealing to me. Rake offers no concrete tasks like compile. It
> is completely agnostic whether you use if for Java, C or whatever. It
> is a base technology for any build or build system. See for
> example http://www.martinfowler.com/articles/rake.html
Correct.  Gant is currently a notation for scripting Ant tasks.

The connection to Rake is probably not a good one since Rake (or better
is Rant) is a file relationship dependency system on which a DSL can be
built.  Gant is just an Ant task scripting system, it has no way of
calculating dependencies between files or other things.

I think we must clearly separate the DSL construction ideas from the
underlying computational model.  Buildr is a declarative specification
of a project built on a file relationship system and teh ability to
script Ant tasks.  Gant needs a declarative specification of a project
but can currently only work with scripting Ant tasks.

> I was pretty slack to refer to this link. What I mean with using the
> Maven project layout is assuming the following folder structure:
>
>
> src/main/java
> src/main/resources
> src/test/java
> src/test/resources
> src/integtest/java
> src/integtest/resources
> src/webapps
The Maven 2 model uses java where is should use code or is it really
only Java that can go in there?  I really don't want to have to put Java
code and Groovy code into separate hierarchies as I appear to have to
with Maven 2.

> That is it. We said that we provide a build DSL for Java projects.
> Actually I think we should provide a build DSL for Java/Groovy
> projects. What structure should we offer?

A good and useful one ;-)

> Not too complicated is not good enough. Such simple things should be
> done simple, otherwise we have failed :)

Entities should not be multiplied beyond necessity. (William of Ockham)

Make everything as simple as possible, but not simpler (Einstein)

Even for expert users things should be simple (Frank Lloyd Wright)

> Regarding the whole transitive dependency issue. For me there is only
> one must. The build script must be able to make it clear what are
> first level dependencies and what are not. If I wanted to add
> hibernate to my dependencies in Maven1, I had to declare a list like
> the following:
>
>
> hibernate...
> ehcache
> cglib
> asm
> ....
> other non hibernate stuff
This is clearly insane.  It is not the job of a project to have to work
out and specify all the dependencies of the dependencies of the
dependencies.

> If someone decided not to use hibernate any longer, he or she had a
> good time figuring out which dependencies to remove from the list. How
> do you know, that asm is not a runtime dependency of another non
> hibernate dependency. To maintain the dependencies with Maven1 was a
> nightmare. You had to add a lot of comments. To have more
> expressiveness in regard to this, was for me initially one of the main
> advantages of the Maven2 dependency handling. I still think it is
> better than Maven1, but ...

Quod erat demonstrandum.

>
> Finally, some goodies from the Maven dependency handling:
>
>
> 1.) Let's say you want to use dom4j. You want to use the xpath
> functionality of dom4j. Dom4j needs Jaxen for supporting this. As not
> everybody uses the xpath functionality, Jaxen is an optional
> dependency of dom4j.

We have to add to the mix here that various operating systems have
different ways of dealing with standardly installed jars.  Ubuntu for
example puts things in /usr/share/java.  So at deployment or
installation time a project should not be installing its own private
copies of everything leading to a multiplicity of copies of jars.

How many copies of xercesImpl.jar has your system got?  (Rhetorical
question. :-)

> See: http://repo1.maven.org/maven2/dom4j/dom4j/1.6.1/dom4j-1.6.1.pom
>
>
> What do you have to do in the pom.xml to get it into your classpath?
> <dependency>
>    <artifactId>dom4j</artifactId>
> ...
> </dependency>
> <dependency>
>       <groupId>jaxen</groupId>
>       <artifactId>jaxen</artifactId>
>       <version>1.1-beta-6</version>
>       <optional>true</optional>
>  </dependency>
To use the vernacular "OK, this sucks."  but is:

dependency <<[ groupId : 'jaxen' , artifactId : 'jaxen' , version :
'1.1-beta-6' , optional : 'true' ]

sufficiently better?

> You have to declare Jaxen as a first level dependency and the build
> expresses no longer, that Jaxen is used in this project only as a
> dependency of dom4j. Yak!!!! Welcome back in the jar hell!

Which is why Jaxen should never appear in the build file.  If you use
dom4j then that needs to be stated the rest is a question of calculating
the needed dependencies which themselves depend on the operating system
and it's current install set.

> 2.) Let's say you want to use dom4j and some other project. Let's say
> you want to use an XPP reader with dom4j. As this is an optional
> dependency, you have to do the same as above. Now imagine the other
> project has a non optional dependency to xpp3_min. Either you end up
> with xpp3 and xpp3_min (a subset of xpp3) in your classpath. Or you
> have to do say:
>
>
> <dependency>
>    <artifactId>dom4j</artifactId>
> ...
> </dependency>
> <dependency>
>       <groupId>xpp3</groupId>
>       <artifactId>xpp3</artifactId>
>       <version>1.1.3.3</version>
>       <optional>true</optional>
> </dependency>
>
>
> <dependency>
>    <artifactId>other project</artifactId>
>    <exclusions>
>      <exclusion>
>          <artifactId>xpp3_min</artifactId>
>          <groupId>...<groupId>
>       </exclusion>    
>   </exclusions>
> </dependency>
>
>
> The latter says on first sight. The other project does not need xpp3.
> Which is not the case. How to understand the dependencies in a larger
> build if you have those kind of mechanisms?
>
>
> This is a common problem. For example cglib and cglib_full, spring and
> spring-context, spring-....
>
>
> I feel very strong about not having anything like this in our build
> system.  For me the Maven dependency mechanism is a no go! Ivy might
> be an alternative. But I don't know it good enough, to be confident
> not to run into similar issues. So at least we should be able to
> disable any transitive dependency handling.!
OK, so let us set up a prototype project based on this scenario
somewhere so that it can be used as a "playground" to try various
specification notations.

> Now what about this one:
>
> MY_CACHE = "org.cache:mycache:jar:1.0"
> HIBERNATE = ["org.hibernate:hibernate:jar:3.2.0.ga",
> MY_CACHE, ....]  
> OTHER = ["...", MY_CACHE, ....]  
> ...
> compile.with HIBERNATE

> This is so simple and expressive.  

I think more context is needed, I don't get the benefit of this as yet.

> (stolen from buildr)

Buildr is FOSS, it cannot be stealing as long as proper attribution is
given for the use of any copyright material!

BTW what licence is Buildr working to?

> Why not:
>
> JMOCK = group("jmock",
> "jmock-cglib", :under=>"jmock", :version=>"1.1.0")
> JUNIT = "junit:junit:jar:3.8.1"
> TEST_DEPS = [JMOCK, JUNIT]
> ...
> compile.with COMPILE_DEPS
> test.with TEST_DEPS

With proper naming of the variables there is no need for the latter two
statements, they can be implicit.  Isn't that the beuty of
convention?  :-)

> Because Ant and Rake have no intersection. Except that if Rake were
> available for Java, you could have based Ant on Rake to do things more
> elegantly. We might want to offer this Rake elegance to our users for
> there custom tasks. And use it internally for some of our stuff.

> I really recommend having a look at buildr.

So, some question really needs to be asked here:

Should we all install JRuby and switch to Buildr?  Is there actually any
future for Gant if Buildr already does exactly what people want from a
build system?  What is it that Gant can offer that makes it a viable
alternative with a realistic future?  Should Gant in fact reimplement
the file level dependency management of Rake or find a solution that
does not require it?

--
Russel.
====================================================
Dr Russel Winder                +44 20 7585 2200
41 Buckmaster Road              +44 7770 465 077
London SW11 1EN, UK             russel@...


signature.asc (196 bytes) Download Attachment

Re: Gant 0.4 - Creating a powerful DSL for building Java projects

by Russel Winder :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Tue, 2007-05-22 at 09:47 +0200, Jose Noheda wrote:

> Just my two cents. I'm normally very kind to abstract/generic
> architectures but maybe not in this case. In my mind using Groovy to
> build Java fits like a perfect solution, better than ant, better than
> Maven. Trying to go beyond that...I don't see it, at all. May be a
> good solution would be to develop the best build tool for Java. Once
> we are there we can think about more ambitious goals. I would offer
> the concrete build tasks (like checkout or compile).

For building C and C ++ systems, there are Make, Autotools, SCons, Rant,
Rake, Waf, CMake, Boost.Build, etc., etc.  Although C, C++ and LaTeX
build systems are available for Ant (and Maven) no-one uses them.
Conversely, SCons and Rant have Java build capabilities, and they are
increasingly being used because Ant and Maven are seen as tedious.

The point here is that build scripting with a dynamic language is here
to stay.  Maven 1 and Maven 2 missed that.

It is clear that C/C++, LaTeX, and Java/Groovy build technology has
split and now have their own camps.  However, despite what people are
saying there is no need for this.  SCons is showing that if you have the
infrastructure you can do the job.  The problem for Buildr and Gant is
that they run on Java and so are fundamentally slow compared to SCons
and Rant.  Gant sitting on top of Java and Groovy is really slow to
start compared to other build systems so is only really useful where a
JVM would have been started -- or already is running in a serving mode.
The idea of a build server is possibly an interesting one, especially in
order to handle parallel builds.

I am getting into stream of consciousness writing now, so I will
stop :-)

--
Russel.
====================================================
Dr Russel Winder                +44 20 7585 2200
41 Buckmaster Road              +44 7770 465 077
London SW11 1EN, UK             russel@...


signature.asc (196 bytes) Download Attachment

Re: Gant 0.4 - Creating a powerful DSL for building Java projects

by Jochen Theodorou :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Russel Winder schrieb:
[...]

>> My basic idea of a lifecycle that time was to have simple method calls:
>>
>> def build() {
>>    init()
>>    compile()
>>    test()
>>    jar()
>>    deploy()
>> }
>
> If the lifecycle is fixed then there is no need to program it per se.
> Also of course you need entry points, hence the idea of targets rather
> than just functions.

well... in this idea the lifecycle consist on a custom set of targets.
Each target is a method. That means the user is specifying the lifecycle
as well as the targets by overwriting and calling methods.

>> where each method can be overwritten and add things to the lifecycle...
>> Now I know that will not fit, since these lifecycly methods do need
>> additional informations like descriptions and "task" dependencies. I
>> guess one idea back then was to have a set of fixed top level methods
>> for that like
>>
>> def compile(){
>>    meta {
>>      description "call javac task from ant to compiles all java files"
>>      compilation from:".java", to:".class"
>>    }
>>    action {
>>      ant.javac(...)
>>    }
>> }
>
> This could be made to work but I suspect you end up with a single
> program.   A build specification has to be constructed along the lines of
> an event driven system:  a build specification offers a set of things to
> do to the user, and the user then selects what is to be done.  The
> single flow of control of the above examples don't really work.

can you explain that a little more? Each method can serve as entry point
here. Each method can call methods from other files....

>> well, something like that. meta and action would be special methods
>> activated depending on the phase the build is. Other methods would be
>> allowed too, marking normal dependencies for the task. Well that was my
>> idea back then.. of course with some defaults for each method so that
>> someone could write a class like that:
>>
>> class CleanAlwaysBuild extends DefaultBuild {
>>     def build() {
>>      clean()
>>      super.build()
>>    }
>> }
>
> The original Gant specifications were class based but the general
> response of users was that they wanted script based.  Of course a script
> is a class so there are possibilities for using inheritance.

yepp ;)

bye blackdrag

--
Jochen "blackdrag" Theodorou
Groovy Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/

---------------------------------------------------------------------
To unsubscribe from this list please visit:

    http://xircles.codehaus.org/manage_email


Re: Gant 0.4 - Creating a powerful DSL for building Java projects

by Russel Winder :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, 2007-05-23 at 09:10 +0200, Jochen Theodorou wrote:

> >> My basic idea of a lifecycle that time was to have simple method calls:
> >>
> >> def build() {
> >>    init()
> >>    compile()
> >>    test()
> >>    jar()
> >>    deploy()
> >> }
> >
> > If the lifecycle is fixed then there is no need to program it per se.
> > Also of course you need entry points, hence the idea of targets rather
> > than just functions.
>
> well... in this idea the lifecycle consist on a custom set of targets.
> Each target is a method. That means the user is specifying the lifecycle
> as well as the targets by overwriting and calling methods.
But isn't it better to use dependencies:

target ( initialize : '' ) { . . . }
target ( compile : '' ) { depends ( initialize ) ; . . . }
target ( test : '' ) { depends ( compile ) ; . . . }
target ( package : '' ) { if ( ! skipTests ) { depends
( test ) } . . . }
target ( deploy : '' ) { depends ( package ) . . . }

The only difference here is that the targets specify a set of entry
points into the build process whereas the original was a totally
scripted build.  The difference here is only that of totally program
controlled versus providing facilities for the user.

> >> where each method can be overwritten and add things to the lifecycle...
> >> Now I know that will not fit, since these lifecycly methods do need
> >> additional informations like descriptions and "task" dependencies. I
> >> guess one idea back then was to have a set of fixed top level methods
> >> for that like
> >>
> >> def compile(){
> >>    meta {
> >>      description "call javac task from ant to compiles all java files"
> >>      compilation from:".java", to:".class"
> >>    }
> >>    action {
> >>      ant.javac(...)
> >>    }
> >> }
> >
> > This could be made to work but I suspect you end up with a single
> > program.   A build specification has to be constructed along the lines of
> > an event driven system:  a build specification offers a set of things to
> > do to the user, and the user then selects what is to be done.  The
> > single flow of control of the above examples don't really work.
>
> can you explain that a little more? Each method can serve as entry point
> here. Each method can call methods from other files....
By using examples that are just functions, the issue of how the user
specifies what to do is being ignored.  If the build is an either/or,
either you do it or you don't, then a totally programming oriented
perspective is fine.  As we have users who will want to do different
things then we have to provide a set of entry points into the process.
Hence the targets.

Overall there is no difference in how the build actually happens it is
simply a question of writing a program versus writing a set of possible
responses to actions from the user.
 
> > The original Gant specifications were class based but the general
> > response of users was that they wanted script based.  Of course a script
> > is a class so there are possibilities for using inheritance.
>
> yepp ;)

You are going to have to follow that one up ;-)

--
Russel.
====================================================
Dr Russel Winder                +44 20 7585 2200
41 Buckmaster Road              +44 7770 465 077
London SW11 1EN, UK             russel@...


signature.asc (196 bytes) Download Attachment

Re: Gant 0.4 - Creating a powerful DSL for building Java projects

by hdockter :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On May 23, 2007, at 7:23 AM, Russel Winder wrote:

On Mon, 2007-05-21 at 22:08 +0200, Hans Dockter wrote:

For Gant 0.4 we want to add abstractions as known from Maven, like
project layout, build lifecycle, dependencies, etc ...

In terms of goals, I would say something more like the following:

Gant is currently a very lightweight wrapper around AntBuilder that
provides an easy way of specifying targets.  It provides a way of
programming dependencies between targets and some standard command line
processing.  Currently, Gant follows the Ant model of requiring the
tasks to manage file-level dependencies, so it follows the Ant
tradition, it does not follow the Make, Rake, Rant, Scons tradition --
where the system calculates relationships and dependencies between files
and other things and triggers actions to ensure dependencies are met.

There is an essential dichotomy between the Ant and Make traditions that
I think has to be recognized and used as a basis for planning.  In
particular, Raven and Buildr are based on Rake, from the Make tradition,
and build on that a mechanism for scripting Ant tasks.  This seems to be
a valuable integration of the two traditions.  The downside is that it
is entirely Java build focused, and not build focused -- that is left to
Rant, SCons, Waf.

In your last sentence you mention Rant, Scons and Waf. Rake is not in that list. How are they distinguished, except that they offer language specific tasks compared to Rake? I don't know Waf. Related to this is the question: as buildr is based on Rake it has also a build focus not just a Java build focus?

Often the drive to create something new comes from a pain one is having with the current options. This is the case for me. Therefore my primary focus are Java builds. In particular, as you have pointed out, as people from a non Java setting, have already found there favorite tool.

Yet why not creating a Rake like system with Groovy. May be not for 0.4 but for a later release. That would add to Gant more general purpose functionality and enrich the Java build.


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 :) 

Some important points here.

1.  Gant appears to be focusing only on Java/Groovy builds.
2.  The Maven repository is a massive resource.
3.  Internal DSLs are the way forward for build systems.

[ . . . ]

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. 

I am not sure it is necessary to actually work with real projects, but
we need to create a set of highly stripped down test projects that we
can amend in order to drive the way that the Gant scripts look.

I wonder if we should start by creating a set of test projects in the
Gant Subversion store?

You are right. This is a good idea. I gonna start setting up some tests projects there this week.


Project Layout:

I like the project layout used by Maven2. It is defined
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).

I have a problem with the core structure, but only a small one.  Calling
the code directory src/{main,test}/java has led to a situation where for
other languages you have src/{main,test}/groovy.  The source code is
partitioned by language in order to allow the plugins to know what to
do.  I wonder if all the source code should just appear in
src/{main,test}/code and let the suffixes of the files determine
language as they do for all other tools?

Good point. Jochen also pointed out that he prefers a src only folder. And with your arguments above I now think this is the way to go.


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.

What are the real purposes of the lifecycle states?  I think they are
two-fold:

1.  The provide a set of standard useful targets that mean every project
is the same.
2.  They provide a mechanism for scheduling the behaviour of the
plugins.

I would suggest that for Gant, 1 is good and 2 is irrelevant.

Right. So there will be no lifecycle object, just an implicit lifecycle defined by the dependencies of the tasks.


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.

With rigidity comes pain.

I favor the Rake way. We should also have a look at buildr (which is
based on Rake) how it implements its lifecycle handling.

Buildr is interesting because is provides a declarative layer over an
imperative infrastructure.  This means it can harness the power and
flexibility that means that the default rigidity does not create pain.

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.

Isn't this just a notation for saying which version of which jar is a
primary dependency.  Maybe I am missing something, but I don't see
anything special here.  Necessary yes, special no.

For you this is nothing special, just a natural way to do things. For me and other people which have not used dynamic scripting languages for builds yet, being brainwashed by years of xml scripting, it is a refreshing thing to see and seems worth mentioning :)


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.  

I think I must be missing something about this issue.  Using the Maven
repository is I think absolutely necessary.  It is too big a resource to
ignore.  Even Ivy recognizes this :-)  However, relying only on the
Maven repository is a bad idea.  So making alternatives to the Maven
repository strikes me as a good idea though in the main the Maven
repository will be providing most of the material.

As said above, we are almost forced to use the Maven repository at ibiblio. One can use it for two purposes though.

1.) Just for getting the jars. This is the way buildr is using it. Buildr offers no transitive dependency support whatsoever yet. Although there are thinking of ways to support it.
2.) For getting the jars and for getting dependency information about the jars, which means evaluating the pom.xml that accompanies the jar. The problem is, that the pom.xml description language for dependencies is fundamentally flawed and leads to issues (pain). This is the big problem for Java dependency handling. Even if there are better languages for describing jar dependencies, ibiblio is using the Maven one. 


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. 

I think I may be misunderstanding the currently conventional use of the
term "transitive dependency" here, or at least its implementation in
Maven and Ivy.

To me "transitive dependency" is all about a project specifying its
primary dependencies and then the repository management ensuring that
there is closure over all necessary dependencies.

I agree with your definition. To make this work you need a sufficiently good descriptor language for dependencies.

1.) Mavens dependency language is flawed. There are examples in other emails. 
a.) There is no way to express the fact that for example xpp3_min is contained in xpp3. Or spring-context is contained in spring. Dealing with the problems this causes leads to unnecessary work and a confusing build script. I don't know if Ivy offers a solution for this in its description language.
b.) In Maven you are forced to say: the hibernate.jar has one and only one set of dependencies. Which is completely insufficient. As the dependencies depend on the context. Ivy is better here. Maven tries to alleviate this with the optional keyword, which leads to other problems.

Another point is, that you might want to define your own policy for dealing with version conflicts. Ivy allows to define your own policy, Maven not.


The example I have is the Solaris package management system, the RPM
package management system for Red hat and Fedora and the Debian package
management system for Debian and Ubuntu.  If you load a package with the
Debian packaging system, then it ensures that there is closure over all
dependencies.  If you use the Solaris packaging system it just loads the
package and the system administrator has to work out what other packages
need loading.  The word crap springs to mind.  This is why yum has to do
so much work to manage the RPMs.

In a project, I want to specify only the things I actually depend on.
The build system then has to be responsible for ensuring all the
dependencies are met.  The question is how to do this and what is being
shipped in a package.  This is by definition platform dependent.
Fedora, Ubuntu, Debian, Windows all have different strategies for
installing jars and for managing the default classpath.  So a build
system has to understand deployment and packaging in a way that Maven
fails to do.  I don't know how Buildr handles this just now.  Of course
there is the versions problem, which most people solve by shipping
copies of jar files, which leads to classpath/jar hell, which leads to
pain, which leads to suffering.  

It would be great to have a build system that offers a _good_ solution for transitive dependency handling. Ivy seems to be much better than Maven, I just don't know if it is good enough. But the area of conflict will always be the pom's in the Maven ibiblio repository.

Buildr does not implements any transitive dependency handling mechanism. Although they are thinking about ways to support it.


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
section:Dealing with integration versions). I would not support the
scope concept as used by Maven. 

I am not sure about snapshots, I rather like the idea of having a
"bleeding edge" mechanism of working with the latest in everything.  But
then I used to run a mix of Debian Testing and Debian Unstable so
clearly I am a sucker for punishment :-)

Ivy is offering a 'latest' functionality without giving up unique names for the local artifacts.


Scopes in Maven are, I think, a way of managing the lifecycle and hence
classpaths.  It strikes me as useful to be able to say which jars are
required at which stage of working so that the classpath can be the
minimal required. 
The problem with Ant is it is all too easy to just
load all the dependencies into a single classpath and use it all of the
time.  This strikes me as hiding away many dependency problem.  By
correctly scoping when a dependency is needed, you control the classpath
and so raise problems and issues early.

I completely agree with the problem description. If this is not separated, it might cause a runtime failure after shipping, because the main/java code is depending on a assumed test dependency. The build does not warn you, as it has used only one big classpath for everything. (I know there should be integration tests :) ). Or the other way round, you ship a library only used for testing. 

The question is how to solve it. Buildr offers a:

compile.with DEPENDENCIES_A
test.with DEPENDENCIES_B

Whereas DEPENDENCIES_A are implicitly added to the test path.


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. 

Working with the Maven 2 standard layout has the advantage of making it
easy for Maven projects to switch.  So from a marketing perspective this
is a good idea.  Ant based projects are not a problem so there is no
barrier there.  Of course there is the Maven 1 / Maven 2 structure
differences.  I am assuming we go with the Maven 2 structure and worry
about Maven 1 later?

The only open question re layout is whether to use main/src or main/java?

- Hans

Re: Gant 0.4 - Creating a powerful DSL for building Java projects

by Jochen Theodorou :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Russel Winder schrieb:

> On Wed, 2007-05-23 at 09:10 +0200, Jochen Theodorou wrote:
>
>>>> My basic idea of a lifecycle that time was to have simple method calls:
>>>>
>>>> def build() {
>>>>    init()
>>>>    compile()
>>>>    test()
>>>>    jar()
>>>>    deploy()
>>>> }
>>> If the lifecycle is fixed then there is no need to program it per se.
>>> Also of course you need entry points, hence the idea of targets rather
>>> than just functions.
>> well... in this idea the lifecycle consist on a custom set of targets.
>> Each target is a method. That means the user is specifying the lifecycle
>> as well as the targets by overwriting and calling methods.
>
> But isn't it better to use dependencies:
>
> target ( initialize : '' ) { . . . }
> target ( compile : '' ) { depends ( initialize ) ; . . . }
> target ( test : '' ) { depends ( compile ) ; . . . }
> target ( package : '' ) { if ( ! skipTests ) { depends
> ( test ) } . . . }
> target ( deploy : '' ) { depends ( package ) . . . }
>
> The only difference here is that the targets specify a set of entry
> points into the build process whereas the original was a totally
> scripted build.  The difference here is only that of totally program
> controlled versus providing facilities for the user.

in the end it might be a matter of taste.. but there is a difference. If
I define defaults for the targets, then what do I do with these defaults
  when I need to make it a little bit different? For example.. let us
think we have a build for a normal java program and then add an
additional phase for groovy based on the java parts in another project.
What would we do? Copy 99% of the file, rewriting the compile task
completely? in my idea you would extend the other class and over write
the compile method, while still being able to delegate the call or
simply adding a new part in the lifecycle like:

def compile() {
   super.compile()
   compileGroovy()
}

def compileGroovy() {
   meta {
       description """call groovyc task from ant to compiles all groovy
files"""
       compilation from:".groovy", to:".class"
   }
   action {
      ant.groovyc(...)
   }
}

and I have the freedom of calling the old part after my part, before my
part or not at all. But extending is not all... I mean we could easily
provide partial build data, that is simply included, missing method and
a naming convention would make it possible.

The declarative parts are still there, just not for the targets itself.

>>>> where each method can be overwritten and add things to the lifecycle...
>>>> Now I know that will not fit, since these lifecycly methods do need
>>>> additional informations like descriptions and "task" dependencies. I
>>>> guess one idea back then was to have a set of fixed top level methods
>>>> for that like
>>>>
>>>> def compile(){
>>>>    meta {
>>>>      description "call javac task from ant to compiles all java files"
>>>>      compilation from:".java", to:".class"
>>>>    }
>>>>    action {
>>>>      ant.javac(...)
>>>>    }
>>>> }
>>> This could be made to work but I suspect you end up with a single
>>> program.   A build specification has to be constructed along the lines of
>>> an event driven system:  a build specification offers a set of things to
>>> do to the user, and the user then selects what is to be done.  The
>>> single flow of control of the above examples don't really work.
>> can you explain that a little more? Each method can serve as entry point
>> here. Each method can call methods from other files....
>
> By using examples that are just functions, the issue of how the user
> specifies what to do is being ignored.  If the build is an either/or,
> either you do it or you don't, then a totally programming oriented
> perspective is fine.  As we have users who will want to do different
> things then we have to provide a set of entry points into the process.
> Hence the targets.

targets == methods with naming convention

> Overall there is no difference in how the build actually happens it is
> simply a question of writing a program versus writing a set of possible
> responses to actions from the user.

yeah, ok, but event driven doesn't favor declarative or imperative.

One major goal of maven was the recycling of build descriptions. I have
a bit the felling that in Gant you can either use a predefined task or
not. If your clean task needs to be extended, then you do what?

>>> The original Gant specifications were class based but the general
>>> response of users was that they wanted script based.  Of course a script
>>> is a class so there are possibilities for using inheritance.
>> yepp ;)
>
> You are going to have to follow that one up ;-)

of course, if the base class should be custom for each project, this
makes a problem. The class muist be described somewhere, somehow. It
does not need to be a class construct as it is usually used in Groovy
then, but if not the AST needs to be rewritten... for example

"""
include (webDeploy)
include (basicBuild)
include (integrationTest)

...
"""

I could use thes include commands to rewrite the AST and and stubs for
methods in webDeploy, basicBuild, integrationTest. That's a bit like
multiple inheritance then. I could even rewrite calls to "super".. if
clear ;). Or I could hook in invokeMethod build a map of the methods
form the includes and call these according .. without the ability to use
"super" then of course....

bye blackdrag

--
Jochen "blackdrag" Theodorou
Groovy Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/

---------------------------------------------------------------------
To unsubscribe from this list please visit:

    http://xircles.codehaus.org/manage_email


Re: Gant 0.4 - Creating a powerful DSL for building Java projects

by hdockter :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On May 23, 2007, at 8:20 AM, Russel Winder wrote:

> On Tue, 2007-05-22 at 09:14 +0200, Hans Dockter wrote:
>
>> See later for directory layout. Re your second point. For me it is
>> clear: No plugins! This artificial separation makes no point for our
>> approach. Often it makes the build less expressive and a paint to
>> maintain. We don't need plugins, we offer good old tasks (targets) in
>> the build script. Groovy offers all that is necessary if one wants to
>> decouple build logic . We don't have to care about that.
>
> Well, no plugins in the Maven 2 sense anyway.  I guess this is  
> really a
> question of what plugins means for a given system, and what they are
> there to achieve.

Right

>
>> I think I would like to move away from the Maven concept of an
>> external lifecycle object were you attach actions to. I'd rather have
>> lifecycle taks that depend on each other. Those dependencies set  
>> up an
>> implicit lifecycle. See my comments on lifecycle in my original mail.
>
> Is it really the case that the lifecycle is that bad.  From an  
> internal
> implementation perspective it is not great but from a user  
> perspective?
> The idea that all I need to know to get a build is that there are a
> number of target names and that these have a known relationship is  
> very
> good.  This is one of the big wins for Maven.  Maven's problem was not
> the idea of lifecycle, it was the problems it got itself into  
> trying to
> do everything else.

Lifecycle is good. The question is how to establish it. Reading your  
response to Jochen, we are exactly on the same page here:

Quote Russel:

> But isn't it better to use dependencies:
>
> target ( initialize : '' ) { . . . }
> target ( compile : '' ) { depends ( initialize ) ; . . . }
> target ( test : '' ) { depends ( compile ) ; . . . }
> target ( package : '' ) { if ( ! skipTests ) { depends
> ( test ) } . . . }
> target ( deploy : '' ) { depends ( package ) . . . }
>
> The only difference here is that the targets specify a set of entry
> points into the build process whereas the original was a totally
> scripted build.  The difference here is only that of totally program
> controlled versus providing facilities for the user.

This is exactly what I have in mind ;). It is a different way of  
modelling a lifecycle than Maven does!

>
>> So far Gant is no DSL for building Java projects. There is no
>> terminology for source folder, test folder, lifecycle,  
>> packaging, ....
>> We want to introduce this. I think the 'why' and the advantages of
>> such a build DSL are pretty obvious. So Gant 0.4 will hopefully offer
>> many more things than Gant 0.3. This build DSL is the most prominent
>> goal for 0.4. But there is more that can be done. What Rake offers is
>> very appealing to me. Rake offers no concrete tasks like compile. It
>> is completely agnostic whether you use if for Java, C or whatever. It
>> is a base technology for any build or build system. See for
>> example http://www.martinfowler.com/articles/rake.html
>
> Correct.  Gant is currently a notation for scripting Ant tasks.
>
> The connection to Rake is probably not a good one since Rake (or  
> better
> is Rant) is a file relationship dependency system on which a DSL  
> can be
> built.  Gant is just an Ant task scripting system, it has no way of
> calculating dependencies between files or other things.

Right

>
> I think we must clearly separate the DSL construction ideas from the
> underlying computational model.

Definitely. But if a user want to customize the build, it makes a  
difference to him or her whether this underlying computational model  
is available or not.

> Buildr is a declarative specification
> of a project built on a file relationship system and teh ability to
> script Ant tasks.  Gant needs a declarative specification of a project
> but can currently only work with scripting Ant tasks.

For 0.4 this will be good enough I think. I just don't want to give  
up the idea to implement some Rake like underlying module later on.

>
>> I was pretty slack to refer to this link. What I mean with using the
>> Maven project layout is assuming the following folder structure:
>>
>>
>> src/main/java
>> src/main/resources
>> src/test/java
>> src/test/resources
>> src/integtest/java
>> src/integtest/resources
>> src/webapps
>
> The Maven 2 model uses java where is should use code or is it really
> only Java that can go in there?  I really don't want to have to put  
> Java
> code and Groovy code into separate hierarchies as I appear to have to
> with Maven 2.

I agree.

>
>>
>> Finally, some goodies from the Maven dependency handling:
>>
>>
>> 1.) Let's say you want to use dom4j. You want to use the xpath
>> functionality of dom4j. Dom4j needs Jaxen for supporting this. As not
>> everybody uses the xpath functionality, Jaxen is an optional
>> dependency of dom4j.
>
> We have to add to the mix here that various operating systems have
> different ways of dealing with standardly installed jars.  Ubuntu for
> example puts things in /usr/share/java.  So at deployment or
> installation time a project should not be installing its own private
> copies of everything leading to a multiplicity of copies of jars.
>
> How many copies of xercesImpl.jar has your system got?  (Rhetorical
> question. :-)

I haven't thought about this one yet. Maven offers the scope provided  
for this.

>
>> See: http://repo1.maven.org/maven2/dom4j/dom4j/1.6.1/dom4j-1.6.1.pom
>>
>>
>> What do you have to do in the pom.xml to get it into your classpath?
>> <dependency>
>>    <artifactId>dom4j</artifactId>
>> ...
>> </dependency>
>> <dependency>
>>       <groupId>jaxen</groupId>
>>       <artifactId>jaxen</artifactId>
>>       <version>1.1-beta-6</version>
>>       <optional>true</optional>
>>  </dependency>
>
> To use the vernacular "OK, this sucks."  but is:
>
> dependency <<[ groupId : 'jaxen' , artifactId : 'jaxen' , version :
> '1.1-beta-6' , optional : 'true' ]
>
> sufficiently better?

What would be better is:

DOM4J = ["dom4j:dom4j:jar:1.6.1", "jaxen:jaxen:jar:1.1-beta-6" ]

This clearly expresses what is going on. You have to do it manually,  
but some might say: 'So what?'

>
>> You have to declare Jaxen as a first level dependency and the build
>> expresses no longer, that Jaxen is used in this project only as a
>> dependency of dom4j. Yak!!!! Welcome back in the jar hell!
>
> Which is why Jaxen should never appear in the build file.  If you use
> dom4j then that needs to be stated the rest is a question of  
> calculating
> the needed dependencies which themselves depend on the operating  
> system
> and it's current install set.
>
>> 2.) Let's say you want to use dom4j and some other project. Let's say
>> you want to use an XPP reader with dom4j. As this is an optional
>> dependency, you have to do the same as above. Now imagine the other
>> project has a non optional dependency to xpp3_min. Either you end up
>> with xpp3 and xpp3_min (a subset of xpp3) in your classpath. Or you
>> have to do say:
>>
>>
>> <dependency>
>>    <artifactId>dom4j</artifactId>
>> ...
>> </dependency>
>> <dependency>
>>       <groupId>xpp3</groupId>
>>       <artifactId>xpp3</artifactId>
>>       <version>1.1.3.3</version>
>>       <optional>true</optional>
>> </dependency>
>>
>>
>> <dependency>
>>    <artifactId>other project</artifactId>
>>    <exclusions>
>>      <exclusion>
>>          <artifactId>xpp3_min</artifactId>
>>          <groupId>...<groupId>
>>       </exclusion>
>>   </exclusions>
>> </dependency>
>>
>>
>> The latter says on first sight. The other project does not need xpp3.
>> Which is not the case. How to understand the dependencies in a larger
>> build if you have those kind of mechanisms?
>>
>>
>> This is a common problem. For example cglib and cglib_full, spring  
>> and
>> spring-context, spring-....
>>
>>
>> I feel very strong about not having anything like this in our build
>> system.  For me the Maven dependency mechanism is a no go! Ivy might
>> be an alternative. But I don't know it good enough, to be confident
>> not to run into similar issues. So at least we should be able to
>> disable any transitive dependency handling.!
>
> OK, so let us set up a prototype project based on this scenario
> somewhere so that it can be used as a "playground" to try various
> specification notations.

I think transitive dependency handling constitute a minor benefit of  
our tool compared to providing project, multi-project and lifecycle  
support. Yet doing transitive dependencies right seems to be a  
challenge. I would not like to get stuck by this. I would like to  
first implement the features that offer the most benefit. That might  
be good enough for a 0.4.

>
>> Now what about this one:
>>
>> MY_CACHE = "org.cache:mycache:jar:1.0"
>> HIBERNATE = ["org.hibernate:hibernate:jar:3.2.0.ga",
>> MY_CACHE, ....]
>> OTHER = ["...", MY_CACHE, ....]
>> ...
>> compile.with HIBERNATE
>
>> This is so simple and expressive.
>
> I think more context is needed, I don't get the benefit of this as  
> yet.
>
>> (stolen from buildr)
>
> Buildr is FOSS, it cannot be stealing as long as proper attribution is
> given for the use of any copyright material!

I was not serious when I said stolen. I just wanted to make clear  
that this is none of my ideas.

>
> BTW what licence is Buildr working to?

Apache license 2.0

>
>> Why not:
>>
>> JMOCK = group("jmock",
>> "jmock-cglib", :under=>"jmock", :version=>"1.1.0")
>> JUNIT = "junit:junit:jar:3.8.1"
>> TEST_DEPS = [JMOCK, JUNIT]
>> ...
>> compile.with COMPILE_DEPS
>> test.with TEST_DEPS
>
> With proper naming of the variables there is no need for the latter  
> two
> statements, they can be implicit.  Isn't that the beuty of
> convention?  :-)

This is a cool idea. But the problem might be multiproject builds,  
which are defined in one build script, each having a different  
classpath.

>
>> Because Ant and Rake have no intersection. Except that if Rake were
>> available for Java, you could have based Ant on Rake to do things  
>> more
>> elegantly. We might want to offer this Rake elegance to our users for
>> there custom tasks. And use it internally for some of our stuff.
>
>> I really recommend having a look at buildr.
>
> So, some question really needs to be asked here:
>
> Should we all install JRuby and switch to Buildr?  Is there  
> actually any
> future for Gant if Buildr already does exactly what people want from a
> build system?  What is it that Gant can offer that makes it a viable
> alternative with a realistic future?  Should Gant in fact reimplement
> the file level dependency management of Rake or find a solution that
> does not require it?
>

For 0.4 we should find a solution that does not require a Rake like  
system.

I think it makes a lot of sense to have a Groovy based build system:

1.) For just using the buildr DSL you hardly need any Ruby knowledge.  
But when it comes to customizing the build this is different. So for  
Groovy users there is a strong advantage in being able to customize  
their build with Groovy.
2.) Another aspect of customizing the build is using existing Java  
libs for customization (e.g. svnkit, JSch). What if a method you call  
requires an implementation of an Interface. As far as I know JRuby  
won't help here.
3.) Transparency to Groovy users. Looking at the source of buildr, if  
you don't know Ruby this is not easy to read.
4.) Buildr is a small project. To implement its functionality won't  
take that long (We can't offer the Rake goodies, at least not at the  
beginning, but this is no big deal I would say).
5.) We want to offer good support for the build of Groovy projects.
6.) There are so many smart people around in the Groovy ecosystem,  
that I would be surprised if we don't come up with a couple of  
original and innovative features.


- Hans

---------------------------------------------------------------------
To unsubscribe from this list please visit:

    http://xircles.codehaus.org/manage_email


Re: Gant 0.4 - Creating a powerful DSL for building Java projects

by hdockter :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On May 23, 2007, at 11:15 AM, Jochen Theodorou wrote:

Russel Winder schrieb:
On Wed, 2007-05-23 at 09:10 +0200, Jochen Theodorou wrote:
My basic idea of a lifecycle that time was to have simple method calls:

def build() {
   init()
   compile()
   test()
   jar()
   deploy()
}
If the lifecycle is fixed then there is no need to program it per se.
Also of course you need entry points, hence the idea of targets rather
than just functions.
well... in this idea the lifecycle consist on a custom set of targets. Each target is a method. That means the user is specifying the lifecycle as well as the targets by overwriting and calling methods.
But isn't it better to use dependencies:
target ( initialize : '' ) { . . . }
target ( compile : '' ) { depends ( initialize ) ; . . . }
target ( test : '' ) { depends ( compile ) ; . . . }
target ( package : '' ) { if ( ! skipTests ) { depends
( test ) } . . . }
target ( deploy : '' ) { depends ( package ) . . . }
The only difference here is that the targets specify a set of entry
points into the build process whereas the original was a totally
scripted build.  The difference here is only that of totally program
controlled versus providing facilities for the user. 

in the end it might be a matter of taste.. but there is a difference. If I define defaults for the targets, then what do I do with these defaults  when I need to make it a little bit different? For example.. let us think we have a build for a normal java program and then add an additional phase for groovy based on the java parts in another project. What would we do? Copy 99% of the file, rewriting the compile task completely? in my idea you would extend the other class and over write the compile method, while still being able to delegate the call or simply adding a new part in the lifecycle like:

def compile() {
  super.compile()
  compileGroovy()
}  

Wouldn't we simply add a target to our build?

target ( groovy : 'groovy' ) {
  depends(compile)
  // do something
}

- Hans



Re: Gant 0.4 - Creating a powerful DSL for building Java projects

by hdockter :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On May 23, 2007, at 9:10 AM, Jochen Theodorou wrote:

> Russel Winder schrieb:
> [...]
>>> My basic idea of a lifecycle that time was to have simple method  
>>> calls:
>>>
>>> def build() {
>>>    init()
>>>    compile()
>>>    test()
>>>    jar()
>>>    deploy()
>>> }
>> If the lifecycle is fixed then there is no need to program it per se.
>> Also of course you need entry points, hence the idea of targets  
>> rather
>> than just functions.
>
> well... in this idea the lifecycle consist on a custom set of  
> targets. Each target is a method. That means the user is specifying  
> the lifecycle as well as the targets by overwriting and calling  
> methods.
>

What we want is a mechanism which offers entry points and make sure  
that the former phases of this entry point are also called. How would  
you implement this with your approach? Adding a call to the compile  
method within the test method? Having aggregate methods like build to  
enable this?

- Hans

---------------------------------------------------------------------
To unsubscribe from this list please visit:

    http://xircles.codehaus.org/manage_email


Re: Gant 0.4 - Creating a powerful DSL for building Java projects

by Jochen Theodorou :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hans Dockter schrieb:
[...]

>> def compile() {
>>   super.compile()
>>   compileGroovy()
>> }  
>
> Wouldn't we simply add a target to our build?
>
> target ( groovy : 'groovy' ) {
>   depends(compile)
>   // do something
> }

no, because all other depends(compile) are not changed to
depends(groovy). My example "replaces" the compile target while reusing
the old compile target.

bye blackdrag

--
Jochen "blackdrag" Theodorou
Groovy Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/

---------------------------------------------------------------------
To unsubscribe from this list please visit:

    http://xircles.codehaus.org/manage_email


Re: Gant 0.4 - Creating a powerful DSL for building Java projects

by Jochen Theodorou :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hans Dockter schrieb:

>
> On May 23, 2007, at 9:10 AM, Jochen Theodorou wrote:
>
>> Russel Winder schrieb:
>> [...]
>>>> My basic idea of a lifecycle that time was to have simple method calls:
>>>>
>>>> def build() {
>>>>    init()
>>>>    compile()
>>>>    test()
>>>>    jar()
>>>>    deploy()
>>>> }
>>> If the lifecycle is fixed then there is no need to program it per se.
>>> Also of course you need entry points, hence the idea of targets rather
>>> than just functions.
>>
>> well... in this idea the lifecycle consist on a custom set of targets.
>> Each target is a method. That means the user is specifying the
>> lifecycle as well as the targets by overwriting and calling methods.
>>
>
> What we want is a mechanism which offers entry points and make sure that
> the former phases of this entry point are also called. How would you
> implement this with your approach? Adding a call to the compile method
> within the test method?  Having aggregate methods like build to enable
 > this?

adding a call is the way I think of. build is a target on its own... if
we need to make a difference between helper methods and build targets,
then we could name it for example buildTarget, targetBuild.. something
like that.

bye blackdrag

--
Jochen "blackdrag" Theodorou
Groovy Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/

---------------------------------------------------------------------
To unsubscribe from this list please visit:

    http://xircles.codehaus.org/manage_email


Re: Gant 0.4 - Creating a powerful DSL for building Java projects

by hdockter :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On May 23, 2007, at 5:00 PM, Jochen Theodorou wrote:

> Hans Dockter schrieb:
> [...]
>>> def compile() {
>>>   super.compile()
>>>   compileGroovy()
>>> }
>> Wouldn't we simply add a target to our build?
>> target ( groovy : 'groovy' ) {
>>   depends(compile)
>>   // do something
>> }
>
> no, because all other depends(compile) are not changed to depends
> (groovy). My example "replaces" the compile target while reusing  
> the old compile target.
>
> bye blackdrag

I see your point now. But one could easily define a policy that the  
target is just a wrapper.

target ( compile : 'compile' ) {
    Build.compile()
}

Then you could overwrite the compile target:

target ( compile : 'compile' ) {
   Build.compile()
   compileGroovy()
}

- Hans




---------------------------------------------------------------------
To unsubscribe from this list please visit:

    http://xircles.codehaus.org/manage_email


Re: Gant 0.4 - Creating a powerful DSL for building Java projects

by Jochen Theodorou :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hans Dockter schrieb:
[...]

> I see your point now. But one could easily define a policy that the
> target is just a wrapper.
>
> target ( compile : 'compile' ) {
>    Build.compile()
> }
>
> Then you could overwrite the compile target:
>
> target ( compile : 'compile' ) {
>   Build.compile()
>   compileGroovy()
> }

that's right, but then I need to know the contents of compile, or not?
You really think it is good to need such detailed knowledge?

You could only rescue the situation by putting all code in methods,
document what method is called... why do I need then the target description?

bye blackdrag

--
Jochen "blackdrag" Theodorou
Groovy Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/

---------------------------------------------------------------------
To unsubscribe from this list please visit:

    http://xircles.codehaus.org/manage_email

< Prev | 1 - 2 - 3 | Next >