Ant copy with exclusion pattern does not seem to work - ant

The following Ant snippet should work:
...
<mkdir dir="${web.build.war.dir}/WEB-INF/classes"/>
<copy todir="${web.build.war.dir}/WEB-INF/classes">
<fileset dir="${web.build.classes.dir}">
<exclude name="**/pos/**" />
</fileset>
</copy>
...
It should copy every file from ${web.build.classes.dir} to ${web.build.war.dir}/WEB-INF/classes except those files that have /pos/ in their path.
But for some reason, when I do find build on the project, I get output that looks something like this:
...
build/war/WEB-INF/classes/my/path/to/pos
build/war/WEB-INF/classes/my/path/to/pos/Class1.class
build/war/WEB-INF/classes/my/path/to/pos/Class2.class
build/war/WEB-INF/classes/my/path/to/pos/Class3.class
build/war/WEB-INF/classes/my/path/to/pos/Class4.class
build/war/WEB-INF/classes/my/path/to/pos/Class5.class
build/war/WEB-INF/classes/my/path/to/pos/Class6.class
...
Every other similar copy operation appeared to work just fine.

Eh, in the end, the answer was quite obvious in hindsight.
In the original question I had omitted some of the tasks from the target for the sake of brevity. Appears, I should have not.
More complete snippet would have been this:
...
<mkdir dir="${web.build.war.dir}"/>
<copy todir="${web.build.war.dir}">
<fileset dir="${web.src.web.dir}">
<exclude name="**/pos/**"/>
<exclude name="security/**"/>
</fileset>
</copy>
<mkdir dir="${web.build.war.dir}/WEB-INF/classes"/>
<copy todir="${web.build.war.dir}/WEB-INF/classes">
<fileset dir="${web.build.classes.dir}">
<exclude name="**/pos/**" />
</fileset>
</copy>
...
The first copy task would copy all the resources from the development copy of the web resources to the war-to-be folder.
I was using Eclipse IDE and as the project was configured to build java classes to the ${web.src.web.dir}/WEB-INF/classes folder, the first task simply copied all of the classes to the war folder and thus the exclusion filter in the next copy task had no effect.

Related

Execute ant task over sons of parent folder

I was trying to execute a task over a fileset defined using something like this:
<target name="copyToTarget">
<copy todir="${target.folder}/" >
<fileset dir="../**/folder" />
</copy>
</target>
Is there anyway to achieve this?
EDIT:
I saw by myself I can use something like:
<fileset dir="../" includes="*/folder/** />
but the problem is that this copies the whole structure since the parent folder and I only need it contents (e.g., with this I obtain
/target/son1/folder/contents
and I'm looking for
/target/contents
EDIT 2:
Using How to strip one folder during Ant copy I managed how to get the result I need:
<target name="copyFolderToTarget">
<copy todir="${target.folder}" >
<fileset dir="../" includes="*/src_folder/**" />
<cutdirsmapper dirs="2"/>
</copy>
</target>

Ant using Fileset in jar task and renaming files

I have the following piece of code:
<jar destfile="${jar.file}">
<fileset dir="${basedir}/resources"/>
<include name="META-INF/ejb-jar.xml"/>
<include name="META-INF/persistence-prod.xml"/>
</fileset>
[...]
</jar>
The problem is that persistence-prod.xm1 should be persistence.xml when placed in the jar.
I know I could create a working directory and layout my whole jar there, and then jar that up. I know I can copy that one file elsewhere and rename it while copying. If I had a whole bunch of files named *-prod.xml to be renamed *.xml, I can use a file mapper inside the copy task. However, I want to be able to rename the file right in the <jar> task. I tried adding <globmapper> to the jar task, but I got the error message: jar doesn't support the nested "globmapper" element.
Any idea how this rename can take place while jaring the file?
Of course, the minute I asked the question, I figure out the answer:
I can't put <globmapper> directly into a <jar> task, but I can include <mappedresources> into the <jar> task, and place my <globmapper> in there:
Wrong:
<jar destfile="${jar.file}">
<fileset dir="${basedir}/resources"/>
<include name="META-INF/ejb-jar.xml"/>
<include name="META-INF/persistence-prod.xml"/>
</fileset>
<globmapper from="*-prod.xml" to="*.xml"/>
[...]
</jar>
Right:
<jar destfile="${jar.file}">
<fileset dir="${basedir}/resources"/>
<include name="META-INF/ejb-jar.xml"/>
</fileset>
<mappedresources>
<fileset dir="${basedir}/resources">
<include name="META-INF/persistence-prod.xml"/>
</fileset>
<globmapper from="*-prod.xml" to="*.xml"/>
</mappedresources>
[...]
</jar>
I guess this makes sense since it limits my file mapping to just the <mappedresources> and not to all <fileset> of the <jar> task.

Copying the most recent files with Ant

So I have a bunch of Jars in a directory that look like this:
library_2.4.3.jar 2/3/2012
library_3.0.1.jar 9/1/2012
api.lib_10.3.jar 3/2/2011
api.lib_12.4.5.jar 6/9/2012
I have already written the following using Ant 1.7 to copy the jars to where I want them and strip away the version number from the file
<copy todir="${lib.dir}" overwrite="true">
<fileset dir="${plugins.dir}">
<include name="library*.jar" />
<include name="api.lib*.jar" />
</fileset>
<regexpmapper from="(.*)_(.*).jar" to="\1.jar"/>
</copy>
The problem I'm running into is that I want it to copy the newer version of the file. Right now it seems to be copying only the older files. I have looked into the <sort> and <TimestampSelector> tasks but those are not supported under the copy task.
What can I do to copy the newer versions of the file?
Do not put them under the copy task directly... Create the property and use the property in the copy tag...
<timestampselector property="latest.modified">
<path>
<fileset dir="${my-directory.dir}">
<include name="file-*" />
</fileset>
</path>
</timestampselector>
<copy todir="." file="${latest.modified}">
Hope, it works.

How do I use Ant to copy a folder?

I'm trying to copy a directory using the Ant copy task.
I am a newbie at Ant; my current solution is:
<copy todir="${release_dir}/lib">
<fileset dir="${libpath}" />
</copy>
I'm wondering if there is a better and shorter way to accomplish the same thing?
First of all, those are the examples from Ant documentation:
Copy a directory to another directory
<copy todir="../new/dir">
<fileset dir="src_dir"/>
</copy>
Copy a set of files to a directory
<copy todir="../dest/dir">
<fileset dir="src_dir">
<exclude name="**/*.java"/>
</fileset>
</copy>
<copy todir="../dest/dir">
<fileset dir="src_dir" excludes="**/*.java"/>
</copy>
Copy a set of files to a directory, appending .bak to the file name on the fly
<copy todir="../backup/dir">
<fileset dir="src_dir"/>
<globmapper from="*" to="*.bak"/>
</copy>
Secondly, here is the whole documentation about copy task.
Just because the docs were not very clear to me, and because the time I spent can serve others:
The docs say that this "copies a directory (dir1) to another directory (dest)":
<copy todir="../new/dest">
<fileset dir="src/dir1"/>
</copy>
Actually, this does not mean "copy dir1 inside dest", but rather "copy the contents of dir1 inside dest".
(In general, in Ant, the "root dir" of a filesets -as well at the todir attribute- is not considered as being part of the set itself.)
To place the directory dir1 inside dest one has several alternatives (none totally satisfying to me - and I'd imagined that the new DirSet would help here, but no)
<copy todir="../new/dest/dir1">
<fileset dir="src/dir1"/>
</copy>
or
<copy todir="../new/dest">
<fileset dir="src" includes="dir1/**"/>
</copy>
See also here and here.
From http://ant.apache.org/manual/Tasks/copy.html:
<copy todir="../new/dir">
<fileset dir="src_dir"/>
</copy>
This will do it:
<copy todir="directory/to/copy/to">
<fileset dir="directory/to/copy/from"/>
</copy>
The ant manual is your friend: Ant Manual, in this case: Copy Task

Ant - copy only file not directory

I need to copy all files in a folder except directory in that folder using Ant script.
Im using below script to do that.
<copy todir="targetsir">
<fileset dir="srcdir">
<include name="**/*.*"/>
</fileset>
</copy>
But it copies all files and directory in that folder.
how to restrict/filter directory in that folder?
thanks,
I think there is an easier way.
flatten="true" - Ignore directory structure of source directory, copy all files into a single directory, specified by the todir attribute. The default is false.
Do you mean that srcdir conatins sub-directories, and you you don't want to copy them, you just want to copy the files one level beneath srcdir?
<copy todir="targetsir">
<fileset dir="srcdir">
<include name="*"/>
<type type="file"/>
</fileset>
</copy>
That should work. The "**/*.*" in your question means "every file under every sub directory". Just using "*" will just match the files under srcdir, not subdirectories.
Edited to exclude creation of empty subdirectories.
I do not have enough reputation to comment, so I'm writing new post here. Both solutions to include name="*" or name="*.*" work fine in general, but none of them is exactly what you might expect.
The first creates empty directories that are present in the source directory, since * matches the directory name as well. *.* works mostly because a convention that files have extension and directories not, but if you name your directory my.dir, this wildcard will create an empty directory with this name as well.
To do it properly, you can leverage the <type /> selector that <fileset /> accepts:
<copy todir="targetsir">
<fileset dir="srcdir">
<include name="*"/>
<type type="file"/>
</fileset>
</copy>
Can you try
<copy todir="targetsir">
<fileset dir="srcdir">
<include name="*.*"/>
</fileset>
</copy>
** is used to match a directory structure.
<copy todir="targetsir" includeEmptyDirs="false">
<fileset dir="srcdir">
<include name="*"/>
</fileset>
</copy>
If your folder has many subdirectories and you don't want them to be copied (if you want only files) try this..
<target name="copy">
<copy todir="out" flatten="true">
<fileset dir="tn">
<filename name="**/cit.txt" />
</fileset>
</copy>
</target>
The secret is to use not fileset but dirset instead.

Resources