How exclude in fileset checking if property is set? - ant

I need to create a fileset but I need to exclude a folder if some property is set (project.name).
<fileset dir="${build.folder}">
<include name="**/*"/>
<exclude name="${project.name}/**/*"/>
</fileset>
How can I do it?

Assuming you are using a recent version of ANT (1.9.1+), try this:
<project name="tryit" xmlns:if="ant:if" xmlns:unless="ant:unless">
<target name="try">
<fileset id="my-fileset" dir="${build.folder}">
<include name="**/*"/>
<exclude if:set="project.name" name="${project.name}/**/*"/>
</fileset>
<echo message="My fileset is ${toString:my-fileset}" />
</target>
</project>

Related

Ant fileset matching only files but excluding all sub directories

How do I copy only files immediately under the directory and not its subdirectories? I don't know a priori the names of the files or the subdirectories. I've tried the following to no avail:
<include name="*"> # includes all files and subdirs
===
<include name="*">
<exclude name="*/**> # or "*/" or "**"
Any help would be appreciated.
UPDATE:
I ended up just adding a delete task to delete the copied subdirectories:
<delete includeemptydirs="true">
<fileset dir="${targetdir}">
<type type="dir"/>
</fileset>
</delete>
<?xml version="1.0" encoding="UTF-8"?>
<project default="copy-top-most-files-only" name="My Project">
<property name="to.dir" value="/path/to/dest/folder/" />
<property name="from.dir" value="/path/to/source/folder/" />
<target name="copy-top-most-files-only">
<copy todir="${to.dir}" includeEmptyDirs="false" >
<fileset dir="${from.dir}">
<exclude name="*/**/*" />
</fileset>
</copy>
</target>
</project>
One way to do this is to specify a <depth> selector, for example:
<copy todir="dest">
<fileset dir="src">
<depth max="0" />
</fileset>
</copy>
That will prevent subdirectories from being copied.
You can combine selectors with include/exclude rules if needed.

how to reuse the definition of a number of filesets?

I have a number of tasks in my build.xml that all utilize the same set of filesets. E.g. something like the following (I've retain the actual names of the tasks - related to the cobertura coverage tool - but the nature of the enveloping task is immaterial to this question).
<target name="coverage-report">
<cobertura:cobertura-report destdir="${coverage.xml.dir}" format="xml">
<fileset dir="${src.dir}">
<include name="**/*.java" />
</fileset>
<fileset dir="${componentFoo.dir}/src">
<include name="**/*.java" />
</fileset>
</cobertura:cobertura-report>
</target>
<target name="summary-coverage-report">
<cobertura:cobertura-report destdir="${coverage.summaryxml.dir}" format="summaryXml">
<fileset dir="${src.dir}">
<include name="**/*.java" />
</fileset>
<fileset dir="${componentFoo.dir}/src">
<include name="**/*.java" />
</fileset>
</cobertura:cobertura-report>
</target>
<target name="alternate-coverage-report">
<cobertura:cobertura-report destdir="${coverage.html.dir}">
<fileset dir="${src.dir}">
<include name="**/*.java"/>
</fileset>
<fileset dir="${componentFoo.dir}/src">
<include name="**/*.java" />
</fileset>
</cobertura:cobertura-report>
</target>
What I would like to do is to be able to define once this recurring set of filesets and reuse it. Now, there's a related SO question on how to use the same fileset in multiple places but that's not working here as I have a number of filesets, not just one. I also tried wrapping the filesets inside a macrodef and expanding the macrodef when needed but I get the message that the these tasks "don't support the nested [name of macrodef] element". So I guess macrodefs in Ant can only be used as high-level tasks and cannot be expanded in arbitrary places.
So is there a way to reuse a definition of a number of filesets in Ant?
This would be easy if the cobertura tasks accepted arbitrary resource collections instead of being hard-coded to just fileset - it may be worth submitting a feature request to this end. For example with a copy task:
<resources id="filesets">
<fileset dir="${src.dir}">
<include name="**/*.java" />
</fileset>
<fileset dir="${componentFoo.dir}/src">
<include name="**/*.java" />
</fileset>
</resources>
<copy todir="dest">
<resources refid="filesets"/>
</copy>
You can fall back to the purely XML-level and use an entity reference:
<!DOCTYPE project [
<!ENTITY cobFilesets '<fileset dir="${src.dir}">
<include name="**/*.java" />
</fileset>
<fileset dir="${componentFoo.dir}/src">
<include name="**/*.java" />
</fileset>'>
]>
<project ....>
<target name="coverage-report">
<cobertura:cobertura-report destdir="${coverage.xml.dir}" format="xml">
&cobFilesets;
</cobertura:cobertura-report>
</target>
</project>

Ant war and ear is not generating

I am new to this ant I wrote athe following build.xml file for generating war and ear. it is showing build successfull. but it not generating any war/ear file. I mentioned my script below. please help me what changes i have to do..
Thanks in advance....
<property name="src" value="src"/>
<property name="dst" value="web"/>
<property name="classes" value="WEB-INF/classes"/>
<property name="archiveName" value="medcardets"/>
<property name="archive" value="BuildArchive"/>
<fileset id="lib" dir="${dst}/WEB-INF/lib">
<include name="*.jar"/>
</fileset>
<fileset id="war.file" dir="/">
<include name="${archiveName}.war"/>
</fileset>
<fileset id="ear.file" dir="/">
<include name="${archiveName}.war"/>
</fileset>
<fileset id="lib.rules" dir="${dst}/WEB-INF/lib/rules">
<include name="*.jar"/>
</fileset>
<fileset id="lib.j2ee" dir="j2ee">
<include name="*.jar"/>
</fileset>
<target name="clear">
<delete dir="${dst}/${classes}"/>
<delete dir="${archive}"/>
</target>
<target name="build" depends="clear">
<mkdir dir="${dst}/${classes}"/>
<javac srcdir="${src}" destdir="${dst}/${classes}" debug="on" debuglevel="lines,vars,source">
<classpath>
<fileset refid="lib"/>
<fileset refid="lib.rules"/>
<fileset refid="lib.j2ee"/>
</classpath>
</javac>
<copy todir="${dst}/${classes}">
<fileset dir="${src}">
<exclude name="**/CVS"/>
<exclude name="**/*.java"/>
</fileset>
</copy>
</target>
Your question implies that you have written code that you expect to generate a WAR, but you have no instruction to do so. I see from your comment you are actually asking what the command should be.
Most important: I hope we are all new to things, after 35 years in the industry I learn something every day. Why did you ask the question rather than google? Learning to search is the most important skill. Google ant task WAR gives this task with an example:
<war destfile="myapp.war" webxml="src/metadata/myapp.xml">
<fileset dir="src/html/myapp"/>
<fileset dir="src/jsp/myapp"/>
<lib dir="thirdparty/libs">
<exclude name="jdbc1.jar"/>
</lib>
<classes dir="build/main"/>
<zipfileset dir="src/graphics/images/gifs"
prefix="images"/>
</war>
and a similar entry for EAR:
<ear destfile="${build.dir}/myapp.ear" appxml="${src.dir}/metadata/application.xml">
<fileset dir="${build.dir}" includes="*.jar,*.war"/>
</ear>

ant build.xml target to check for debug code

When debugging it's quite common for me to use things such as Zend_Debug and die() in the PHP to locate an issue. Occasionally I forget to take these out before committing my code. So I was wondering...
How do I write an ant build.xml target which checks all the files in my application for specific strings and fails if they have been found?
Basically, I'm after a reverse grep command which fails when it finds a string.
Any ideas?
Also, given my build.xml file looks like this (I've removed most of my targets to make it short), how do I make it work?
I don't know how ant works, so I'm after a 'drop-in' solution or good instructions.
<?xml version="1.0" encoding="UTF-8"?>
<project name="API" default="build" basedir=".">
<property name="source" value="application"/>
<target name="build" depends="prepare,lint,phpcpd,phpdox,phpunit,phpcb"/>
<target name="clean" description="Cleanup build artifacts">
<delete dir="${basedir}/build/api"/>
</target>
<target name="lint">
<apply executable="php" failonerror="true">
<arg value="-l" />
<fileset dir="${basedir}/${source}">
<include name="**/*.php" />
</fileset>
<fileset dir="${basedir}/tests">
<include name="**/*.php" />
</fileset>
</apply>
</target>
</project>
Within the lint target (after the apply element) add
<fileset id="die-files" dir="${basedir}/${source}">
<include name="**/*.php" />
<contains text="die()"/>
</fileset>
<fail message="The following files contain "die()": ${ant.refid:die-files}">
<condition>
<resourcecount when="greater" count="0" refid="die-files"/>
</condition>
</fail>
If you can use ant-contrib than:
<for param="file">
<path>
<fileset dir="/path/to/application/"/>
</path>
<sequential>
<if>
<contains string="#{file}" substring="bad elements"/>
<then>
<fail>warning! substring is present in directory</fail>
</then>
</if>
</sequential>
</for>

Ant: copy the same fileset to multiple places

I need an Ant script that will copy one folder to several other places. As a good obedient programmer, I want not to repeat myself. Is there any way of taking a fileset like this:
<copy todir="${target}/path/to/target/1">
<fileset dir="${src}">
<exclude name='**/*svn' />
</fileset>
</copy>
And storing the fileset in a variable so it can be re-used?
Declare an id attribute on the fileset and then reference it in each copy task.
For example:
<project name="foo">
<fileset id="myFileSet" dir="${src}">
<exclude name='**/*svn' />
</fileset>
...
<target name="copy1">
<copy todir="${target}/path/to/target/1">
<fileset refid="myFileSet"/>
</copy>
</target>
<target name="copy2">
<copy todir="${target}/path/to/target/2">
<fileset refid="myFileSet"/>
</copy>
</target>
</project>
Rich's answer is probably better for your specific problem, but the generic way of reusing code in Ant is a <macrodef>.
<macrodef name="copythings">
<attribute name="todir"/>
<sequential>
<copy todir="#{todir}">
<fileset dir="${src}">
<exclude name='**/*svn' />
</fileset>
</copy>
</sequential>
</macrodef>
<copythings todir="/path/to/target1"/>
<copythings todir="/path/to/target2"/>
Upvoted first answer already, but you can also use a mapper to copy to multiple destinations.

Resources