【问题标题】:Do I have a way to check the existence of a directory in Ant (not a file)?我有办法检查 Ant 中的目录(不是文件)是否存在吗?
【发布时间】:2010-11-12 22:26:38
【问题描述】:

如何使用 Ant 检查文件夹是否存在?

我们可以检查文件是否存在,但我们可以对文件夹做同样的事情吗?

【问题讨论】:

    标签: scripting ant build


    【解决方案1】:

    您使用类型设置为“dir”的available 任务。

    例如:

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

    进行条件处理的标准方法是使用condition task。在下面的示例中,如果目录存在,则运行 doFoo 将回显一条消息,而运行 doBar 将回显一条消息除非该目录存在。

    doFoo 和 doBar 都需要 dir.check 目标,它根据可用任务的结果将 dir.exists 属性设置为 true 或 false。 doFoo 目标仅在该属性设置为 true 时运行,doBar 仅在未设置或设置为 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 提供了额外的任务,包括一个 If 任务,可以使处理更简单(对我来说,更直观),您可以从 download page 下载 Antelope 任务。

    【讨论】:

    • 但这会将属性值设置为 true。那我应该如何检查情况。我的意思是任何“如果”?
    • 为什么验证dir.check在doFoo和doBar之后?不应该是另一种方式吗? @Rich 卖家
    • @MiguelOrtiz 声明顺序无关紧要,执行仅取决于depends 属性。我认为将所谓的“公共”目标放在顶部,将“私人”实用程序目标放在底部会更干净
    【解决方案2】:

    这是一个将available 元素合并到if 测试中的小示例。

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

    警告:您需要 ant-contrib.jar 在您的 ANT_HOME\lib 目录中,否则您将无法访问 if 元素,并且您的脚本将因以下错误而失败:

    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. 
    

    【讨论】:

    • 我喜欢这个解决方案的简单性和表现力。安装 ant-contrib.jar 是值得的。
    【解决方案3】:

    这是我的解决方案,它不需要设置属性和使用带有“if”或“unless”的目标:

    宏:

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

    用法:

    <assertDirAvailable dir="${dirToCheck}" />
    

    【讨论】:

    • 不错!避免 ant-contrib.jar 这是一件好事。保持声明性而非程序性。
    • 更正:它应该是 ${artifactDir} 而不是 @{artifactDir}。
    • 我从我的实际构建脚本中复制了该用法示例,其中 artifactDir 是宏定义中的一个属性。我已将使用示例更改为可能更常见的传递参数而不是宏定义属性的情况。谢谢!
    【解决方案4】:

    我的解决方案使用 ANT 1.8 版本,如果/除非不支持 ${evalTrueOrFalse} 语法,旧版本可能无法工作。

    <?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 或早期的 ANT 1.7 不起作用,请升级到 ANT 1.8 版本。
    • 目标属性 ifunless 将 ${var} 语法评估为真/假
    • 条件属性 else 如果可用条件为假,则将值设置为属性,否则不会设置变量。 NotSet 值与显式错误值不同。
    • 调用任何目标,但 if/unless 属性定义了它是否实际运行

    http://ant.apache.org/manual/properties.html#if+unless
    [If/Unless] 在 Ant 1.7.1 和更早版本中,这些属性只能是属性名称。从 Ant 1.8.0 开始,您可以改为使用属性扩展。与旧样式相比,这为您提供了额外的灵活性。

    【讨论】:

    • 5 年后,我认为 doCustomize 应该是 doMagic。
    【解决方案5】:

    这是另一种方法,允许在不使用 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>
    

    【讨论】:

      【解决方案6】:

      这是另一个涉及for 循环的示例。如果目录不存在则失败。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-12-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-01
        相关资源
        最近更新 更多