Accessing project prefix inside the included ant file - ant

Is it possible to access "as" prefix inside the included ant file
(i.e. to access "as" attribute value specified in include task)
file including.xml:
<project name="myproject">
<include file="included.xml" as="nested" />
</project>
file included.xml:
<project>
<echo message="I am included into ${ant.project.name} as ${SomePropertyIAskAbout}" />
</project>
Desired output: "I am included into myproject as nested"

<include> executes an included buildfile as if were in the including buildfile. Having both files reference a custom property will do the trick.
including.xml
<project name="myproject">
<property name="including-as-attribute" value="nested" />
<include file="included.xml" as="${including-as-attribute}" />
</project>
included.xml
<project>
<fail unless="including-as-attribute"/>
<echo message="I am included into ${ant.project.name} as ${including-as-attribute}" />
</project>
Output of ant -f including.xml
[echo] I am included into myproject as nested

Related

If there is no properties file declared, what does the $ do in an Ant build file?

Essentially, I am wondering how ant knows that $ means to pull from the properties file.. what if there was no properties file named?
Take example this build file
<?xml version="1.0" encoding="UTF-8"?>
<project name="Hello World Project" default="info">
<property file="build.properties"/>
<fileset dir="${build.dir}" >
<include name="**/*.java"/>
</fileset>
<target name="info">
<echo>${src}</echo>
</target>
</project>
I know that the $ sign is referencing a property in the build.properties file, however what if there is no properties file, what does the $ sign do in a regular Ant compilation?
Ant leaves references to non-existent properties unchanged. For example, the following Ant script...
<project name="ant-echo-missing-property" default="run">
<target name="run">
<property file="non-existent-file.properties"/>
<echo>${missing-property}</echo>
</target>
</project>
...outputs...
run:
[echo] ${missing-property}

ant warning : could not load antlib.xml

I have the antcontrib.jar in my lib folder of Ant. I set my ant home as "C/Prog Files/apache-ant".
But still when I run my build.xml, i get the warning "could not load antlib.xml and antcontrib.prop".
Because of this, I am not able to do any "regex" operations.
I properly loaded the antcontrib.jar in the lib folder of the ant.
Where I am wrong here?
Provide resource and classpath in your taskdef correctly as follows
<typedef resource="net/sf/antcontrib/antlib.xml" classpath="<path to ant-contrib.jar>"/>
Here's an example of an Ant script that uses Ant-Contrib's <propertyregex> task:
build.xml
<project name="ant-propregex-simple" default="run">
<taskdef resource="net/sf/antcontrib/antlib.xml" />
<target name="run">
<property name="line.to.test" value="First Second" />
<property name="the.regex" value="^([^ ]*) ([^ ]*)$" />
<propertyregex
input="${line.to.test}"
regexp="${the.regex}"
select="\2"
property="the.match"
/>
<echo>${the.match}</echo>
</target>
</project>
The key is the <taskdef ...> line.
Output
run:
[echo] Second
BUILD SUCCESSFUL

How to exclude base directory from phing/ant FileSet

I have a phing build target that I want to run on each directory directly under my project base. I'm using a foreach task with a fileset to run the target on each directory. The problem I'm having is that the base directory is included, with a filename of "".
Here's an example of the directory structure:
One
Two
build.xml
Here's a simple build file to test:
<?xml version="1.0" encoding="UTF-8"?>
<project name="Test" default="test">
<target name="test">
<foreach param="filename" absparam="absfilename" target="echo-file">
<fileset dir="${project.basedir}">
<include name="*" />
<exclude name="*.*" />
</fileset>
</foreach>
</target>
<target name="echo-file">
<echo message="filename: ${filename}" />
<echo message="absfilename: ${absfilename}" />
</target>
</project>
And here's the results of the build (note the first entry with empty filename):
Buildfile: /Users/dmertl/test/build.xml
Test > test:
[foreach] Calling Buildfile '/Users/dmertl/test/build.xml' with target 'echo-file'
Test > echo-file:
[echo] filename:
[echo] absfilename: /Users/dmertl/test/
[foreach] Calling Buildfile '/Users/dmertl/test/build.xml' with target 'echo-file'
Test > echo-file:
[echo] filename: One
[echo] absfilename: /Users/dmertl/test/One
[foreach] Calling Buildfile '/Users/dmertl/test/build.xml' with target 'echo-file'
Test > echo-file:
[echo] filename: Two
[echo] absfilename: /Users/dmertl/test/Two
Not sure how I didn't figure this out the first time around, but here's the solution:
<foreach param="filename" absparam="absfilename" target="echo-file">
<fileset dir="${project.basedir}">
<include name="*" />
<exclude name="/" />
<exclude name="*.*" />
</fileset>
</foreach>
Excluding "/" in the fileset removes the root directory.

Change baseDir attribute while using import tag

Let me first provide the background of the problem I'm facing.
I have a directory structure as below.
c:\myDirectory
c:\myDirectory\Project1
c:\myDirectory\Scripts
Under the c:\myDirectory\Scripts there is a script that download the source code (from svn) and creates the c:\myDirectory\Project1 directory.
I have another ant scripts ( c:\myDirectory\Scripts**compile-source.xml ) that compiles the Project1
from an ant script build.xml that is downloaded to c:\myDirectory\Project1
Snippet for c:\myDirectory\Scripts\compile-source.xml
<project name="compile" default="buildAll" basedir=".">
<property file=".\build.properties">
</property>
.......
<import file="${project.home.path}/${project.name}/build.xml"/>
<target name="buildAll">
<antcall target="jar-pack"/>
</target>
</project>
Snippet for c:\myDirectory\Project1\build.xml.
<project name="CommonFeatures" default="jar-pack" basedir=".">
<description>
A build file for the Common Features project
</description>
....
</project>
Note that the basedir for the project is set as "." for both the above ant scripts.
When I execute the script c:\myDirectory\Scripts\compile-source.xml from the c:\myDirectory\Scripts directory the target "jar-pack" present in the c:\myDirectory\Project1\build.xml gets executed.
However, the problem is that basedir attribude in build.xml ( basedir="." ) is the current working directory and in this case its c:\myDirectory\Scripts. Hence the script build.xml errors out since the basedir for build.xml is expected to be c:\myDirectory\Project1. The build.xml script would have worked, if basedir="." were set to "c:\myDirectory\Project1", but unfortunately build.xml file comes from the source code that is downloaded and I'm unable to edit.
So here's my question, Is it possible to do any of the following.
Override the value of the attribude basedir="." in build.xml when the is done in c:\myDirectory\Scripts\compile-source.xml ?
Is it possible to change the basedir in build.xml by any other mechanism so that the script c:\myDirectory\Project1\build.xml is executed under directory c:\myDirectory\Project1 ?
Any other way to resolve this issue?
Any help from Ant experts to overcome this issue is highly appreciated.
You can update basedir using subant task. Check this answer
Create the following build.xml file (assuming it is in Z:/any/folder):
<?xml version="1.0" encoding="UTF-8"?>
<project name="project">
<target name="mytarget">
<subant target="debug">
<property name="basedir" value="X:/any/dir/with/project"/>
<fileset dir="Y:/any/folder/with" includes="build.xml"/>
</subant>
</target>
</project>
The you can execute ant mytarget from Z:/any/folder
You can specifically reference the location of your build file, which is described in this stack overflow thread. This would allow you to get and use the directory your build file resides in as a reference point.
For your case the usage of the subant or ant tasks may be better suited, but nevertheless...
You can (but you should know/consider the side-effects!) extend ant with the common ant-contrib task definitions and use the var task which is able to override properties. Make sure to use the latest version (> 1.0b3).
<!-- adjust to your path and include it somewhere at the beginning of your project file -->
<taskdef resource="net/sf/antcontrib/antlib.xml" classpath="lib/ant-contrib-1.0b3.jar" />
<!-- works e.g. for basedir = /foo/bar to update it to /foo/bar/.. ~ /foo -->
<var name="basedir" value="${basedir}/.." />
update: but one has to be careful, because this does not change . (current working directory) (so <property name="x" location="tmp" /> would be relative to . and not to basedir anymore ; update: setting basedir outside of ant or via <project basedir= also sets . to basedir!). Here is some test target proving the effect on both:
<target name="tst.dummy.basedir-override">
<!-- example output:
tst.dummy.basedir-override:
[echo] basedir before: basedir=D:\tst, '.'=D:\tst\.
[echo] updating it via 'var' to '..'
[echo] basedir now: basedir=D:\tst/.., '.'=D:\tst\.
-->
<property name="cur" location="." /> <!-- makes the relative path absolute -->
<echo message="basedir before: basedir=${basedir}, '.'=${cur}" />
<echo message="updating it via 'var' to '..'" />
<var name="basedir" value="${basedir}/.." />
<property name="cur2" location="." /> <!-- makes the relative path absolute -->
<echo message="basedir now: basedir=${basedir}, '.'=${cur2}" />
</target>

How to turn directories to .jar files with Ant

How to turn a list of directories into a list of .jar files ?
It seems that using Copy Task and Mappers is the right way to do this but I did not find any nested element creating a jar file from a directory.
Of course, the list of directories would be computed and not hard coded in the ant script.
For instance, a foo directory contains bar1, bar2 and bar3 directories. The script would create bar1.jar from the bar1 dir, bar2.jar from bar2 dir and bar3.jar from bar3 dir
The script would create a bar4.jar from a newly added bar4 directory without any change in the script (no hardcoded list).
Thanks ahead for your help
You can use the subant task to do this. For example:
<project name="jars" default="jar" basedir=".">
<property name="dir.build" value="${basedir}/build"/>
<property name="dir.root" value="${basedir}/foo"/>
<target name="init">
<tstamp/>
<mkdir dir="${dir.build}"/>
</target>
<target name="jar" depends="init">
<!-- ${ant.file} is the name of the current build file -->
<subant genericantfile="${ant.file}" target="do-jar">
<!-- Pass the needed properties to the subant call. You could also use
the inheritall attribute on the subant element above to pass all
properties. -->
<propertyset>
<propertyref name="dir.build"/>
</propertyset>
<!-- subant will call the "do-jar" target for every directory in the
${dir.root} directory, making the subdirectory the basedir. -->
<dirset dir="${dir.root}" includes="*"/>
</subant>
</target>
<target name="do-jar">
<!-- Get the basename of the basedir (bar1, bar2, etc.) -->
<basename file="${basedir}" property="jarname"/>
<jar jarfile="${dir.build}/${jarname}.jar" basedir="${basedir}"/>
</target>
</project>
You could use the appropriate Jar task, along with the foreach ant-contrib extension task.
A sample:
<foreach list="${hmProjectsList}" delimiter="/,"
target="cvsCheckOut" param="hmProjectDir" inheritall="true" />

Resources