Ant zipfileset rename file - ant

I would like to include file to zipfileset but rename it as well
e.g.
<zipfileset dir="${basedir}/test/target" prefix="webapps">
<include name="test*.war"/>
</zipfileset>
but want to change name from test.war to sample.war
how to achieve this ? thank you.

You can probably do what you want using a mappedresources resource collection.
This 'worked for me' in a basic test (one input war called test1.war):
<mappedresources id="mapped.zfs">
<zipfileset dir="${basedir}/test/target">
<include name="test*.war"/>
</zipfileset>
<globmapper from="test*" to="webapps/sample*" />
</mappedresources>
<zip destfile="eg.zip">
<resources refid="mapped.zfs" />
</zip>
% unzip -l eg.zip
Archive: eg.zip
Length Date Time Name
--------- ---------- ----- ----
0 11-27-2012 00:19 webapps/
1423 11-27-2012 00:16 webapps/sample1.war
--------- -------
1423 2 files

I don't think this is possible, I'd go for 2 steps approach.
Either rename and add:
<move file="${basedir}/test/target/test.war" tofile="${basedir}/test/target/sample.war"/>
<zipfileset dir="${basedir}/test/target" prefix="webapps">
<include name="sample*.war"/>
</zipfileset>
or copy and add (if you need both):
<copy file="${basedir}/test/target/test.war" tofile="${basedir}/test/target/sample.war"/>
<zipfileset dir="${basedir}/test/target" prefix="webapps">
<include name="sample*.war"/>
</zipfileset>

martin clayton's answer worked for me. I was also able to do it all in one element (as children):
<zip destfile="eg.zip">
<mappedresources>
<zipfileset file="test*.war"/>
<globmapper from="test*" to="webapps/sample*" />
</mappedresources>
<!-- additional file-sets and resources may be listed here -->
</zip>

In addition to solution mentioned by peter, if you do not want to retain 2 copies of the same file... you can remove the copied one...
<copy file="${basedir}/test/target/test.war" tofile="${basedir}/test/target/sample.war"/>
<zipfileset dir="${basedir}/test/target" prefix="webapps">
<include name="sample*.war"/>
</zipfileset>
<delete file="${basedir}/test/target/sample.war"/>
Now you would not have duplicate copy of test.war.

Related

How do I flatten the top level folder of a zip file with ant?

A lot of zip files have a root folder, how do I unpack the zip file and get rid of the root folder?
I know there is the globmapper:
<unzip dest="${dest.path}">
<fileset dir="${source.path}">
<include name="**/zipfile*.*.zip" />
</fileset>
<mapper>
<globmapper from="rootFolder/*" to="*" />
</mapper>
</unzip>
But what if I don't know the name of the root folder? Wildcards are not working e.g.
<globmapper from="root*Folder/*" to="*" />
Is there a way to use wildcards or a mapper/function that upacks without the root folder?
There's actually a separate mapper specifically made for this called cutdirsmapper. Give this a try:
<unzip dest="${dest.path}">
<fileset dir="${source.path}">
<include name="**/zipfile*.*.zip" />
</fileset>
<cutdirsmapper dirs="1" />
</unzip>

How to include an empty folder in a zip file

I have created a zip file with many folders and files in it.
<!-- Create the distribution directory -->
<mkdir dir="${buildDirectory}/core/dist"/>
<zip destfile="${buildDirectory}/core/dist/core.zip">
<zipfileset dir="${buildDirectory}/core/" prefix="core/bin">
<include name="*.jar" />
</zipfileset>
<zipfileset dir="${buildDirectory}/core/src/resources" prefix="core/conf">
<include name="log4j.properties" />
<include name="core.properties" />
<include name="conf.xml" />
</zipfileset>
<zipfileset dir="${buildDirectory}/algorithm/testData" prefix="core/data">
<include name="defs.properties" />
<include name="proto.aza" />
</zipfileset>
So the zip now has
/bin
/conf
/data
I also need to include (add) an empty /logs folder in the zip structure.
How do I do that.
thanks
The least clumsy way I can find of doing this is to create an empty directory somewhere first, and then include it in your zipfile. Cutting down your example a bit, to get a zip with just an empty logs directory in it, you could write:
<mkdir dir="${buildDirectory}/core/dist"/>
<mkdir dir="${buildDirectory}/core/dist/logs"/>
<zip destfile="${buildDirectory}/core/dist/core.zip">
<zipfileset dir="${buildDirectory}/core/dist/logs" fullpath="logs"/>
</zip>

Ant: How to select the latest modified file from a directory?

Assume I have a directory which contains several files with the same name prefix and a timestamp, e.g.
my-directory:
- file-0749
- file-1253
- file-2304
How can I tell ANT to select the latest modified file from my directory (in this case this would be file-2304)?
You can do that with the TimestampSelector task from ant-contrib.
<timestampselector property="latest.modified">
<path>
<fileset dir="${my-directory.dir}">
<include name="file-*" />
</fileset>
</path>
</timestampselector>
<echo message="${latest.modified}" />
Found a way without an additional library:
<copy todir="${tmp.last.modified.dir}">
<last id="last.modified">
<sort>
<date />
<fileset dir="${my.dir}" />
</sort>
</last>
</copy>
<echo message="last modified file in ${my.dir}: ${ant.refid:last.modified}" />
You can work directly with ant.refid:last.modified like the echo task does. Don't forget to delete tmp.last.modified.dir.

copying multiple directories (and contents) in one shot

I've been using ant for nearly a decade, but every so often I need to do something beyond my-ordinary experience. This one lacked an obvious answer (and the intuitive approaches led to dead ends)
Problem:
Copy several subdirectories (and their contents) in directory "example" to new directory "myInstance". To clarify, copy some, but not all subdirectories in the source directory.
Source directory:
example/
ignoreThisDirectory/
ignoreThisOneAlso/
lib
etc/
webapps/
Attempt: Dead End
This attempt at first appeared to work. It created the subdirectories lib, etc,webapps. However 'copy' did not copy their contents; i was left with empty subdirectories.
<copy todir="myInstance" >
<dirset dir="example" includes="lib etc webapps"/>
</copy>
Successful But Verbose
In the end, I had to copy each directory individually, which seem verbose and non-DRY:
<copy todir="myInstance/etc">
<fileset dir="example/etc"/>
</copy>
<copy todir="myInstance/lib">
<fileset dir="example/lib" />
</copy>
<copy todir="myInstance/webapps">
<fileset dir="example/webapps" />
</copy>
thanks in advance
You can specify multiple inclusion and exclusion rules in a fileset. If you don't specify an inclusion rule, the default is everything is included, except anything that is excluded at least once by an exclude rule.
Here's an inclusive example:
<property name="src.dir" value="example" />
<property name="dest.dir" value="myInstance" />
<copy todir="${dest.dir}">
<fileset dir="${src.dir}">
<include name="lib/**" />
<include name="etc/**" />
<include name="webapps/**" />
</fileset>
</copy>
Note the ** wildcard that will bring in the full directory tree under each of the three 'leading-edge' sub-directories specified. Alternatively, if you want to specifically exclude a few directories, but copy over all others, you might omit inclusion (and thereby get the default all-inclusive behaviour) and supply a list of exclusions:
<copy todir="${dest.dir}">
<fileset dir="${src.dir}">
<exclude name="ignoreThisDir*/" />
<exclude name="ignoreThisOne*/" />
</fileset>
</copy>
You could further boil the particular example you gave down to one exclusion pattern:
<exclude name="ignore*/" />

How can I exclude files from a reference path in Ant?

In a project we have several source paths, so we defined a reference path for them:
<path id="de.his.path.srcpath">
<pathelement path="${de.his.dir.src.qis.java}"/>
<pathelement path="${de.his.dir.src.h1.java}"/>
...
</path>
Using the reference works fine in the <javac> tag:
<src refid="de.his.path.srcpath" />
In the next step, we have to copy non-java files to the classpath folder:
<copy todir="${de.his.dir.bin.classes}" overwrite="true">
<fileset refid="de.his.path.srcpath">
<exclude name="**/*.java" />
</fileset>
</copy>
Unfortunately, this does not work because "refid" and nested elements may not be mixed.
Is there a way I can get a set of all non-java files in my source path without copying the list of source paths into individual filesets?
Here's an option. First, use the pathconvert task to make a pattern suitable for generating a fileset:
<pathconvert pathsep="/**/*,"
refid="de.his.path.srcpath"
property="my_fileset_pattern">
<filtermapper>
<replacestring from="${basedir}/" to="" />
</filtermapper>
</pathconvert>
Next make the fileset from all the files in the paths, except the java sources. Note the trailing wildcard /**/* needed as pathconvert only does the wildcards within the list, not the one needed at the end:
<fileset dir="." id="my_fileset" includes="${my_fileset_pattern}/**/*" >
<exclude name="**/*.java" />
</fileset>
Then your copy task would be:
<copy todir="${de.his.dir.bin.classes}" overwrite="true" >
<fileset refid="my_fileset" />
</copy>
For portability, instead of hard-coding the unix wildcard /**/* you might consider using something like:
<property name="wildcard" value="${file.separator}**${file.separator}*" />

Resources