ANT Scenario Conditional Depend Targets - ant

Is it possible in ANT to have the same target which depends on set of different targets depending on the condition in this target.
EXAMPLE:
<target name=my_target depends="target2,target3,target4" if="my_property1">
and
<target name=my_target depends="target2,target5,target6" if="my_property2">
Where "target2" evaluates properties my_property1 or my_property2.
Is something like this possible, or is there another way to assign to the same target different "depends" based on condition?
Thanks.

You cannot have duplicate targets. I'm not quite clear on what you're goign for... what does target2 do with your properties? To replicate the behavior you have you could setup
<target name="my_target" depends="target2,target3,target4,target5,target6">
and then setup if and/or unless on target1-6 something like
<target name="target2"> (run target2 always)
<target name="target3" if="my_property1">
<target name="target4" if="my_property1">
<target name="target5" if="my_property2">
<target name="target6" if="my_property2">

Related

Why does ANT update the contents of a fileset after it was created, and can I override this?

I think this may be easiest explained by an example, so here goes:
<target name="test">
<fileset id="fileset" dir="target">
<include name="*"/>
</fileset>
<echo>${toString:fileset}</echo>
<touch file="target/test"/>
<echo>${toString:fileset}</echo>
</target>
Outputs:
test:
[echo]
[touch] Creating target/test
[echo] test
What I ideally want is to have the fileset stay the same so I can have a before/after set (in order to get a changed set using <difference>, so if you know of a way to skip right to that...).
I've tried using <filelist> instead, but I can't get this correctly populated and compared in the <difference> task (they're also hard to debug since I can't seem to output their contents). I also tried using <modified/> to select files in the fileset, but it doesn't seem to work at all and always returns nothing.
Even if there is an alternative approach I would appreciate a better understanding of what ANT is doing in the example above and why.
The path selector is evaluated on the fly. When a file is added, it will reflect in the set when you use it.
You may able to evaluate and keep it in variable using pathconvert. Then this can be converted back to filest using pathtofilest
A fileset is something like a selector. It's a set of "instructions" (inclusions, exclusions, patterns) allowing to get a set of files.
Each time you actually do something with the fileset (like printing the files it "references"), the actual set of files is computed based on the "instructions" contained in the fileset.
As Jayan pointed out it might be worth posting the final outcome as an answer, so here's a simplified version with the key parts:
<fileset id="files" dir="${target.dir}"/>
<pathconvert property="before.files" pathsep=",">
<fileset refid="files"/>
</pathconvert>
<!-- Other Ant code changes the file-system. -->
<pathconvert property="after.files" pathsep=",">
<fileset refid="files"/>
</pathconvert>
<filelist id="before.files" files="${before.files}"/>
<filelist id="after.files" files="${after.files}"/>
<difference id="changed.files">
<filelist refid="before.files"/>
<filelist refid="after.files"/>
</difference>

How to check a condition once when using multiple "depends"?

I want to have a 'master' ant target which depends on multiple "worker targets", (each of which does "one thing well")
However, I want to conditionally execute the "master" target, i.e. and not execute the "worker' subtargets if the condition is not met
(specficially, the master target creates and populates the database. The subtarget creates schema, populates tables, etc. The final step in the master target leaves a marker file to indicate "database created once." On subsequent runs, the process should not try to create the database.
The question
How can I implement this in a manner both "antish" (i.e. without "antcall) and DRY (dont' repeat yourself).
Example
<target name="check-db-created">
<available file="db.created.marker.txt" property="db.already.created"/>
</target>
<target name="create-new-db"
unless="db.already.created"
depends="check-db-created,create-db-mssql,create-tables,compile-sp,disable-constraints.....">
</target>
<target name="create-db-mssql" >
..do stufff
</target>
Comments
The issue is that the 'sub-targets' ('create-db-mssql', create-tables', etc) execute even though the "master" target does not need to run. Ant documentation clearly discusses this.
Important: the if and unless attributes only enable or disable the
target to which they are attached. They do not control whether or not
targets that a conditional target depends upon get executed. In fact,
they do not even get evaluated until the target is about to be
executed, and all its predecessors have already run.
I can code around the rpoblem by adding "unless" clauses to all the 'worker targets', but would like to avoid repeating.
Additionally, I use antcall as follows, but would prefer to avoid the "GOTO" of the ant world.
<target name="create-new-db" depends="check-db-created"
unless="db.already.created">
<antcall target="create-new-db-internal"/>
</target>
<target name="create-new-db-internal"
depends="create-db,create-tables,compile-sp,disable-constraints,insert-base-data,insert-installer-generated-sql,insert-kb-data"
>
</target>
thanks

Excluding the setup method of a junit test using ant

Hi I am new to junit and ant.
I want to prevent the JUnit #Before* annotated methods from execution.
Is that possible with Ant's "exclude"?
Are other possibilities to prevent these annotated methods from execution?
thx
No you can't do that with Ant's exclude.
You could use Ant to change the annotation in all files.
http://ant.apache.org/manual/Tasks/replace.html
<replace dir="${tests}" token="#Before" value="#BeforeREMOVED">
<include name="**/*.java"/>
<exclude name="**/*Test*"/>
</replace>
You can adjust/omit the include and exclude tags as necessary to match the files you want.
You can alway change the files back
<replace dir="${tests}" token="#BeforeREMOVED" value="#Before">
<include name="**/*.java"/>
<exclude name="**/*Test*"/>
</replace>
Otherwise you can extend the tests with a new class that overrides the methods. Seems like it might be a lot of work though.

Execute Ant action always and independently from target

Is there a way to specify actions like <copy> in an Ant buildfile that get executed every time the build file gets read by ant (regardless of the target which is called)?
The background is: I want a *.properties-file to be automatically created from a template when it's not present. I know, I could specify a target which does this and then include it at the root of the dependency-tree but maybe there is a more elegant solution. Because actually the problem is a bit more complex: the ant file where the *.properties-file is read-out is imported by other build files and I don't want to cross-reference targets between them.
I hope I explained my problem sufficiently. In cases of questions do not hestitate to ask.
This is my first posting here. Hope you can help - Greetings from Germany, Ben.
Just put the code at the top of the file, outside of a target definition.
<project name="myproject" default="mytarget" basedir=".">
<echo message="Hello there." />
<target name="mytarget">
<!-- Do stuff. -->
</target>
<target name="myothertarget">
<!-- Do other stuff. -->
</target>
</project>
In this case the echo will get executed once before any target, regardless of which target is invoked.

How to suppress ant jar warnings for duplicates

I don't want ant's jar task to notify me every time it skips a file because the file has already been added. I get reams of this:
[jar] xml/dir1/dir2.dtd already added, skipping
Is there a way to turn this warning off?
This is an older question, but there is one obvious way to exclude the duplicates warning, do not include the duplicate files. You could do this in one of two ways:
Exclude the duplicate files in some fashion, or
Copy the files to a staging area, so that the cp task deals with duplicates, not the jar task.
So, instead of doing:
<jar destfile="${dist}/lib/app.jar">
<fileset dir="a" include="xml/data/*.{xml,dtd}"/>
<fileset dir="b" include="xml/data/*.{xml,dtd}"/>
<fileset dir="c" include="xml/data/*.{xml,dtd}"/>
</jar>
do one of:
<jar destfile="${dist}/lib/app.jar">
<fileset dir="a" include="xml/data/*.{xml,dtd}"/>
<fileset dir="b" include="xml/data/*.xml"/>
<fileset dir="c" include="xml/data/*.xml"/>
</jar>
or
<copy todir="tmpdir">
<fileset dir="a" include="xml/data/*.{xml,dtd}"/>
<fileset dir="b" include="xml/data/*.{xml,dtd}"/>
<fileset dir="c" include="xml/data/*.{xml,dtd}"/>
</copy>
<jar destfile="${dist}/lib/app.jar">
<fileset dir="tmpdir" include="xml/data/*.{xml,dtd}"/>
</jar>
<delete dir="tmpdir"/>
Edit: Base on the comment to this answer, there is a third option, although it is a fair bit more work... You can always get the source to the jar task, and modify it so that it does not print out the warnings. You could keep this as a local modification to your tree, move it to a different package and maintain it yourself, or try to get the patch pushed back upstream.
I don't know of any options on the jar task to suppress these messages, unless you run the whole build with the -quiet switch, in which case you may not see other information you want.
In general if you have lots of duplicate files it is a good thing to be warned about them as a different one may be added to that which you expect. This possibly indicates that a previous target of the build has not done its job as well as it might, though obviously without more details it is impossible to say.
Out of interest why do you have the duplicate files?

Resources