Check the existence file in ant [duplicate] - ant

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Ant task to check if a file exists?
How can one check if a file exist in a directory, if not use another file in different location. I tried the follow but does not help me with what I want. Could someone help?
<condition property="somefile.available">
<or>
<available file="/home/doc/somefile"/>
<and>
<available file="/usr/local/somefile" />
</and>
</or>
</condition>

Use condition tests to establish if files are present. Then have a target for each true condition
<target name="go" depends="file-checks, do-something-with-first-file, do-something-with-second-file"/>
<target name="file-checks">
<available file="/home/doc/somefile" property="first.file.found"/>
<available file="/usr/local/somefile" property="second.file.found"/>
</target>
<target name="do-something-with-first-file" if="first.file.found">
???
</target>
<target name="do-something-with-second-file" if="second.file.found">
???
</target>

If you don't mind using ant-contrib you can take the procedural approach like this:
<if>
<available file="file1"/>
<then>
<property name="file.exists" value="true"/>
</then>
<else>
<if>
<available file="file2"/>
<then>
<copy file="file2" tofile="file1"/>
<property name="file.exists" value="true"/>
</then>
</if>
</else>
</if>
Otherwise you can probably use a target that is conditional on a property being set to indicate whether the file already exists in the preferred location, like Ant task to run an Ant target only if a file exists? but using unless instead of if.

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 check if Ant is executed under certain path?

How can I use Ant to verify that the current working directory is located (arbitrarily deeply nested) under a certain path? For example, I want to execute a target only if the current directory is part of /some/dir/, for example if Ant is executed in directory /some/dir/to/my/project/.
The best I could come up with is a String contains condition:
<if>
<contains string="${basedir}" substring="/some/dir/"/>
<then>
<echo>Execute!</echo>
</then>
<else>
<echo>Skip.</echo>
</else>
</if>
This works for my current purpose but I'm afraid it might break some time in the future... for example when a build is executed in path /not/some/dir/ which is also contains the specified directory string.
Are there any more robust solutions like a startsWith comparison or even better a file system based check...?
There is no specific startswith condition in native Ant, but there is a matches condition that takes regular expressions.
As a side note, ant-contrib is rarely necessary for most build scripts, and will often lead to unreliable code. I would strongly recommend avoiding it.
Here's a sample script to illustrate how you can use the matches condition with native Ant. The test target is, of course, just for demonstration.
<property name="pattern" value="^/some/dir" />
<target name="init">
<condition property="basedir.starts.with">
<matches pattern="${pattern}" string="${basedir}" />
</condition>
</target>
<target name="execute" depends="init" if="basedir.starts.with">
<echo message="Executing" />
</target>
<target name="test">
<condition property="dir1.starts.with">
<matches pattern="${pattern}" string="/some/dir/" />
</condition>
<condition property="dir2.starts.with">
<matches pattern="${pattern}" string="/some/dir/to/my/project/" />
</condition>
<condition property="dir3.starts.with">
<matches pattern="${pattern}" string="/not/some/dir/" />
</condition>
<echo message="${dir1.starts.with}" />
<echo message="${dir2.starts.with}" />
<echo message="${dir3.starts.with}" />
</target>

Conditionally load properties files in Ant

My Ant script should download a ZIP file which contains a set-up file to be installed in a database (Oracle or PostgreSQL) and generate dumps. Different dumps are generated depending on the properties data provided in the set up file.
I have 3 properties files:
user.properties : this contains various details provided from Jenkins and apart from that a value: prepare.MTdump.generate=true
nonMT.properties
MT.properties
Is it possible in Ant to load the first properties file user.properties and depending upon the condition (e.g. if prepare.MTdump.generate=true) load MT.properties or if it's false load nonMT.properties?
I have been unable to add an IF condition to load the properties file. I even tried with the unless condition of <target> but have been unable to achieve the requirement.
If you are using ant-contrib, this should work:
<property file="user.properties"/>
<if>
<equals arg1="${prepare.MTdump.generate}" arg2="true"/>
<then>
<property file="MT.properties"/>
</then>
<else>
<property file="nonMT.properties"/>
</else>
</if>
Otherwise, you can just use conditions. Just run the loadProperties target below.
<property file="user.properties"/>
<target name="test.if.use.MT">
<condition property="useMT">
<equals arg1="${prepare.MTdump.generate}" arg2="true"/>
</condition>
<condition property="useNonMT">
<not>
<equals arg1="${prepare.MTdump.generate}" arg2="true"/>
</not>
</condition>
</target>
<target name="loadMTProperties" if="${useMT}" depends="test.if.use.MT">
<property file="MT.properties"/>
</target>
<target name="loadNonMTProperties" if="${useNonMT}" depends="test.if.use.MT">
<property file="nonMT.properties"/>
</target>
<target name="loadProperties" depends="loadMTProperties, loadNonMTProperties"/>

How to use logical operators in ant?

i have a small peice of code which prints if platform is unix or windowsas
<if>
<equals=${arg1} value="linux-86"/>
<then>
<echo message="linux"
<then>
<elseif>
<equals=${arg1} value="linux-64"/>
<then>
<echo message="linux"/>
</then>
</elseif>
<else>
<echo message="Windows">
</else>
</if>
Here we can see we are unnecessarily checking first two conditions for same message,is there any OR operator in ant like we have in c ||,so that we can write arg1=linux-64||linux-86....if there is please tell me how should i use this will save up lot of time here
<condition property="WinPlatform.Check">
<or>
<equals arg1="${param1}" arg2="win-x86"/>
<equals arg1="${param1}" arg2="win-x86-client"/>
<equals arg1="${param1}" arg2="win-x64"/>
</or>
</condition>
<target name="Mytarget" if="WinPlatform.Check">
<echo message="executing windows family build:::${param1}"/>
</target>
now call Mytarget with your parameter,it will work
The if task is part of ant-contrib. It is not available in core Ant.
Various conditions are available in core Ant and can be used, for example, to make target execution conditional.
Before 1.8, if/unless conditions evaluate "is the property set?"
<target name="test" if="foo" unless="bar"/>
From 1.8, if/unless conditions can evaluate "is the property true/false":
<target name="test" if="${foo}" unless="${bar}"/>
Why don't you have a look in the ant manual? http://ant.apache.org/manual/Tasks/conditions.html
Or google for "ant if task".

subant on condition

I'd like to execute subant on some condition. something like:
<if>
<equals value="value1" property="${some.property">
<then>
<subant target="#{target}" failonerror="true" inheritall="false">
<buildpath refid="some-ref1" />
</subant>
</then>
<else>
<subant target="#{target}" failonerror="true" inheritall="false">
<buildpath refid="some-ref2" />
</subant>
</else>
</if>
But can't find a way to do it. Read the ant manual and googled, but no solution is found.
Thanks.
I believe the error may lie in your equals tag. Instead of using the 'value' and 'propery' attributes, try using 'arg1' and 'arg2', i.e.:
<equals arg1="value1" arg2="${some.property}">
Check out the examples in the ant-contrib doc: http://ant-contrib.sourceforge.net/tasks/tasks/if.html.
If the problem is that your 'if', 'then', and/or 'else' tags are not resolving properly, then you may be missing the ant-contrib libraries. Ant-contrib is not natively included with ant, but you can download it here: http://sourceforge.net/projects/ant-contrib/files/
Per the ant-contrib site (http://ant-contrib.sourceforge.net/), here's what you must do to install ant-contrib:
Option 1: Copy ant-contrib-0.3.jar to the lib directory of your Ant installation. If you want to use one of the tasks in your own project, add the lines
<taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
to your build file.
Option 2: Keep ant-contrib-0.3.jar in a separate location. You now have to tell Ant explicitly where to find it (say in /usr/share/java/lib):
<taskdef resource="net/sf/antcontrib/antcontrib.properties">
<classpath>
<pathelement location="/usr/share/java/lib/ant-contrib-0.3.jar"/>
</classpath>
</taskdef>
Please look up a <target if="${some.property}>. You may want another target with an unless.
If the property has to do with a file existing, see Ant task to check a file exists?. Even if this is not your main concern, I am sure you can get the idea from the accepted answer.
Do you mean calling another target
if so here is
<if>
<equals value="value1" property="${some.property">
<then>
<antcall target="#{target}" failonerror="true" inheritall="false">
</then>
<else>
<antcall target="#{target}" failonerror="true" inheritall="false">
</else>
</if>

Resources