Control run of depends target ant? - ant

Based on whether a certain property is set I want to decide whether I want to run a target and its dependencies
Now I know that the "if" attribute can only control the run of the target in which it is specified and not the dependencies.
Is there any variant of "if" or any other alternative which would ensure that I control the run of a target and its dependencies too.
One alternative which comes to my mind it to have "if" attribute in all the dependent targets. But that seems redundant.

This has already been asked before in this question. The answer there applies very well. However, depending on how frequently the target is going to be invoked, another solution (more readable than the mentioned answer) is to use the if task from Ant-Contrib:
<if>
<equals arg1="condition_prop" arg2="some_value" />
<then>
<antcall target="target_with_dependencies" />
</then>
</if>

Related

Exclude fileset from another fileset using a property

I've been using Gradle almost exclusively lately, but every now and again I have to dive back into our antiquated ant build system and figure out how to do something. Then I realize how little I know about ant and/or how difficult even some of the simplest tasks appear to be.
For example, I have a target that does some operation on a fileset:
<target name="some-operation">
<fileset dir="blah" id="stuff">
<filename name="**/*.txt" />
<not>
<filename name="**/foo/*" />
</not>
</fileset>
<!-- do some operations on "stuff" -->
</target>
Imagine this is in some old build system that multiple projects use. I want to exclude additional things in the fileset (let's say, files inside directory "bar", similar to "foo"), but since this is something multiple projects use, I can't just go putting my custom exclusions into the build system. I need some way to plug that additional fileset in (it could contain multiple exclusions).
What's the best way of doing this? I'm thinking I'll set a property in my build with the files to exclude, but the some-operation target will have to handle it gracefully when that property is missing. However, if I set a fileset to a property, I'm not quite sure how to get it excluded from the original fileset in some-operation.
Any ideas of the best/cleanest way to do this?
For reuse create a macrodef with nested element holding 1-n filesets for flexibility.
See this answer providing an example of macrodef using nested element.

Need Ant condition example

Can someone please explain me with Example of Ant condition property with "if", "and", "not" and "istrue" with the code??
I'm new to Ant and need help on this.
Basically i need to download file using FTP. I have code to download it. but there are few condition i need to check before downloading.
Before downloading check the Downloadstatusvariable value (usually its true or false value")
check whether file is already downloaded or available in the path
if both the conditions fails then exec the FTP download code.
Thanks in advance.
ant-contrib is widely-used library and the if/else/for/foreach tasks will not only make it easier to write complex ant scripts, they'll make your ant scripts much more readable.
But, since you insist :)
The way I've handled this in the past is to set up a task A that only executes if property X is set, and make task A depend on some task B that checks the conditions and sets property X if they are true. For example:
<target name="get-ftp-file" depends="check-need-ftp-file" if="ftp.call.required">
<ftp ... />
</target>
<target name="check-need-ftp-file">
<condition property="ftp.call.required">
<and>
<not>
<!-- Checks if Downloadstatusvariable variable is true -->
<istrue value="${Downloadstatusvariable}"/>
</not>
<not>
<!-- Checks if file is present in filesystem -->
<available file="${my.file}"/>
</not>
</and>
</condition>
</target>
EDIT:
coolgokul, the <and> and <not> tasks are standard logical operators. The <available> condition in the example above evaluates to true if the file exists on the local machine. But we want to download the file only if the file does NOT exist on the local machine, so we wrap it up in the <not> task. Similar for the ${Downloadstatusvariable} check--we want to make sure it is not true, so we use <istrue> and then wrap it up in <not>.
Finally, we want to make sure that that the variable is not true AND the file does not exist, so we wrap up both those conditions in <and>. Translated to English, we're asking "Is Downloadstatusvariable not true, and is the downloaded file not available?"
Recommend you read more about conditional operators # http://ant.apache.org/manual/Tasks/conditions.html
Hope that helps.
The standard Ant does not have an "if" task, but you can do pretty much any conditional logic you need to by using the "condition' task. See http://ant.apache.org/manual/Tasks/condition.html for some examples.
There is a set of additional tasks including an "if" task in the ant-contrib library, but I'd advise against using this unless you really need to, due to the complexity it will add to your build environment.
Are you trying out using Ant Contrib Task?. If you click on the links over there, the document explains with example what you might want to achieve through each of the tasks
Some relevant examples might be here: Steve J's Blog

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

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.

Manually Start ANT Task

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.

Resources