简体   繁体   中英

Copy subdirectories if they contain a specific file in Ant

Really new to Ant and I have been trying to figure that out but could not...

Let say I have a structure like that :

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

I'd like to copy the files at the root (which is pretty simple filtering). But the the troubles come : I want to copy subdirectories of data only if they contain a file, here named include.xml. Here is what the destination folder should look like after copying

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

As you can see, /data/dir3, /data/dir5 and /data/dir1/subdir1 have not been copied, because they did not contain the include.xml file.

It might be simple but I could not find a way to do it, the property and available being set from what I understood globally ?

I don't think there exist a predefined property in ant because your requirements are very specific.

You may use <foreach> task from ant-contrib and write a recursive target which performs a copy.

Or you may implement the recursive solution in javascript using <script language="javascript"> . In this case you don't need additional libraries.

Yet another solution may be to copy everything and delete directories which don't contain include.xml.

You may find some examples here .

Here is an example thanks to the guidance of @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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM