Manually Start ANT Task - ant

For various reasons that I won't go into (I promise it's necessary to do this with the current code base; I know it's goofy), I want to execute a target twice in the same build task.
For example, I want to execute the target foo, then bar, then foo again. This is a simplified version of what I already tried:
<target name="foo">
...
</target>
<target name="bar" depends="foo">
...
</target>
<target name="project" depends="foo,bar">
...
</target>
In this case when executing the project target, foo only ran once. I also tried getting rid of the depends attribute on the bar target and making the project's depends attribute "foo,bar,foo", but still the same result.
Is there a way to force a task to execute, even if it's already successfully completed? Or is there a better way to go about this?

The antcall task allows you to explicitly call a target.
I think that's a better solution than using the depends mechanism. As you've identified, this determines what has already run. Antcall instructs the target to run regardless of whether it's run before.
You can parameterise the call to customise what it does on each invocation.

Related

Check if two antcalls are successfull

I'm extremely new to ant script and i want to find out if my build is successful or not. my main target has two antcalls and i don't know how to check if they were successful or not, in order to evaluate the main target.
run all is my main target
<target name="run all">
<antcall target="Run basic configuration" />
<antcall target="Run custom configuration"/>
i want to add a fail condition for the "run all" target.
Each target does check individually if they are successful, but I want to know if the target that calls the ant is unsuccessful in case those two fail.
Also, if one fails does the other one get called?
To determine if an antcall is successful requires a more careful definition of what success is. It can mean:
The code executed without throwing an exception.
The code did what you wanted it to do.
In the first case, you can wrap the execution of your antcall with a trycatch block to catch exceptions. The trycatch task is part of ant-contrib, but that is frequently used in Ant coding. You'd do:
<trycatch property="exception.message" reference="exception.object">
<try>
<antcall target="targetName"/>
</try>
<catch>
<!-- handle exception logic here -->
</catch>
<finally>
<!-- do any final cleanup -->
</finally>
</trycatch>
In the second case, you need to pass back to the caller some state that indicates that the code did what you wanted it to do.
Note that the antcall task reloads the ant file (e.g., build.xml), so it can be an expensive operation. There are alternatives to using the antcall task:
Use the antcallback task (ant-contrib). The antcallback task specifically addresses the need to pass back data.
Use the depends attribute when defining a target to call dependent tasks.
Use the runtarget task (ant-contrib). With runtarget, all of your properties are passed and any properties you set in your target are available to the caller.
Use the macrodef task. It avoids reparsing of the ant file, can be passed attributes with default values, can be passed nested elements, and more. As such, this is the preferred solution in most cases.
In each of the cases above, just set return properties that you can inspect in the calling target to determine whether the called or dependent targets did what you expected them to do.

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

Can Ant continue when it encounters an error?

I have an Ant target that executes 2 steps in sequence:
<target name="release">
<antcall target="-compile"/>
<antcall target="-post-compile"/>
</target>
With the above script, it quits immediately if the "-compile" target fails. "-post-compile" does not get a chance to run. Is there a way to make sure the second step (-post-compile) is executed even if the 1st one (-compile) fails?
If you are using ant-contrib (which is very common), you could make use of the try-catch task and put your post-compile call into its finally element.
Also, if you are not using ant-contrib, then you might use the subant task to call your compile target. subant has a failonerror attribute, which you can use to individually ignore failed targets. Lots of usage examples on the task description page.
I think you are looking for
-keep-going (-k)
This will tell Ant to continue building all targets which do not depend on the failed target.

How do I get the target as a property in Ant?

Possibly one of those really terrible beginner questions where the manual will tell you everything, but, anyway, take this line below:
ant -Dfoo=bar buildme
in my build script, what is the property that holds "buildme"?
The list of targets invoked is available in the property
ant.project.invoked-targets
If there is a default target specified, then that will be the invoked target. If one or more targets are specified on the command line, these appear comma-separated in the property. Note that the property only becomes set once execution passes to a target - if you try to read the property outside of any target, it will be unset.
So, if the project has a default target 'zero':
$ ant one two
# ant.project.invoked-targets is set to:
one,two
and
$ ant
# ant.project.invoked-targets is set to (default):
zero
Seems like ant.project.invoked-targets is not available in ant 1.7.1
Not sure I understand your question, but "buildme" is the target to execute, not a property.
ant [options] [target [target2 [target3] ...]]
You "pick it" by creating the corresponding target:
<target name="buildme">
<!-- tasks that will execute here -->
</target>
As for the foo property, you "pick it" by using ${foo}.

Ant var and property scope

I have a main build script that calls various targets. One of these targets needs to store a value and another target needs to display it. Obviously this is not working so I think it may be related to scope. I've tried var, property, and declaring the property outside of target1. Since var seems to be mutable, it looks like I need to use it instead, but each time my output is empty.
Main script
<antcall target="target1"/>
<antcall target="display"/>
In target1:
<var name="myVar" value="${anotherVar}"/>
In display:
<echo>${myVar}</echo>
Do you really need to use <antcall>? Can you use target dependencies instead?
As you suspect, using <antcall> essentially creates a new scope.
antcall will start the ant target in a new project and will not affect the main project in any way. Try runtarget from antcontrib to run the targets in the same project.
You can call multiple targets with one antcall element. These targets will then share a single project instance including the properties defined. To do this specify the targets as nested elements like this:
<antcall>
<target name="target1"/>
<target name="display"/>
</antcall>
Another option I found was the antcallback, and it appears to work. This limits what is returned to just a particular list of values, which seems inherently safer than opening up the scope of the whole target (as it sets, creates, modifies many var and properties).
<antcallback target="target1" return="myVar"/>
<antcall target="display"/>
I think all of these are valid solutions, it just depends on what level you want to change the variable scope at.
<antcall target="display">
<param name="param1" value="anything" />
</antcall>
put the above code in your target1. I am sure you will be able to access your param1 in display now.

Resources