Reputation: 175
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 ?
Upvotes: 1
Views: 412
Reputation: 175
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>
Upvotes: 1
Reputation: 21162
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.
Upvotes: 1