Kann ich die Existenz eines Verzeichnisses in Ant überprüfen (keine Datei)?

71

Wie überprüfe ich mit Ant, ob ein Ordner vorhanden ist?

Wir können die Existenz einer Datei überprüfen, aber können wir dasselbe auch für einen Ordner tun?

Chathuranga Chandrasekara
quelle

Antworten:

103

Sie verwenden die verfügbare Aufgabe mit dem Typ "dir".

Zum Beispiel:

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

Die Standardmethode für die bedingte Verarbeitung ist die Bedingungsaufgabe . Im folgenden Beispiel wird beim Ausführen von doFoo eine Nachricht wiedergegeben, wenn das Verzeichnis vorhanden ist, während beim Ausführen von doBar eine Nachricht wiedergegeben wird, sofern das Verzeichnis nicht vorhanden ist.

Das Ziel dir.check wird sowohl von doFoo als auch von doBar benötigt. Es setzt die Eigenschaft dir.exists abhängig vom Ergebnis der verfügbaren Aufgabe auf true oder false. Das doFoo-Ziel wird nur ausgeführt, wenn diese Eigenschaft auf true gesetzt ist, und doBar wird nur ausgeführt, wenn es nicht auf false gesetzt oder gesetzt ist.

<?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 bietet zusätzliche Aufgaben, einschließlich einer If-Aufgabe, die die Verarbeitung vereinfachen (und für mich intuitiver) kann. Sie können die Antelope-Aufgaben von der Download-Seite herunterladen .

Reicher Verkäufer
quelle
1
Dadurch wird jedoch ein Eigenschaftswert auf true gesetzt. Wie soll ich dann den Zustand überprüfen? Ich meine ein "wenn"?
Chathuranga Chandrasekara
Warum ist die Überprüfung dir.check nach doFoo und doBar? sollte nicht umgekehrt sein? @ Rich Verkäufer
Miguel Ortiz
@MiguelOrtiz Die Deklarationsreihenfolge spielt keine Rolle, die Ausführung hängt nur von den dependsAttributen ab. Ich denke, es ist sauberer, sozusagen "öffentliche" Ziele oben und "private" Versorgungsziele unten zu setzen
Coderino Javarino
31

Hier ist ein kleines Beispiel, in dem das availableElement in einen ifTest integriert wird.

<!-- 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>

Warnung : Sie benötigen ant-contrib.jar in Ihrem Verzeichnis ANT_HOME \ lib, da Sie sonst keinen Zugriff auf die ifElemente haben und Ihr Skript mit diesem Fehler fehlschlägt:

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.
quelle
2
Ich mag die Einfachheit und Ausdruckskraft dieser Lösung. Es hat sich gelohnt, das extra schwere Heben zu installieren.
Jason Sperske
9

Hier ist meine Lösung, bei der keine Eigenschaften festgelegt und Ziele mit "wenn" oder "außer" verwendet werden müssen:

Makro:

<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>

Verwendung:

<assertDirAvailable dir="${dirToCheck}" />
bcody
quelle
Nett! Vermeidet ant-contrib.jar, was eine gute Sache ist. Hält es eher deklarativ als prozedural.
Cartland
Korrektur: Es sollte $ {ArtefaktDir} sein, nicht @ {ArtefaktDir}.
Cartland
Ich habe dieses Verwendungsbeispiel aus einem meiner tatsächlichen Build-Skripte kopiert, in denen ArtefaktDir ein Attribut in einem Makrodef war. Ich habe das Verwendungsbeispiel auf den möglicherweise häufigeren Fall geändert, dass ein Parameter anstelle eines Makrodef-Attributs übergeben wird. Vielen Dank!
bcody
1

Bei meiner Lösung mit der ANT 1.8-Version funktionieren ältere Versionen möglicherweise nicht, wenn die Syntax $ {evalTrueOrFalse} nicht unterstützt wird.

<?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 oder früher ANT 1.7 funktioniert nicht. Upgrade auf ANT 1.8.
  • Zielattribute, wenn und sofern die Syntax $ {var} nicht auf true / false ausgewertet wird
  • Bedingungsattribut Wert des else wird auf die Eigenschaft gesetzt, wenn die verfügbare Bedingung false war, ohne dass die Variable nicht festgelegt ist. Der NotSet-Wert ist nicht identisch mit einem expliziten falschen Wert.
  • Rufen Sie ein beliebiges Ziel auf, aber wenn / sofern-Attribut definiert, ob es tatsächlich ausgeführt wird

http://ant.apache.org/manual/properties.html#if+unless
[Wenn / Es sei denn] In Ant 1.7.1 und früheren Versionen konnten diese Attribute nur Eigenschaftsnamen sein. Ab Ant 1.8.0 können Sie stattdessen die Eigenschaftserweiterung verwenden. Im Vergleich zum älteren Stil bietet dies zusätzliche Flexibilität.

Wen
quelle
1
5+ Jahre später denke ich, dass doCustomize doMagic gewesen sein sollte.
TonyG
0

Hier ist ein anderer Ansatz, mit dem Sie nur eine Aufgabe aufrufen können, ohne ant-contrib.jar zu verwenden.

<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>
Rodrigo Riquelme Espinosa
quelle
0

Hier ist ein weiteres Beispiel für eine forSchleife. Fehler, wenn kein Verzeichnis vorhanden ist.

<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
quelle