Using mapper & fileset to copy files into a different subdirectory? - ant

I want to create an Ant target that copies files in a directory to a destination directory with the same folder structure, plus one more subfolder appended.
For example, the source is:
a/b/c/foo.pdf
d/e/f/bar.pdf
I want the destination to be:
a/b/c/x/foo.pdf
d/e/f/x/bar.pdf
Here is my target so far, but it doesn't appear to be doing anything:
<copy todir="${dest.dir}">
<fileset dir="${src.dir}" casesensitive="yes">
<include name="**${file.separator}foo.pdf" />
</fileset>
<mapper type="glob"
from="foo.pdf" to="x${file.separator}foo.pdf" />
</copy>
What am I missing?

You could use a regexp mapper:
<copy todir="${dest.dir}">
<fileset dir="${src.dir}" casesensitive="yes">
<include name="**/*.pdf"/>
</fileset>
<mapper type="regexp" from="^(.*)/(.*\.pdf)" to="\1/x/\2" />
</copy>
I've used hard-coded file.separators to shorten. Basically, you split the path to the input file (from) into directory and filename (capture \1 and \2) and then insert the \x extra element between them (to).
I'm not clear on your example - it looks like you want to match 'bar.pdf' and rename it to 'foo.pdf', as well as changing the directory. If you need to do that, you might consider chaining a couple of simpler regexp mappers, rather than trying to cook up one complex one:
<copy todir="${dest.dir}">
<fileset dir="${src.dir}" casesensitive="yes">
<include name="**/*.pdf"/>
</fileset>
<chainedmapper>
<mapper type="regexp" from="^(.*)/(.*\.pdf)" to="\1/x/\2" />
<mapper type="regexp" from="^(.*)/(.*\.pdf)" to="\1/foo.pdf" />
</chainedmapper>
</copy>
When using a glob mapper, you need to specify one wildcard * in the from field:
Both to and from are required and
define patterns that may contain at
most one *. For each source file that
matches the from pattern, a target
file name will be constructed from the
to pattern by substituting the * in
the to pattern with the text that
matches the * in the from pattern.
Source file names that don't match the
from pattern will be ignored.
So something like this might work:
<mapper type="glob" from="*/foo.pdf" to="*/x/foo.pdf" />

Related

Add .class to ant build classpath

I am trying to add a few folders to the classpath in our ant build file.
<dirset dir="${env.WT_HOME}/codebase/com/lcs/wc/">
<include name="flexbom flexQuerySpec flextype foundation material util moa" />
</dirset>
All these folders (i.e. 'flexbom' 'flexQuerySpec'...) are inside codebase/com/lcs/wc folder. Each folder has several class files. I want to add all these class files to the path.
Above script doesn't seem to be working. I am still getting class not found for these folder/packages.
Nested <include> elements in a <fileset> or <dirset> specify matching patterns, one pattern per element, rather than lists.
An alternative is to use the includes attribute instead like this:
<dirset dir="${env.WT_HOME}/codebase/com/lcs/wc/"
includes="flexbom flexQuerySpec flextype foundation material util moa" />
Or multiple include elements:
<dirset dir="${env.WT_HOME}/codebase/com/lcs/wc/">
<include name="flexbom" />
<include name="flexQuerySpec" />
<include name="flextype" />
<include name="foundation" />
<include name="material" />
<include name="util" />
<include name="moa" />
</dirset>

Why excludesfile is not working?

I have a list of class files to be excluded and i have added them in a file (say) exclude_class.txt as :
**/a/b/c/*.class
**/d/e/f/*.class
**/g/h/i/j/*.class
**/k/l/*.class
Now when I use excludesfile in fileset task it is not working:
<fileset dir=".">
<include name="A/**/*.class"/>
<include name="B/**/*.class:/>
<excludesfile name="exclude_class.txt"/>
</fileset>
Please let me know what is the issue here. What should be the syntax of file to use in excludesfile task.
excludesfile (and also excludes, includes, includesfile) is an attribute of <fileset> and not a nested tag. you may use it like this:
<fileset dir="." excludesfile="exclude_class.txt">
<include name="A/**/*.class"/>
<include name="B/**/*.class:/>
</fileset>
on the other hand, <include>, <exclude> are nested tags and may be used in the manner in which you've written.
as for the syntax within exclude_class.txt.. just make sure that there are no leading / trailing spaces in each line.

How do I use a patternset to filter a list of files?

This seems like something that should be obvious, but I don't think it is. Given:
a space-delimited list of files (or comma-delimited, etc.)
a <patternset> of whitelisted patterns
How do I come up with a <fileset> that contains all of the files in the list that match the whitelisted pattern?
Getting a list of files from the list is easy enough:
<patternset id="the-patternset" includes="${list.of.files}" />
<fileset id="the-fileset" dir="${basedir}">
<patternset refid="the-patternset" />
</fileset>
<pathconvert pathsep="${line.separator}" property="the-filelist" refid="the-fileset"/>
<echo>fileset: ${the-filelist}</echo>
…will happily produce a fileset with all of the files in ${list.of.files}. But adding a filter of sorts:
<patternset id="the-filter">
<include name="includeme/**/*.java" />
<exclude name="excludeme/**/*.java" />
</patternset>
<patternset id="the-patternset" includes="${list.of.files}" />
<fileset id="the-fileset" dir="${basedir}">
<patternset refid="the-patternset" />
<patternset refid="the-filter" />
</fileset>
<pathconvert pathsep="${line.separator}" property="the-filelist" refid="the-fileset"/>
<echo>fileset: ${the-filelist}</echo>
…will list a union of the patternsets—i.e., all files that match either the-filter or the-patternset.
How do I produce a fileset containing files that are in ${list.of.files} and match the-patternset?
Here's a potted example. Create two filesets (or perhaps filelists) one from each of your patternsets. I'll just use fixed lists here:
<property name="list.1" value="a,b,c" />
<property name="list.2" value="b,c,d" />
<fileset dir="." id="set.1" includes="${list.1}" />
<fileset dir="." id="set.2" includes="${list.2}" />
Then use the <intersect> resource collection to get the required 'overlap' set:
<intersect id="intersect">
<resources refid="set.1"/>
<resources refid="set.2"/>
</intersect>
Most Ant tasks will allow you to use a resource collection in place of a simple fileset.

Exporting zipfilesets

We are currently generating a zip file using multiple targets as follows.
<zipfile>
<zipfileset dir="alpha" prefix="alpha" />
<zipfileset dir="beta" prefix="alpha" excludes="*.bar" />
<zipfileset dir="gamma/G" prefix="gamma" />
</zipfile>
A requirement has come up in that we need to generate (and include) a list of the included files and their corresponding MD5 checksum values.
If we use a <fileset>/<patternset>/<pathconvert> combination, I can get a text file containing all the files, and generate from there. However, I can't seem to find a way to do this with <zipfileset /> targets.
Is there a way to do a 'dry-run' and obtain a list of the targets that will be included? Or is there a (simple) method of extracting the required information from the generated ZIP itself?
If you have already generated file (with checksum) you can just add it with help of another fileset.
The sample:
<target name="ziptest">
<zip destfile="${src}\output.zip">
<fileset dir="${src}">
<include name="dir1\*"/>
<include name="dir2\fileprefix*"/>
</fileset>
<fileset dir="${src}">
<!-- You have property with filename: file.name.checksum-->
<include name="${file.name.checksum}"/>
</fileset>
</zip>
</target>

need to check if filename contains the date.default property in ant script

Here is my script:
`
description="--> emails any file from a specified location">
<tstamp>
<format property="date.default" pattern="yyyy-MM-dd"
offset="-1" unit="day" />
</tstamp>
<echo message="${date.default}" />
<for param="file">
<path>
<fileset dir="${report.dir}">
<include name="**/*file*.doc" />
<contains text=" ${date.default}"/>
</fileset>
</path>
</for>`
It looks like you're trying to iterate over the set of files with names that match both the word 'file' (as you use this in the include element) and the value of '${date.default}'. You probably don't need to use a selector for that - the include directive is usually enough for file name matches. For example, you might use:
<include name="**/*file*${date.default}*.doc" />
The contains selector is for matching content of files, rather than the file names. If you have a complex filename-based matching rule, then you may need to make use of the filename selector in combination with includes, and possibly excludes. But 'filename' selectors are normally only needed when selection is based on filename plus some other criteria.

Resources