ant conditional import - ant

Is it possible to import a file in ant's build.xml if a property is set, if not then don't import it.
Is there a way OTHER THAN using ant-contrib if task.
Thanks

Yes, you can.
For example:
<target name="importFile" depends="myProperty.check" if="myPropertyIsSet">
<echo>Import my file here</echo>
</target>
<target name="myTarget.check">
<condition property="myPropertyIsSet">
<and>
<!-- Conditions to check if my property is set. -->
</and>
</condition>
</target>
Available conditions are described in Apache Ant Manual.

This is quite an old question but since Ant 1.9.1 you can use the "if"-attribute to do conditional imports:
<project name="cond-import" basedir="." xmlns:if="ant:if">
<condition property="script-exists">
<available file="other-ant-script.xml"/>
</condition>
<include if:set="script-exists" file="other-ant-script.xml"/>
</project>

Related

Getting condition doesn't support the nested "then" element in <condition>

I'm new to Ant/Apache. When I tried to use <condition> tag in XML it's throwing an error. condition doesn't support the nested "then" element. Here is my code
<target name="determine-ae-build">
<condition property="ApplicationName">
<equals arg1="${ApplicationName}" arg2="new"/>
<then>
<echo>3.9 Robots Config Copied</echo>
</then>
<else>
<condition property="ApplicationName">
<equals arg1="${ApplicationName}" arg2="old"/>
<then>
<echo>3.8 Robots Config Copied</echo>
</then>
<else>
<echo>3.9 Robots Config Copied</echo>
</else>
</condition>
</else>
</condition>
</target>
I've tried with IF also but since my Ant version is not supporting to do this. Can someone help to resolve this issue. Thanks! in advance
The condition task simply sets a property; it doesn't contain nested build logic. The property that it sets can later be used to control which targets are executed.
While you can use antcontrib's extra if, then, and else tasks to accomplish something like what you showed in your example, I'd recommend sticking to the native Ant approach, which relies on target dependencies and uses separate targets to control build logic:
<project name="build" basedir="." default="build">
<target name="build" depends="copy-3.8,copy-3.9" />
<target name="copy-3.8" depends="determine-ae-build" if="copy.old">
<echo>3.8 Robots Config Copied</echo>
</target>
<target name="copy-3.9" depends="determine-ae-build" unless="copy.old">
<echo>3.9 Robots Config Copied</echo>
</target>
<target name="determine-ae-build">
<condition property="copy.old">
<equals arg1="${ApplicationName}" arg2="old"/>
</condition>
</target>
</project>
With the above script, you would run ant build (possibly with -DApplicationName=old). The build target depends on both copy targets, both of which depend on determine-ae-build. The determine-ae-build target will therefore run first. If ApplicationName is set to "old" (either from a properties file that has been loaded, or from being provided in command line with -DApplicationName=old) then the property copy.old will be set to true. Otherwise it will remain unset.
Then copy-3.8 and copy-3.9 will be called. If copy.old is is true, copy-3.8 will run. Otherwise, it will be skipped. copy-3.9 has no condition so it will run no matter what.
Lastly, the build target will execute because it was the original target called from the command line, but it contains no actual steps so the build will finish.
<target name="prepare-copy" description="copy file based on condition" depends="determine-ae-build, prepare-copy-old, prepare-copy-new, prepare-copy-default">
<sleep seconds="10"/> --To read the results
</target>
<target name="prepare-copy-old" description="copy file based on condition" if="copy.old">
<echo>Old File Copied </echo>
</target>
<target name="prepare-copy-new" description="copy file based on condition" if="copy.new">
<echo>New File Copied</echo>
</target>
<target name="prepare-copy-default" description="copy file based on false condition" if="copy.default">
<echo>Default File Coping</echo>
</target>
<target name="determine-ae-build">
<condition property="copy.old">
<equals arg1="${ApplicationName}" arg2="old"/>
</condition>
<condition property="copy.new">
<equals arg1="${ApplicationName}" arg2="new"/>
</condition>
<condition property="copy.default">
<not>
<or>
<equals arg1="${ApplicationName}" arg2="new"/>
<equals arg1="${ApplicationName}" arg2="old"/>
</or>
</not>
</condition>
</target>
Explanation: Calling way "ant -Dcopy.old = true prepare-copy". Here we are passing to copy old file hence, "Old File Copied" will copied. If you call it like "ant prepare-copy" it'll call "Default File Coping".
Kindly Accept my answer if it is answered your question.Thankyou!

How to stop ant script execution or skip targets without fail?

I want to terminate an ant script, or skip some targets, but without the fail task. I wanted to do it like this:
`
<target name="init">
<condition property="canContinue">
<not>
<equals arg1="${isOffline}" arg2="1" />
</not>
</condition>
</target>
<target name="init-setup" depends="init" if="canContinue">
<echo message="CanContinue: ${canContinue}"/>
</target>
<target name="doIt" depends="init-setup">
</target>
`
I would like to skip all the targets which depend on init-setup, not just init-setup.
How can I do this?
Thank you!
If you're not using explicit fail tasks, you'll need to add your boolean flag to each target you want to skip.
Using your example:
<target name="doIt" depends="init-setup" if="canContinue">
</target>

can I use the same ant build file for windows and unix

I had ant build file for windows box and can I use the same build file for deploying on Unix also ?
Take all the file names and OS-dependent items and put them in properties files with the same keys. Use the <condition> task to load the correct properties file:
<target name="init-os">
<condition property="os.windows">
<os family="windows"/>
</condition>
<condition property="os.unix">
<os family="unix"/>
</condition>
</target>
<target name="init-windows-properties" depends="init-os" if="os.windows">
<property file="windows.properties"/>
</target>
<target name="init-unix-properties" depends="init-os" if="os.unix">
<property file="unix.properties"/>
</target>
<target name="init-properties" depends="init-windows-properties, init-unix-properties"/>
<target name="init-directories" depends="init-properties">
<mkdir .../>
<!-- More directories -->
</target>
<target name="init" depends="init-properties, init-directories"/>
Add more to the "init" target for the rest of the work you need to do.

Using a conditional length in ANT

I am currently trying to use the length task in ANT, more specifically making a conditional length task.
I want to to flag a message to a currently existing file if a file is greater than a set length, like so:
<project name="ant" default="check-filesize">
<target name="check-filesize">
<length mode="all" property="fs.length.bytes" when="gt" length="100">
<fileset dir="size" includes="*"/>
</length>
<echo>sorry your file set is to large</echo>
</target>
</project>
I have already written the code to print the size of all files in the directory but I haven't included it here to keep this brief.
If length does not allow for the echo tag can I perform this another way if not does any one know what the when tag does ? Obviously I only want the echo to happen when the condition is violated
Many thanks in advance
I discovered a way to do this using no external libraries, but thankyou for your help. here is how :
<project name="ant" default="check-filesize">
<target name="check-filesize">
<fail message="Your File Exceeds Limitations Please Operator For Full Size Of Data Set>
<condition>
<length length="1000" when="gt" mode="all" property="fs.length.bytes">
<fileset dir="size" includes="*"/>
</length>
</condition>
</fail>
</target>
</project>
Here is a way to conditionally echo a statement using Ant's built-in tasks:
<project name="ant-length" default="check-filesize">
<target name="check-filesize" depends="get-length, echo-if-large"/>
<target name="get-length">
<condition property="fs.length.too.large">
<length mode="all" when="gt" length="100">
<fileset dir="size" includes="*"/>
</length>
</condition>
</target>
<target name="echo-if-large" if="fs.length.too.large">
<echo>sorry your file set is too large</echo>
</target>
</project>
The third-party Ant-Contrib library has an <if> task that simplifies this.

In Ant, can I use a property inside a target's "depends"?

I m trying to do this with Ant:
<property name="test" value="123"/>
<target name="helloworld" depends="${test}"/>
But I'm getting error "Target ${test} does not exist in this project."
So I m guessing I can do this?
You can use the AntCall Task to call a Task inside another Task.
<project>
<target name="asdf">
<property name="prop" value="qwer" />
<antcall target="${prop}" />
</target>
<target name="qwer">
<echo message="in qwer" />
</target>
</project>
To make one depend on the other, you can set a parameter in the dependent task and check it in your calling task.
Rather than depends, you can check a property using the if attribute. See the manual for more details.
For example:
<target name="helloworld" if="test"/>
Note this only checks if the property is set (you can use unless to check if it is unset).
An alternative, more complex but powerful, approach is to use a nested condition on a depended target:
<target name="helloworld" depends="myTarget.check" if="myTarget.run">
...
</target>
<target name="myTarget.check">
<condition property="test">
<and>
<available file="foo.txt"/>
<available file="bar.txt"/>
</and>
</condition>

Resources