ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
Subject Re: A DAG for all occasions
Date Mon, 08 Jan 2001 04:40:58 GMT

I guess I was thinking more of a parse-time expansion of templates (using
something like XSLT) than a run-time expansion (using ant properties). The
main reason why the example you gave causes problems is because you've tied
the template mechanism to the "ant-call" mechanism, which should be two
separate things IMHO. If you expand all of the templates ahead of time, the
full DAG can be built up and "target.4" will only be built once.

However, if you need to run a task in order to determine the parameters for
the template, you'll need to run that task, then create a new DAG by
calling the "ant-call" task. I don't think there's a good way around this.
However, the only time this is a problem is when there are targets in the
child build that depend on targets in the parent build. I'm not sure how
much this comes up in practice - I can't think of any good examples that
can't easily be refactored...

As a more concrete example, let's say the user wants to run the same set of
commands in multiple directories (ie compile the files and jar them). We
could create an XSLT file that converts a list of directory names into an
ant project, which might look like this:

<xsl:template match="directory">
     <target name="{@name}" depends="{@depends}">
          <javac srcdir="{@name}" destdir="build/{@name}"/>
          <jar jarfile="dist/{@name}.jar" basedir="build/{@name}"/>

Then define our project file like this:

<?xml-stylesheet href="foo.xsl" ... ?>
<project name="foo">
     <directory name="target.1" depends="target.2"/>
     <directory name="target.2" depends="target.3"/>
     <directory name="target.3" depends="target.4"/>
     <target name="target.4">

This should work OK (assuming ant handles the "xml-stylesheet" directive
correctly). The templates can be expanded at parse time, and the full DAG
can be built correctly. However, lets assume that we don't want to
explicitly say which subdirectories exist, but instead we want to use a
task to figure out those directories. So we define a task that basically
generates the project file above, then calls the "ant-call" task to run it:

<project name="foo-gen">
     <target name="generate">
          <scan-dirs output="foo.ant"/>
          <ant-call project="foo"/>

This should also work OK. "target.4" will be built once and only once in
the child build. However, if for some reason our "generate" target depends
on our "target.4" target, we have problems:

<project name="foo-gen">
     <target name="generate" depends="target.4">
          <scan-dirs output="foo.ant"/>
          <ant-call project="foo"/>
     <target name="target.4">

In this case, "target.4" will get built twice. Are there any good examples
of this scenario? What are some good other examples of how people want to
use templates?

Matt Foemmel
ThoughtWorks, Inc.

                    Peter Donald                                                         
                    <donaldp@apac        To:           
          >              cc:                                          
                                         Subject:     A DAG for all occasions            
                    12:26 AM                                                             
                    respond to                                                           


I was just thinking about how we build dependency graphs and how we should
build it and I hit a snag. I think that we can currently agree that both
inter and intra project DAGs are necessary. However what happens when we
come to templates? My first reaction was to treat them like they are
treated now. ie ant-call executes the target in a new context all it's
dependencies are executed. So if we have the following

<target name="target.1" depends="target.2" />
<target name="target.2" depends="target.3" />
<target name="target.3" depends="target.4" />
<target name="target.4" />

and use <ant-call target="target.1" /> then all of targets 1-4 will be
executed. However consider the case when target.4 is something we want only
to be executed once in the project and not every time a template is called.
There is a number of ways we could get around this - the simplest of which

<target name="target.4" unless="target.4.already-ran">
  <property name="target.4.already-ran" value="true"/>

however this becomes increasingly more complex as more of these targets
were added and a simple look at my build files indicate that it would be a
relatively common occurence.

So how about we explictly mark targets that participate in template. These
targets would not be able to be called except via ant-call or its
equivelent and would be run every time template is called. We could do it
either via an attribute (ie setting template="true") or via changing name
of tag. ie

<template name="target.1" depends="target.2" />
<template name="target.2" depends="target.3" />
<template name="target.3" depends="target.4" />
<target name="target.4" />

The second option (changing tag name) is simple to understand, easy to
implement and I think covers all bases that we need covering (at least that
I can see). What do you think - too icky or a possibility ?



| "Faced with the choice between changing one's mind, |
| and proving that there is no need to do so - almost |
| everyone gets busy on the proof."                   |
|              - John Kenneth Galbraith               |

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message