<zipfileset> vs. <fileset> in ant - ant

The ant build tool provides two different tasks <fileset/> and <zipfileset/>.
According to the documentation <zipfileset/> allows us to extract files from a .zip file
if we use src attribute.
My question is if we are using dir attribute to select files then what is the difference between the two, <zipfileset/> and <fileset/>.
e.g.
<zipfileset dir="conf/Gateway>
<include name="jndi.properties" />
</zipfileset>
and
<fileset dir="conf/Gateway>
<include name="jndi.properties" />
</fileset>

One useful difference between the two tasks if you're building an archive (a ZIP or WAR or JAR for example) is that a zipfileset has a prefix attribute you can use to relocate the given files at a different folder in the archive. For example, if the following is included in a bigger set of fileset and zipfileset elements:
<zipfileset dir="conf/Gateway" prefix="properties">
<include name="jndi.properties" />
</zipfileset>
then the file conf/Gateway/jndi.properties will actually be included in the output as conf/Gateway/properties/jndi.properties. You can achieve the same end in other ways, but this is occasionally useful.
Otherwise, just use the task that seems most appropriate for the task at hand.

Related

Sync Task's Overwrite Attribute Copies Identical Files

I've come across an issue with Ant's Sync task where files are being copied unnecessarily. The goal is to update everything in the ${destination} directory with the contents of the ${source} directory, even if the file in the ${destination} is newer. Based on Ant's documentation, I've added an overwrite attribute to to ensure the ${destination} is overwritten.
<target name="test">
<sync todir="${destination}" overwrite="true" granularity="5000">
<fileset dir="${source}">
</fileset>
</sync>
</target>
This task correctly overwrites the ${destination}, but the file is always copied, even when the source and destination are identical. This leads to a lot of unnecessary traffic.
Based on the documentation, I attempted to configure the granularity attribute, but this doesn't appear to have any effect. I'm also running this test between two directories on the same machine, so I wouldn't expect timestamp differences (certainly not of more than 5 seconds).
Any thoughts about why the Sync task and overwrite attribute function in this way? Are there any solutions using the default set of Ant tasks to prevent the unnecessary file copying?
If you use the sync task with overwrite="true", you will get this behavior.
You could use it with overwrite="false", and then follow up with a copy task that only copy the files that are existing but different, with the different selector, e.g.:
<copy todir="${destination}">
<fileset dir="${source}">
<different targetdir="${destination}" ignoreFileTimes="true"/>
</fileset>
</copy>

how to input a text file for Ant delete task instead of a fileset

Is it possible to input a text file which contains the list of files that needs to be deleted using Ant Delete task?
I know there is an option for giving a fileset inside the delete task but since I have 100's of files that need to be deleted using ant delete.
For example
<target name="removeJarsFromList">
<delete includeEmptyDirs="true" failonerror="false">
<fileset dir="${my_base_dir}">
<include name="/a/file1.jar/**"/>
<include name="/b/file2.jar/**"/>
<include name="/somedir/file3.jar/**"/>
<include name="/c/file4.jar/**"/>
</fileset>
</delete>
</target>
Instead is there an option to have the files that needs to be deleted in a text file and give the text file as input.
myDeleteFileList.txt will have contents something like this
/a/file1.jar
/b/file2.jar
/somedir/file3.jar
/c/file4.jar
And give this file as input to the fileset ?
there's a includesfile attribute for the <delete> task.
includesfile: The name of a file. Each line of this file is taken to be an include pattern. All files are relative to the directory specified in dir. See HERE
<delete dir="${base.dir}" includesfile="abc.txt"/>
abc.txt:
(each line is an include pattern, relative to dir; avoid trailing / leading spaces)
**/fileA
/x/y/fileB
z/*.java
normally, the dir attribute in the <delete> task is used to delete the entire directory, but maybe this'll work. (i havent tried this, so) take a backup of your directory or try it on a temporary directory first!

Ant exclude file based on it's content

Is there any way to exclude files from an ant fileset based on the file content?
We do have test servers where code files are mixed up with files that have been generated by a CMS.
Usually, the files are placed in different folders, but there is a risk that real code files are in the middle of generated code.
The only way to differentiate generated files is to open the files and look at it's content. If the file contains a keyword, it should be excluded.
Does anyone know a way to perform this with Ant?
From the answer provided by Preet Sangha, Ishould use a filterchain. However, I'm missing a step here.
Let's say I load a text file of exclusions to be performed:
<loadfile property="exclusions" srcFile="exclusions.txt" />
But I don't know how to integrate it into my current copy task:
<copy todir="${test.dir}">
<fileset dir="${src.dir}">
</fileset>
</copy>
I tried to add the following exclude to the fileset but it does not do anything:
<exclude name="${exclusions}"/>
I'm sure I'm missing a simple step...
Have a look at the not and contains selectors.
The not selector contains an example of pretty much exactly what you're trying to do.
<copy todir="${test.dir}">
<fileset dir="${src.dir}">
<not>
<contains text="your-keyword-here"/>
</not>
</fileset>
</copy>
There's also the containsregexp selector which might be useful if your criteria for exclusion is more complicated.
There's a load more selectors you can use to refine your selection if needed.
I don't know ant but reading the docs....
Can you build a files list using a filterchain, and put this into the excludefiles of a fileset?
or
perhaps create a fileset with a filterchain that uses a filterreader and linecontainsregexp

How to suppress ant jar warnings for duplicates

I don't want ant's jar task to notify me every time it skips a file because the file has already been added. I get reams of this:
[jar] xml/dir1/dir2.dtd already added, skipping
Is there a way to turn this warning off?
This is an older question, but there is one obvious way to exclude the duplicates warning, do not include the duplicate files. You could do this in one of two ways:
Exclude the duplicate files in some fashion, or
Copy the files to a staging area, so that the cp task deals with duplicates, not the jar task.
So, instead of doing:
<jar destfile="${dist}/lib/app.jar">
<fileset dir="a" include="xml/data/*.{xml,dtd}"/>
<fileset dir="b" include="xml/data/*.{xml,dtd}"/>
<fileset dir="c" include="xml/data/*.{xml,dtd}"/>
</jar>
do one of:
<jar destfile="${dist}/lib/app.jar">
<fileset dir="a" include="xml/data/*.{xml,dtd}"/>
<fileset dir="b" include="xml/data/*.xml"/>
<fileset dir="c" include="xml/data/*.xml"/>
</jar>
or
<copy todir="tmpdir">
<fileset dir="a" include="xml/data/*.{xml,dtd}"/>
<fileset dir="b" include="xml/data/*.{xml,dtd}"/>
<fileset dir="c" include="xml/data/*.{xml,dtd}"/>
</copy>
<jar destfile="${dist}/lib/app.jar">
<fileset dir="tmpdir" include="xml/data/*.{xml,dtd}"/>
</jar>
<delete dir="tmpdir"/>
Edit: Base on the comment to this answer, there is a third option, although it is a fair bit more work... You can always get the source to the jar task, and modify it so that it does not print out the warnings. You could keep this as a local modification to your tree, move it to a different package and maintain it yourself, or try to get the patch pushed back upstream.
I don't know of any options on the jar task to suppress these messages, unless you run the whole build with the -quiet switch, in which case you may not see other information you want.
In general if you have lots of duplicate files it is a good thing to be warned about them as a different one may be added to that which you expect. This possibly indicates that a previous target of the build has not done its job as well as it might, though obviously without more details it is impossible to say.
Out of interest why do you have the duplicate files?

ant iterate over files

I want to iterate over a list of jars (undefined number) and add them all to the jar file.
To add them I plan to use something like this:
<jar id="files" jarfile="all.jar">
<zipfileset src="first.jar" includes="**/*.java **/*.class"/>
<zipfileset src="second.jar" includes="**/*.java **/*.class"/>
</jar>
but how do I iterate over them? I don't have ant-contrib
Thanks!
Just use zipgroupfileset with the Ant Zip task
<zip destfile="out.jar">
<zipgroupfileset dir="lib" includes="*.jar"/>
</zip>
This will flatten all included jar libraries' content.
If you do not have access to ant-contrib For task, you may end up to have to define your custom Task for doing what you need...
If you have ant1.6 and above, you can also try subant (see New Ant 1.6 Features for Big Projects):
If you use <subant>'s genericantfile attribute it kind of works like <antcall> invoking a target in the same build file that contains the task.
Unlike <antcall>, <subant> takes a list or set of directories and will invoke the target once for each directory setting the project's base directory.
This is useful if you want to perform the exact same operation in an arbitrary number of directories.

Resources