【问题标题】:Ant create filesets, dirsets from (absolute) propertiesAnt 从(绝对)属性创建文件集、目录集
【发布时间】:2011-02-25 21:40:41
【问题描述】:

在 ant 中,我定义了一些属性,这些属性定义了我的构建系统所需的一些路径(absolute)。

大多数 ant 任务都需要文件集,因此要从属性构建文件集,我必须这样做:

<fileset dir="" includes="${myprop}"/>

问题是myprop是绝对的,我应该省略dir属性(这是不可能的),所以有没有办法定义(绝对)属性并有效地使用他们来创建文件集、目录集等。 或在 ant 中 这是一种不好的做法(应该只使用相对路径)

谢谢。

【问题讨论】:

    标签: java ant


    【解决方案1】:

    Ant 没有关于绝对与相对的特定规则。如果可能,您应该避免硬编码绝对路径 - 以使您的构建更具可移植性。如果您必须对构建的某些部分使用绝对路径,请尝试构建它们 - 例如从项目的 ${basedir} 构建 - 以便更容易进行更改。

    对于将绝对路径转换为在文件集等中使用的相对路径可能有用的两件事:

    • property task 支持属性relative=,可用于将绝对路径转换为相对路径。
    • 当一个属性中有多个绝对路径时,pathconvert task 可以用来做同样的事情。

    例子:

    <!-- Absolute paths -->
    <property name="myprop" value="${basedir}/x" />
    <property name="myprop2" value="${basedir}/x:${basedir}/y" />
    
    <!-- Convert single path to relative to basedir -->
    <property name="myprop_rel" location="${myprop}" relative="yes"/>
    
    <!-- Go via path/pathconvert for the property with multiple paths -->
    <path id="mypath2" path="${myprop2}" />
    <pathconvert property="myprop2_rel" refid="mypath2" pathsep=",">
        <map from="${basedir}/" to="" />
    </pathconvert>
    
    <fileset id="my_fileset" dir="." includes="${myprop2_rel}" />
    

    回应评论:我不知道在 Ant 中获取文件集最长公共前缀目录的简单方法, 但这是一个包装脚本任务的宏,它执行您可能称之为“收缩包装”的操作。 您可以通过对“输入”文件集的引用以及要设置的属性的名称来调用它。

    <macrodef name="common-prefix-dir">
      <attribute name="refid" />
      <attribute name="outputproperty" />
      <sequential>
      <script language="javascript"><![CDATA[
    
        srcFiles = project.getReference( "@{refid}" )
                  .getDirectoryScanner( project )
                  .getIncludedFiles( );
    
        if ( srcFiles.length > 0 ) {
          prefix = "" + srcFiles[0];
          for ( i = 0; i < srcFiles.length; i++ ) {
            while ( prefix.length && srcFiles[i].substr( 0, prefix.length ) != prefix ) {
              prefix = prefix.substr( 0, prefix.length - 1);
            }
    
            if ( !prefix.length ) {
              break;
            }
          }
        }
        else {
          prefix = "";
        }
        prefix = prefix.substring( 0, prefix.lastIndexOf( '/' ) );
        project.setProperty( "@{outputproperty}", prefix );
    
      ]]></script>
      </sequential>
    </macrodef>
    

    (这来自php implementation。)

    你可以尝试一下:

    <property name="my.dir" location="...your dir here..." />
    <fileset id="my.fs" dir="${my.dir}">
      <!-- define fileset here -->
    </fileset>
    <echo message="Input fileset is: '${toString:my.fs}'" />
    
    <common-prefix-dir refid="my.fs" outputproperty="prefix" />
    <echo message="Longest common prefix is: '${prefix}'" />
    

    pathconvert 任务现在可用于创建收缩包装的文件集:

    <pathconvert property="shrink" refid="my.fs" pathsep=",">
      <map from="${my.dir}/${prefix}/" to="" />
    </pathconvert>
    <fileset id="my.fs.out" dir="${my.dir}/${prefix}" includes="${shrink}" />
    <echo message="Shrink-wrapped fileset is: '${toString:my.fs.out}'" />
    

    【讨论】:

    • 当一个属性中有多个绝对路径时,有没有办法获得最大的公共连续前缀(这将是 basedir)?
    • @alem0lars - 您的评论值得提出自己的问题。我添加了一个候选解决方案。
    【解决方案2】:

    我建议您为dir 目标使用不同的属性,如果您对${myprop} 进行绝对引用,我猜它是一个文件名。尝试将其分成 ${parent.dir} 和 ${target.filename}。

    <fileset dir="${parent.dir}" includes="${target.filename}"/>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多