Copy is not working in Ant Script - ant

I have one variable defined in my properties file:
require.extensions = html, htm
and I am using that variable as below:
<for list="${require.extensions}" param="letter">
<sequential>
<copy todir="${dir.publish.html}">
<fileset dir="${project.dir}">
<include name="**/*.#{letter}"/>
</fileset>
</copy>
</sequential>
</for>
I want to copy all the file with extensions html and htm to ${project.dir} dir to ${dir.publish.html} dir
But currently it only copies html files and not htm files. Why So? As i am getting html and htm values in #{letter} out side but i can't use echo inside so i am not able to check the value of #{letter}. Is there any problem in my code ?
<copy todir="${dir.publish.html}">
<fileset dir="${project.dir}">
<include name="**/*.html"/>
<include name="**/*.htm"/>
</fileset>
</copy>
If i do this it will work. But want to make .html | .htm should be dynamically get inserted.

Given the documentation of the for task, the default delimiter usedto split the string into tokens is ,. This means that your list will contain two tokens: html and <space>htm. So your task copies all the files which end with .<space>htm.

Related

No overwrite on Ant UNZIP

I want to unzip a file, but if some file exists, this mustn´t be replaced.
I tried this:
<unzip src="compress.zip" dest="dirTo" overwrite="false">
<patternset>
<include name="dirFrom/**"/>
</patternset>
"dirFrom", is the name from the directory IN the compress file, what I want to extract. I use "overwrite" to false, but it doesn´t work, and it ovewrites.
I have a directory, and this has different subdirectories. I want one of those subdirectories, with it´s files and sub-subdirectories.
I found how to do it.
1st, I extract everything to auxiliar directory.
2nd, I make a loop, to compare file by file, if that file exists.
3rd, If the file doesn´t exists, I copy it.
<unzip src="compressFile.zip" dest="dirAux">
<patternset>
<include name="mySubDir/**"/>
</patternset>
</unzip>
<fileset id="fileset1" dir="dirAux/mySubDir" />
<property name="newContentMySubDir" refid="fileset1"/>
<for param="nameFile" list="${newContentMySubDir}" delimiter=";">
<sequential>
<if>
<not><available file="${finalDir}/mySubDir/#{nameFile}" type="file"/></not>
<then>
<copy tofile="${finalDir}/mySubDir/#{nameFile}" file="dirAux/mySubDir/#{nameFile}"/>
</then>
</if>
</sequential>
</for>
Setting overwrite to false will only prevent to overwrite destination file if it is newer than source file. For more complex filtering, you have to use copy task with a zipfilset as it is explain in ant documentation (see unzip task -- in section Related tasks). For exemple, following code should not extract files from a zip file if they already exist in the destination directory (respecting source directories layout):
<copy todir="${target.dir}">
<zipfileset src="${zip.file}">
<patternset>
<include name="**/*.*"/>
</patternset>
<present targetdir="${target.dir}" present="srconly"/>
</zipfileset>
</copy>

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.

What's the difference between a nested path and fileset?

I have been googling for the "Differences between fileset and path" article for some time, but have found nothing useful.
For example, what is the difference between the following (say, there is a someDir directory, which contains .jar files and has no subdirectories):
<path id="somePathId">
<pathelement path="someDir"/>
</path>
<path id="someId">
<path refid="somePathId" />
</path>
and
<path id="someId">
<fileset dir="someDir">
<include name="*.*">
</fileset>
</path>
?
They are used in different situations.
fileset is used to specify a group of files. You can use selectors and patternsets to get only the files you want.
classpath is used to specify classpath references. classpath can be specified with a single jar (location="..."), a ; or : separated list of jars (path="...") or with nested resource collections (like fileset).
Also if you want to debug them, it is different:
<echo message="Build-path: ${toString:build-path}" />
vs
<property name="debug.classpath" refid="classpath"/>
<echo message="Classpath = ${debug.classpath}"/>
As for your scripts,
<path id="somePathId">
<pathelement location="someDir"/>
</path>
I did not test it but according to the documentation path= expects a ; or : separated list of jars. This is not the same as your second example.
The major difference between a <path> and a <fileset> is that in <fileset> you can specify if you want to include or exclude certain type of files (Basically, its a group of files within a path... not necessary all the files), for eg:
<path id="someId">
<fileset dir="someDir">
<include name="*.java">
<include name="*.properties">
</fileset>
</path>

A zip file cannot include itself - Ant build error

I have error at the first line of the following code while building with Ant builder,
<war warfile="${wartemp.dir}/${name}.war" basedir="${wartemp.dir}" webxml="${wartemp.dir}/WEB-INF/web.xml">
<include name="*"/>
<include name="scripts/**"/>
<include name="styles/**"/>
<include name="images/**"/>
<include name="WEB-INF/*.*"/>
<include name="WEB-INF/lib/**"/>
<include name="WEB-INF/views/**"/>
<include name="WEB-INF/classes/**"/>
<include name="WEB-INF/jsp/**"/>
<include name="WEB-INF/resources/**"/>
<include name="WEB-INF/spring/**"/>
<include name="WEB-INF/messages/**"/>
<include name="WEB-INF/layouts/**"/>
<exclude name="WEB-INF/web.xml"/>
<exclude name="**/.*"/>
</war>
The error message is:
"... /WEB-INF/build.xml:67: A zip file cannot include itself"
line 67 is the first line of the snippet posted above.
I am beginner to Spring framework. I am using Spring version 3 with springsource toolsuite. How to fix this?
thanks.
Your basedir is the same dir as where you are sending the outputted war file. This is not a problem in itself, the problem is you are including * as input which will include the output file.
To fix this you could either exclude the output file from the included files, e.g.:
<exclude name="${name}.war"/>
or you could write the war file to a different directory structure than you are reading from, e.g.:
<mkdir dir="${war.output.dir}" />
<war warfile="${war.output.dir}/${name}.war" ...>
I guess I found another cause of the "A zip file cannot include itself" problems in any "zip-alike" Ant tasks (zip, jar ...):
Remember, setting the "basedir" attribute is already the first set of files to include! You need to explicitly exclude the zip file being created at this level (with "excludes" attribute. Or, starting with Ant 1.7, with nested "excludes" element).
The "fileset" nested element is another "set" for the zip task. You should ensure that the zip "itself" will be excluded from the set also with another explicit exclude. And so on...

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