Reputation: 13
I have a scenario where i need to move a directory from one location to another. If the same directory exists in the destination folder i need to rename the directory name as oldname_1. So i wrote a snippet as follows:
<target name="Move">
<IF>
<available file="${output.dir}" type="dir" />
<then>
<echo message="Directory exists" />
<rename src="${output.dir}" dest="${output.dir}_1"/>
<property name="newdirectory" value="${dest}"/>
</then>
<ELSE>
<echo message="Directory does not exist" />
</ELSE>
</IF>
<move file="${newdirectory}" todir="C:\reports" />
</target>
The error i am getting is :
Problem: failed to create task Cause: The name is undefined. Action: Check the spelling. Action: Check that any custom tasks/types have been declared. Action: Check that any / declarations have taken place.
Upvotes: 1
Views: 4934
Reputation: 107040
As Ian Roberts has already mentioned, you need the Ant-Contrib jar, and then setup the <taskdef/>
to point to this jar. I highly recommend putting it inside your project and checking it into your version control system. This way, when someone checks out your project, they already have the Ant-Contib.jar installed.
My standard is to put all optional jars required for the build (not jars required for compiling) in the directory ${basedir}/antlib
, then put each optional jar in its own directory, so I would put ant-contrib-1.0b3.jar
into ${basedir}/antlib/antcontrib
.
Then I define the task this way:
<property name="antlib.dir" value="${basedir}/antlib"/>
<taskdef resource="net/sf/antcontrib/antlib.xml">
<classpath>
<fileset dir="${antlib.dir}/antcontrib"/>
</classpath>
</taskdef>
This way, if you update the jar file to a new version of the Ant-Contrib jar, you simply plug it into the directory. You don't have to update the build.xml
.
Also note that I use net/sf/antcontrib/antlib.xml
and not net/sf/antcontrib/antcontrib.properties
. The XML file is what you should use. The directions for this are on the tasks page and differ from the ones on the main page under the installation directions. The reason is that the XML file has the correct definition for the <for>
task, and the properties file does not.
However, there is another way to do if
and unless
in Ant 1.9.1 without the need for optional jar files. These are the new If and Unless entity attributes.
These can be placed in all tasks, or sub-entities, and can usually replace the Ant-Contrib if/else
stuff:
<target name="move">
<available file="${output.dir}" type="dir"
property="output.dir.exists"/>
<echo message"Directory exists"
if:true="output.dir.exists"/>
<move file="${output.dir}" tofile="${output.dir}_1"
if:true="output.dir.exists"/>
<property name="newdirectory" value="${dest}"
if:true="output.dir.exists"/>
<echo message="Directory does not exists"
unless:true="output.dir.exists"/>
<move file="${newdirectory}" todir="C:\reports" />
</target>
Not so clean as your example. However, I would instead use the if=
and unless=
parameters on target names:
<target name="move.test">
<available file="${output.dir}" type="dir"
property="output.dir.exists"/>
</target>
<target name="move"
depends="move.test, move.exists, move.does.not exists">
<move file="${newdirectory}" todir="C:\reports" />
</target>
<target name="move.exists"
if="output.dir.exists">
<echo message="Directory exists" />
<move file="${output.dir}" tofile="${output.dir}_1"/>
<property name="newdirectory" value="${dest}"/>
</move.exists/>
<target name="move.does.not.exists"
unless="output.dir.exists"/>
<echo message="Directory does not exist" />
</target>
If you didn't echo everything, the structure would be a bit cleaner:
<target name="move.test">
<available file="${output.dir}" type="dir"
property="output.dir.exists"/>
</target>
<target name="move"
depends="move.test, backup">
<move file="${newdirectory}" todir="C:\reports" />
</target>
<target name="backup"
if="output.dir.exists">
<move file="${output.dir}" tofile="${output.dir}_1"/>
<property name="newdirectory" value="${dest}"/>
</move.exists/>
Upvotes: 2
Reputation: 122364
The if/else construct is not a native part of Ant out of the box, it is provided by the ant-contrib project, and you need to download a JAR and add the relevant <taskdef>
to your build file. For example, if you download ant-contrib-1.0b3.jar and put it in a directory named build
in the same directory as your build.xml, then you can say
<taskdef resource="net/sf/antcontrib/antcontrib.properties">
<classpath>
<pathelement location="build/ant-contrib-1.0b3.jar"/>
</classpath>
</taskdef>
Upvotes: 0