75

How do I check for the existence of a folder using Ant?

We can check the existence of a file, but can we do the same for a folder as well?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Chathuranga Chandrasekara
  • 20,548
  • 30
  • 97
  • 138

6 Answers6

105

You use the available task with type set to "dir".

For example:

<available file="${dir}" type="dir"/>

The standard way to do conditional processing is with the condition task. In the example below, running doFoo will echo a message if the directory exists, whereas running doBar will echo a message unless the directory exists.

The dir.check target is required by both doFoo and doBar, it sets the dir.exists property to true or false depending on the result of the available task. The doFoo target will only run if that propery is set to true and doBar will only run if it is not set or set to false.

<?xml version="1.0"?>
<project name="test" default="doFoo" basedir=".">
  <property name="directory" value="c:\test\directory"/>

  <target name="doFoo" depends="dir.check" if="dir.exists">
    <echo>${directory} exists</echo>
  </target>

  <target name="doBar" depends="dir.check" unless="dir.exists">
    <echo>${directory} missing"</echo>
  </target>

  <target name="dir.check">
    <condition property="dir.exists">
      <available file="${directory}" type="dir"/>
    </condition>
  </target>
</project>

Antelope provides additional tasks, including an If task that can make the processing simpler (and to me, more intuitive), you can download the Antelope tasks from the download page.

martin clayton
  • 76,436
  • 32
  • 213
  • 198
Rich Seller
  • 83,208
  • 23
  • 172
  • 177
33

Here's a small example incorporating the available element into an if test.

<!-- Test if a directory called "my_directory" is present -->
<if>
  <available file="my_directory" type="dir" />
  <then>
    <echo message="Directory exists" />
  </then>
  <else>
    <echo message="Directory does not exist" />
  </else>
</if>

Warning: you need ant-contrib.jar in your ANT_HOME\lib directory otherwise you won't have access to the if elements, and your script will fail with this error:

Problem: failed to create task or type if
Cause: The name is undefined.
Action: Check the spelling.
Action: Check that any custom tasks/types have been declared.
Action: Check that any <presetdef>/<macrodef> declarations have taken place. 
Dan J
  • 25,433
  • 17
  • 100
  • 173
  • 2
    I like the simplicity and expressiveness of this solution. It was worth the extra heavy lifting to get ant-contrib.jar installed. – Jason Sperske Dec 28 '10 at 22:05
9

Here's my solution, which doesn't require setting properties and using targets with 'if' or 'unless':

Macro:

<macrodef name="assertDirAvailable">
    <attribute name="dir" />
    <sequential>
        <fail message="The directory '@{dir}' was expected to be available but is not">
            <condition>
                <not>
                    <available file="@{dir}" type="dir" />
                </not>
            </condition>
        </fail>
    </sequential>
</macrodef>

Usage:

<assertDirAvailable dir="${dirToCheck}" />
bcody
  • 2,489
  • 1
  • 21
  • 21
  • Nice! Avoids ant-contrib.jar which is a good thing. Keeps it declarative rather than procedural. – cartland Oct 21 '14 at 00:42
  • Correction though: it should be ${artifactDir} not @{artifactDir}. – cartland Oct 21 '14 at 00:51
  • I copied that usage example from an actual build script of mine where artifactDir was an attribute in a macrodef. I've changed the usage example to the possibly more common case of passing a parameter rather than a macrodef attribute. Thanks! – bcody Oct 21 '14 at 10:27
1

My solution using ANT 1.8 version, older versions may not work due if/unless not supporting ${evalTrueOrFalse} syntax.

<?xml version="1.0" encoding="UTF-8"?>
<project name="DoMagic" default="build" basedir=".">

<property environment="env" />
<property name="name" value="Do the ANT Magic" />
<property name="somedir" value="./must_exist_folder"/>
<tstamp><format property="TODAY" pattern="yyyy-MM-dd HH:mm:ss" /></tstamp>

<target name="doMagic" if="${dir.exists}">
  <echo message="Do the magic stuff" />
</target>

<target name="doUsage" unless="${dir.exists}">
  <echo message="Do usage and help" />
</target>

<target name="build">
  <echo message="Do the magic" />

  <condition property="dir.exists" else="false"><available file="${somedir}" type="dir" /></condition>
  <echo message="Folder found: ${dir.exists}" />
  <antcall target="doCustomize"></antcall>
  <antcall target="doUsage"></antcall>
</target>

</project>
  • ANT 1.6 or early ANT 1.7 does not work, upgrade to ANT 1.8 release.
  • Target attributes if and unless evaluates ${var} syntax to true/false
  • Condition attribute else value is set to property if available condition was false, without it variable is not set. NotSet value is not same as an explicit false value.
  • call any target but if/unless attribute defines whether its actually run

http://ant.apache.org/manual/properties.html#if+unless
[If/Unless] In Ant 1.7.1 and earlier, these attributes could only be property names. As of Ant 1.8.0, you may instead use property expansion. Compared to the older style, this gives you additional flexibility.

Whome
  • 10,181
  • 6
  • 53
  • 65
0

Here is another approach, allows to call just one task without using ant-contrib.jar.

<target name="my-task" depends="dir-check">
    <antcall target="my-task-install"/>
    <antcall target="my-task-update"/>
</target>
<target name="my-task-install" unless="dir.exists" >
    {some task}
</target>
<target name="my-task-update" if="dir.exists" >
    {another task}
</target>
<target name="dir-check">
    <condition property="dir.exists">
        <available file="my-dir" type="dir" />
    </condition>
</target>
0

Here is another example involving for loop. Fail if a directory does not exist.

<for list="dir1/, dir2/, dir3/" param="local.dir" >
    <sequential>
        <fail message="Directory @{local.dir} does not exist">
            <condition>
                <not>
                    <available file="@{local.dir}" type="dir" />
                </not>
            </condition>
        </fail>             
    </sequential>
</for>
GLampros
  • 121
  • 1
  • 8