Copy content of subfolders with Ant - ant

How can I copy content of all subfolders of given folder using Ant?
i.e. I have such folder structure
folder/
folder/sub1/1.txt
folder/sub1/f1/1.txt
folder/sub2/2.txt
...
I don't know exact names of subfolders. And I need to copy content from all of them into one folder (keeping the structure of content, i.e. copying all files into one dir using flatten isn't a solution). I need to get
newfolder/1.txt
newfolder/1/1.txt
newfolder/2.txt
...
Does fileset allows to group subfolders in such a way?
** stands for zero or more directories, and usage of * as directory name is disallowed, i.e. <fileset dir="${dir}/*/" /> isn't acceptable.
Thanks in advance, Yury

<copy toDir="newfolder">
<fileset dir="folder">
<include name="*/**"/>
<exclude name="*"/>
</fileset>
<regexpmapper from="^[^/]*/(.*)$$" to="\1" handledirsep="true"/>
</copy>
You only need to specify handledirsep if you ever intend to run this script in Windows.

Related

Copying only files which have another file as a sibling [based on extension]?

I am trying to use ANT to copy some files of a C++ build into another directory.
The output of the build looks like this:
/Build
/LibA
LibA.lib
LibA.pdb
/LibB
LibB.lib
LibB.pdb
/ProjA
myexe.exe
myexe.pdb
/Foo
foo.exe
foo.pdb
/...
Now, I would like to copy all *.exe files and their *.pdb files to another directory (but not the *.pdb files of the libs).
I tried with:
<copy todir="outdir">
<fileset dir="Build">
<include name="**/*.exe" />
<include name="**/*.pdb" />
</fileset>
</copy>
However, then I will also get the *.pdb files inside the LibA, LibB, ... folders.
Is there any way I can only copy the pdb-files which have an *.exe-file in the same directory as their sibling?
Unfortunately, the folders are not named in any way that would allow using wildcards based on the folder name.
Of course, I could list each file individually, such as:
<include name="ProjA/*.pdb" />
<include name="Foo/*.pdb" />
<!-- ... -->
However, I am thinking that maybe there is an elegant way where I can specify "copy all *.exe files and all *.pdb files which have an *.exe file next to them".
You could use the <present> selector to find the "sibling" files, something like this:
<copy todir="outdir">
<fileset dir="Build" includes="**/*.pdb">
<present targetdir="Build">
<mapper type="glob" from="*.pdb" to="*.exe" />
</present>
</fileset>
<fileset dir="Build" includes="**/*.exe" />
<flattenmapper />
</copy>
This will only copy the .pdb files with matching .exe files.
To keep it simple, use a separate fileset for the exe files.
The flatten mapper is only needed if you want to copy just the files ignoring the directory structure in the source.

ant target : copying directories and the respective files that are in it

Suppose I have a directory structure like the following
/a/b/testB.xml
/a/c/testC.xml
/a/testD.xml
and I want to copy everything inside /a to /build
so that I will have
/build/b/testB.xml
/build/c/testC.xml
/build/testD.xml
What ant command should I use? I have tried using fileset and it looks like that it only copies the files that are specified in the includes to the todir directory.
Try this:
<copy todir="build">
<fileset dir="a">
<include name="**/*"/>
</fileset>
</copy>
The docs on FileSet are here.

Ant -- copying files and subdirectories from only one subdirectory on a tree

I'd like to copy files and subdirectories using Ant from a single subdirectory without copying the rest of the directory structure and contents. For example, I'd like to copy dir_3, its files (file_1 to file_n) and subdirectories (dir_4 and dir_5), but not dir_1 nor dir_2. Is there a pattern that I can use to do this?
temp
\--dir_1
\--dir_2
|
\--dir_3
|
\--dir_4
\--dir_5
\-- file_1
|
\--file_n
Thanks.
<copy todir="${copy.dir}">
<fileset dir="temp">
<include name="**/dir3/**"/>
</fileset>
</copy>
When you use the include directive, it will only include the files that match the pattern you give it. In this case, I'm copying only those files that have /dir3/ somewhere in their full path name. This includes sub-directories under dir3 and all files under dir3.
You can use the exclude directive to override the include directives:
<copy todir="${copy.dir}">
<fileset dir="temp">
<include name="**/dir3/**"/>
<exclude name="**/dir3/*"/>
</fileset>
</copy>
This will copy all sub-directories and files in those sub directories, but not the files under dir3 itself. The * matches all files in the directory while ** matches the all the files in the entire directory tree.
Notice this will create a directory temp/dir2/dir3. If I want temp/dir3, I have to set my fileset to the parent directory of dir3:
<copy todir="${copy.dir}">
<fileset dir="temp/dir2">
<include name="dir3/**"/>
</fileset>
</copy>
Doing this:
<copy todir="${copy.dir}">
<fileset dir="temp/dir2/dir3"/>
</copy>
Will create a directory temp with all the files directly under dir3 directly under temp. There will also be a temp/dir4 and temp/dir5 directory containing all the files (and directory trees) under those directories.
<copy todir="/some/path/foobar" verbose="true">
<fileset dir="/some/path/temp/dir2" includes="**"/>
</copy>
just use a fileset starting from dir2 including all dirs and files below..
verbose = true to echo all the files copied
May be you need to use overwrite = true also if the dir that is specified by todir
attribute already exists, otherwise existing files won't be overwritten by copy task

Apache Ant: Selecting files with fileset?

It's really easy to select a file with a specific filename, or filetype using fileset in ANT, however I have yet not figured out how to write a fileset that remove all files with a filename beginning with a dot, such as .builtpath, and .hgignore, but excluding .htaccess;
Here's my current file:
<delete includeemptydirs="true">
<fileset dir="${temp.dir}/fromRepo">
<exclude name=".htaccess"/>
<include name="**/*" /> <!-- How to select files starting with .?!-->
</fileset>
</delete>
Suggest you try:
<delete includeemptydirs="true">
<fileset dir="${temp.dir}/fromRepo">
<exclude name="**/.htaccess"/>
</fileset>
</delete>
If you don't specify any wildcard - as in ".htaccess" then that rule will only match the exact file name, i.e., '.htaccess' in the top-level directory of the fileset. Prepending the directory wildcard ** to .htaccess will tell Ant to exclude from the delete all files called '.htaccess' found under the directory hierarchy of the fileset.
There's an implicit include of all files if you don't specify any include rule - so no need to specify the 'global' include.
One thing to watch out for - setting includeemptydirs true will remove any empty directories when using a fileset with the delete task. A directory will only be considered empty if it doesn't contain any files. In other words: directories containing a file called '.htaccess' will not be deleted, but those with a '.htaccess' file will not be deleted - hope that's what you need.

ANT: Copy contents of multiple filesets with same files in order of priority

I'm trying to build a web application which takes it's class files from multiple locations. These locations can contain the same class files. I need to be able to specify a priority so that some locations take priority over others when copying the classes across.
We have separate ant scripts which build the WAR file. This build is to hotswap in any changed classes whilst I am developing. So this build must be quick.
For example, my two class locations are:
/bin
/build/classes
I want classes from both these directories to be copied to:
/web/WEB-INF/classes
However, if both these locations contain the same class file, eg:
/bin/com/ben/Test.class
/build/classes/com/ben/Test.class
I want files in /bin to always take priority.
So in the example:
the file: /bin/com/ben/Test.class, would be copied.
the file: /build/classes/com/ben/Test.class will be ignored.
My current script looks like this:
<sync todir="${deploy}/WEB-INF/classes" verbose="true">
<fileset dir="bin"/>
<fileset dir="build/classes"/>
</sync>
This works, but each time the script is run, dangling files are removed. I'm also not sure if any priority here is guaranteed.
Any assistance would be appreciated.
By dangling files being removed, do you mean files which are already in your "${deploy}/WEB-INF/classes" directory?
Sync will clear existing files in the target directory, if you don't want that to happen, I would recomend using copy instead.
As for having a folder with a higher priority, you could just copy multiple times and overwrite existing files.
<copy todir="${deploy}/WEB-INF/classes" verbose="true">
<fileset dir="build/classes"/>
</copy>
<copy todir="${deploy}/WEB-INF/classes" verbose="true" overwrite="true">
<fileset dir="bin"/>
</copy>
Now, test.class will be copied from build/classes then overwritten by test.class from bin.
It sounds to me like a very bad idea because if you have problems they will be time consuming to find out. But if you really want to do it here's a possible solution
<war [...] duplicate="preserve">
[...]
<classes dir="bin"/>
<classes dir="build/classes"/>
</war>

Resources