How can I add files in separate folders to a ZIP archive? - ant

I am trying to add 3 diferent TXT files to one ZIP file.
Those 3 TXT files are in separate folders but I have their path.
In the end, I just want a ZIP file with those 3 files in it.
Also, if one of them does not exist, will it include the 2 other ones or will it throw an exception and create no ZIP file?

<zip destfile="your.zip">
<fileset dir="path1" includes="file1.txt"/>
<fileset dir="path2" includes="file2.txt"/>
<fileset dir="path3" includes="file3.txt"/>
</zip>
You can include multiple filesets into a single zip file.
If the path doesn't exist, you'll get an error. If a file doesn't exist, it doesn't care. If none of the files exist, you'll get a warning.

Related

Change 'modified' time for all files in directory to the 'modified' time of files in other directory using ANT

Higuys.
I have a small problem with ant touch task.
What I need to do:
I have directory with sources:
C:\development\source\project\staticfiles\cartridge\rules\*.drl
and all files from it are copied to 'target' dir:
C:\development\target\project\release\rules\*.drl.
As they are copied using ant, the 'modified' time for newly created files in the 'target' dir is changed respectively, but I need to change to 'modified' time of a corresponding file from the 'source' dir after they are copied. Or in other words, I need 'modified' time of both files to be the same.
I guess ant touch can help here, but I do not know how to handle two directories at a time.
Thank you for your help.
you may use the preservelastmodified attribute of the <copy> task.
preservelastmodified : Give the copied files the same last modified time as the original source files.
eg.
<copy todir="${dest.dir}" preservelastmodified="true">
<fileset dir="${src_dir}"/>
</copy>

Zip task in Ant - incuding empty and non-empty subdirectories

Alright, I've been going slightly insane with this one - what bugs me more is that I'm sure a few years back I'd done something similar to what I'm trying to do now.
Let me say right off the bat, I am using ANT version 1.8.2, so I don't have the 1.6.2 issues with zip and empty folders. Most of my searching seems to bring up the 1.6.2 issue.
So, here's my build.xml snippet:
<target name="zip" depends="jar">
<echo>Creating zip file...</echo>
<zip destfile="${dist}/${zipfilename}">
<zipfileset dir="${dist}" includes="${jarfilename}" />
</zip>
<echo>...complete</echo>
</target>
This does what it's supposed to do, take the jar file from the {dist} directory, and put it in the zip so that the {dist} directory is NOT maintained - ie: the jar file gets extracted to wherever the zip file is.
HOWEVER, I would like to know how to do the following:
include a {config} directory and ALL the files within it except for one called "test-config.xml"
include two separate empty directories - say {subdir1} and {subdir2}. They may or may not have files in them, but I do NOT want ANY files in those directories when they get zipped.
For that second part with the empty directories, I'm perfectly content having the zip task create those in the zip itself without necessarily creating them on the local file system. In fact, the ideal would be if they'd be in the zip file and NOT be on the local file system - but I'll take whatever method I can get that works.
So, my local file system will look like so:
dist/MyJar.jar
config/config1.xml
config/config2.xml
config/test-config.xml
subdir1/ (may or may not exist and may or may not have files in it)
subdir2/ (may or may not exist and may or may not have files in it)
I want the ZIP file, when unzipped, to result in:
MyJar.jar
config/config1.xml
config/config2.xml
subdir1/
subdir2/
How do I accomplish this? I've tried variants of fileset, dirset, zipfileset, and am failing at every attempt. The best I've managed is to get the files in the {config} directory to get extracted as if the {config} directory doesn't exist... the hierarchy for that is NOT maintained, but I WANT it to be.
Here's one way you can use zipfileset to handle the config directory:
<zipfileset dir="." includes="config/*" excludes="config/test-config.xml"/>
The only way I can think of getting empty empty folders into the zip is to create them on the file system, add them using a zipfileset and then delete them once you have created the zip file.
Here is a fragment that does what you need (NOTE: I am using folder and file names based on your example; you can replace these with property references as needed):
<tempfile property="temp.file" destDir="." prefix="foo"/>
<mkdir dir="${temp.file}/subdir1"/>
<mkdir dir="${temp.file}/subdir2"/>
<zip destfile="${dist}/${zipfilename}">
<zipfileset dir="${dist}" includes="${jarfilename}"/>
<zipfileset dir="${temp.file}" includes="*"/>
<zipfileset dir="." includes="config/*" excludes="config/test-config.xml"/>
</zip>
<delete dir="${temp.file}"/>

Changing properties file inside a jar with Ant

I have a settings in a properties file located within a jar that I wish to alter at build-time using ant. Ideally if I am able to search for a specific text in the properties file and replace it easily, I would like to do that but isn't sure how.
So I was thinking I can overwrite it with another properties file that has the new settings already predefined. The jar already exists in my directory and the hierarchy of my jar is as follows:
food.jar
/com/food/donut.properties
some file...
some file...
If I had another donut.properties file with a different setting located in a different directory. How can I overwrite it with ant?
Thanks for the help, much appreciated!
EDIT:
With the following code I was able to copy the properties file into the jar. But whenever I attempt to copy the new properties file into the same directory of the old properties file, it does not get replaced. (i.e. If i change the prefix to 'com' i can see the new properties file being inserted into the jar. If the prefix is changed to com/food, nothing is replaced. What am i doing incorrectly?
<jar destfile="${dist.dir}/food.jar" update="true">
<zipfileset file="donut.xml" prefix="com/food/" />
</jar>
needs Ant 1.8.x
Step 1)
edit your propertyfile, multiple nested entry elements possible :
<propertyfile file="/path/to/propertyfile/foo.properties">
<!-- will change an existing key named 'somekey' with the value 'foo' inplace -->
<entry key="somekey" value="foo"/>
</propertyfile>
see Ant Manual propertyfile
Step 2)
update your jar with the altered propertyfile :
<jar destfile="/path/to/your/foo.jar" update="true">
<fileset dir="/path/to/propertyfile" includes="*.properties"/>
</jar>
for renaming use nested mapper like that :
<jar destfile="/path/to/your/foo.jar" update="true">
<mappedresources>
<fileset dir="." includes="*.properties"/>
<globmapper from="*.properties" to="/com/xml/*.properties"/>
</mappedresources>
</jar
The ant documentation of the jar task says:
The update parameter controls what happens if the JAR file already
exists. When set to yes, the JAR file is updated with the files
specified. When set to no (the default) the JAR file is overwritten.
An example use of this is provided in the Zip task documentation.
Please note that ZIP files store file modification times with a
granularity of two seconds. If a file is less than two seconds newer
than the entry in the archive, Ant will not consider it newer.
You might need to make sure the properties file is newer than the one in the jar file. Using the touch task could solve the problem.
Or you might just unzip the jar in the temp directory, copy the properties file with the copy task and its overwrite attribute set to true, and re-jar the contents of the temp directory.

How do I copy a directory from one location to another using Ant?

I am looking to copy a directory from one location to another. However, after looking at "copy" and "copyDir" (which is deprecated) it seems that Ant, by default, only copies the content of one location to another, not the actual directory (and everything in it).
So, as an example I have the following:
./Foo/test.txt
And I apply the following piece of Ant:
<copy todir="./build">
<fileset dir="./Foo"/>
</copy>
The result looks like this:
./build/test.txt
Whereas I would like it to be:
./build/Foo/test.txt
Hope that makes sense. How can I do that?
What about this:
<copy todir="./build">
<fileset dir=".">
<include name="Foo/**"/>
</fileset>
</copy>
To preserve the structure you would need to be copying the parent folder. There is a flatten option in the copy command, but it defaults to false. You can also make the directory structure you want, then copy at the file level straight into your fresh folder.
Here is the relevant line from the reference:
When a <fileset> is used to select files to copy,
the todir attribute must be set. Files that are
located under the base directory of the <fileset>
will be copied to a directory under the destination
directory matching the path relative to the base
directory of the <fileset>, unless the flatten
attribute is set to true.
The problem lies in that you are picking up the Foo folder, so you only get the files under it, you need to pick the folder above Foo to get the fileset where the ~/Foo/file.txt structure exists.

How can I exclude a list of files (held in a file) from an Ant fileset?

Is there a way to have an Ant Fileset->IncludesFile attribute take a property file OR any other file that contains a list of Java class files to exclude?
Eg:
File A.properties OR A.java contains listing
abc.class
mno.class
xyz.class
Is there a way to say to point excludesFile to file A.properties.
<fileset dir="...">
<excludesFile file="A.properties" />
</fileset>
The behavior that I want is when Java runs, it excludes the Java files listed in this file (A.properties)
Hmm...not sure if it's case sensitive. The documentation at http://ant.apache.org/manual/Types/fileset.html shows "excludesfile", all lowercase, as with other ant directives.
I'm not sure exactly what you are asking. If you have a fileset which is including files you would like to exclude, and you want to specify that list of files to exclude in an external file, "excludesfile" is the correct way to do it.

Resources