如果子目录包含Ant中的特定文件,则复制子目录

时间:2015-06-03 10:28:37

标签: xml recursion ant conditional-statements

Ant真的很新,我一直试图解决这个问题但不能......

假设我有这样的结构:

Root
|-data
  |-dir1
     |-include.xml
     |-subdir1
       |-file1
       |-file2
       |-include.xml
     |-subdir2
  |--dir2
     |-file1
     |-include.xml
  |--dir3
  |--dir4
     |-file1
     |-include.xml
  |--dir5
|-build.xml
|-other files

我想在根目录下复制文件(这是非常简单的过滤)。但麻烦来了:我只想复制数据的子目录,如果它们包含一个文件,这里名为include.xml。以下是复制后目标文件夹的样子

Root
|-data
  |-dir1
     |-include.xml
     |-subdir1
       |-file1
       |-file2
       |-include.xml
  |--dir2
     |-file1
     |-include.xml
  |--dir4
     |-file1
     |-include.xml
|-build.xml
|-other files

如您所见,尚未复制/ data / dir3,/ data / dir5和/ data / dir1 / subdir1,因为它们不包含include.xml文件。

这可能很简单,但我找不到办法,可以根据我的全球理解设置属性和可用性吗?

2 个答案:

答案 0 :(得分:1)

我不认为ant中存在预定义属性,因为您的要求非常具体。

您可以使用ant-contrib中的<foreach>任务并编写执行副本的递归目标。

或者您可以使用<script language="javascript">在javascript中实现递归解决方案。在这种情况下,您不需要额外的库。

另一种解决方案可能是复制所有内容并删除不包含include.xml的目录。

您可以找到一些示例here

答案 1 :(得分:1)

感谢@Oleg的指导,这是一个例子                          

  <target name="copy">
      <!-- Remove files if they are not neighbour of required ${data.checkfile} -->
      <script language="javascript"> <![CDATA[
        var getInclude = function(list) {
            var o = {};
            for (i=0; i<list.length; i++) {
              var f = list[i];
              if(f.indexOf(inc_file) > 0) {
                  var folder = f.split("/").slice(0,-1).join("/");;
                  o[folder] = f;
              }
            }
            return o;
        }
        importClass(java.io.File);

        // Access to Ant-Properties by their names
        data_dir = project.getProperty("data.dir"); // The directory where you want to check for subdirectory including X
        copy_dir = project.getProperty("copy.dir"); // The directory where you want to check for subdirectory including X
        inc_file = project.getProperty("data.required"); // The file which says if a folder should be copie

        // Create a <fileset dir="" includes=""/> to retrieve everything from this folder
        fs = project.createDataType("fileset");
        fs.setDir( new File(data_dir) );
        fs.setIncludes("**");
        ds = fs.getDirectoryScanner(project); // Get the files (array) of that fileset
        files = ds.getIncludedFiles(); // Get only the files

        //Create destination and sourceDir File instances
        basedir = new File(".");
        destination = new File(basedir, [copy_dir, data_dir].join("/"));
        source = new File(basedir, data_dir);

        //We create an object where key are folder containing said inc_file
        exist = getInclude(files);
        includes = [];
        for (i=0; i<files.length; i++) {
          filename = files[i];
          folder = filename.split("/").slice(0,-1).join("/");
          if(exist[folder]) {
              f = new File(source, filename);
              copy = project.createTask("copy");
              copy.setTofile(new File(destination, filename));
              copy.setFile(f);
              copy.perform();
          }
        }
      ]]>
    </script>
  </target>
</project>