I am using ant 1.7, getting following error:
build.xml:55: fileset doesn't support the "erroronmissingdir" attribute
what is the alternative attribute for erroronmissingdir( it is in 1.8) in 1.7
The fileset erroronmissingdir attribute is available since Ant 1.7.1. You must be using an earlier release of 1.7.
The attribute is used to tell the build to silently ignore filesets for which the base dir does not exist at execution time:
<copy todir="tmp">
<fileset dir="foo" erroronmissingdir="false">
<include name="**/*"/>
</fileset>
</copy>
If you do not specify erroronmissingdir="false" (or cannot, because your version of Ant does not support it), then the default result is build failure if the dir foo does not exist.
If you need your build to succeed whether or not the dir exists, and you cannot use the erroronmissingdir attribute, you have some options.
For example, you could specify the base dir of the fileset to be a known-to-exist parent of your target dir, something like this:
<copy todir="tmp">
<fileset dir=".">
<include name="foo/**/*"/>
</fileset>
</copy>
(Note in this case, the copy will now create dir foo in the todir of the copy. You could strip that using a glob mapper.)
Another alternative would be to execute your conditionally available fileset operations in targets, guarded by a condition, e.g.
<available property="foo.available" file="foo"/>
<target name="test" if="foo.available">
<copy todir="tmp">
<fileset dir="foo">
<include name="**/*"/>
</fileset>
</copy>
</target>
Output with ant -v will show:
[available] Unable to find foo to set property foo.available
test: Skipped because property 'foo.available' not set.
BUILD SUCCESSFUL Total time: 0 seconds
Related
I have an Ant task that should copy some files and rename them on the fly. For example:
Copy "file1-1.0.2" and rename it to "file1", copy "file-2.5.1" and rename it to "file2".
To do this I'm trying to use copy + fileset + chainedmapper + globmapper:
<copy todir="${version.dir}/WEB-INF/lib/" failonerror="false">
<fileset dir="${version.dir}/WEB-INF/lib/" casesensitive="yes">
<include name="file1-*.jar"/>
<include name="file2-*."/>
<include name="taxclient-v2-v2014-server-*.jar"/>
</fileset>
<chainedmapper>
<globmapper from="file1-*.jar" to="file1.jar"/>
<globmapper from="file2-*.jar" to="file2.jar"/>
</chainedmapper>
</copy>
When the Ant script runs, I get the following error:
The type doesn't support the nested "chainedmapper" element
Why does this error occur?
I was using an old version of ant (1.6). The chainedmapper type is only available since Ant 1.7.0.
Ant Mapper Type
I have the following fileset in my Apache Ant build file (BuildFilesetXML.xml):
<fileset id="XMLFileset" dir="mydir/myxml">
<include name="**/1.xml"/>
<include name="**/2.xml"/>
</fileset>
I want to create dynamically in a different build file (BuildFilesetLog.xml) (do not know the contents of "XMLFileset" in my 2nd build file) a new fileset named "LOGFileset" that will have the same contents of "XMLFileset" but with names renamed to .log. So, in runtime it will have the same structure as the following fileset:
<fileset id="LOGFileset">
<include name="**/1.log"/>
<include name="**/2.log"/>
</fileset>
Can this be done in Ant?
Thanks
No, but some tasks support mappers. For an example see the following answer:
Change directory of FileList when referencing it
I have an ant task that executes some command on a list of files.
I would like, on consecutive builds, to avoid from re-running the command on files that have passed the command with success and haven't changed.
For example: (here the command is xmllint)
<target name="xmllint-files">
<apply executable="xmllint">
<srcfile/>
<fileset dir="." includes="*.xml">
<modified/>
</fileset>
</apply>
</target>
The problem is that even the files where xmlint fails are considered as modified and therefore xmllint will not be re-run on them on consecutive builds. Obviously, this is not the desired behavior.
Two remarks:
I am looking for a general solution and not only a solution for xmllint.
I want to solve the problem totally inside ant without creating
external scripts.
This code uses the Groovy ANT task to do the following:
Implement a custom groovy selector, selecting the XML files to be processed based on a MD5 checksum check.
Invoke xmllint on each file and store it's checksum upon successful completion (This prevents re-execution of xmllint unless the file's contents are changed.
Example:
<project name="demo" default="xmllint">
<!--
======================
Groovy task dependency
======================
-->
<path id="build.path">
<pathelement location="jars/groovy-all-1.8.6.jar"/>
</path>
<taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy" classpathref="build.path"/>
<!--
==============================================
Select files to be processed
MD5 checksums located in "checksums" directory
==============================================
-->
<target name="select-files">
<fileset id="unprocessedfiles" dir=".">
<include name="*.xml"/>
<exclude name="build.xml"/>
<scriptselector language="groovy" classpathref="build.path">
def ant = new AntBuilder()
ant.checksum(file:filename, toDir:"checksums", verifyProperty:"isMD5ok")
self.selected = (ant.project.properties.isMD5ok == "false") ? true : false
</scriptselector>
</fileset>
</target>
<!--
=============================================================
Process each file
Checksum is saved upon command success, prevents reprocessing
=============================================================
-->
<target name="xmllint" depends="select-files">
<groovy>
project.references.unprocessedfiles.each { file ->
ant.exec(executable:"xmllint", resultproperty:"cmdExit") {
arg(value:file)
}
if (properties.cmdExit == "0") {
ant.checksum(file:file.toString(), toDir:"checksums")
}
}
</groovy>
</target>
</project>
Note:
This complex requirement cannot be implemented using the original apply ANT task. One call to xmllint command might succeed whereas another might fail.
A subdirectory called "checksums" is created to store the MD5 checksum files.
The groovy jar can be downloaded from Maven Central
Original answer
Use the ANT modified selector
<project name="demo" default="xmllint">
<target name="xmllint">
<apply executable="xmllint">
<srcfile/>
<fileset dir="." includes="*.xml">
<modified/>
</fileset>
</apply>
</target>
</project>
A property file called "cache.properties" will be created in the build directory. It records file digests, used determine if the file has been changed since the last build run.
I need to write an ant task to selectively delete files.
In a directory, I have the following jars:
acme.jar
acme-201105251330.jar
I want to delete acme.jar because acme-*.jar exists.
Here's what I've tried:
<target name="-check-use-file">
<available property="file.exists">
<filepath> <fileset dir=".">
<include name="./test-*.jar"/> </fileset>
</filepath>
</available>
</target>
<target name="use-file" depends="-check-use-file" if="file.exists">
<!-- do something requiring that file... -->
</target>
Thanks
Have a look at If/Unless Attributes, examples given there seem to be exactly what you are looking for.
I am still very new to ant and, although I know coldfusion, I don't know very much about java conventions, but I know that ant is built using java conventions. That being said I am working on an ant process to copy a project to a temp folder, change some code in the project, and then push the temp directory up to an FTP. I am trying to exclude all of my git, eclipse, and ant files from the copy so that my testing platform doesn't get cluttered. I setup a target to do the copy, but it seems that Ant not only is ignoring my excludes (which I am sure I wrote wrong), but it is only copying top level directories and files. No recursive copy. My current target is:
<target name="moveToTemp" depends="init">
<delete dir="./.ant/temp" />
<mkdir dir="./.ant/temp" />
<copy todir="./.ant/temp">
<fileset dir=".">
<include name="*" />
<exclude name=".*/**" />
<exclude name=".*" />
<exclude name="build.xml" />
<exclude name="settings.xml" />
<exclude name="WEB-INF/**" />
</fileset>
<filterset>
<filter token="set(environment='design')" value="set(environment='testing')" />
</filterset>
</copy>
</target>
I know that I am not doing my excludes right, but I don't know what I am doing wrong with them. I see double asterisks (**) used all the time in Ant but I can't figure out
By default an Ant fileset will (recursively) include all files under the specified directory, equivalent to:
<include name="**/*" />
That's the implicit include. If you supply an include, it overrides the implicit one.
Your include
<include name="*" />
Says 'match any file in the fileset directory', but that excludes traversal of subdirectories, hence your issue. Only files and the top-level directories are being copied.
See Patterns in the Ant docs for directory-based tasks: ** matches any directory tree (zero or more directories).
For your case you should be able to simply remove the 'include', so that the implicit 'include all' applies.
Suggest you also investigate the defaultexcludes task, which lets you set up this sort of thing once for the whole project.
Responding to the title of the question. You can include copy of empty directories as follows. (includeemptydirs attribute)
Example:
<copy includeemptydirs="true" todir="${directory}${file.separator}sentinel_files">
<fileset dir="${basedir}${file.separator}sentinel_files"/>
</copy>
Use the documentation provided in:
https://ant.apache.org/manual/Tasks/copy.html