I have an target of the following form
<target name="runTool" depends="build">
<java className="ToolMain" fork="true" clonevm="true" failonerror="true">
<arg......>
<jvmarg.....>
....
</target>
I want to add an additional target for the debug path, which has all other args same as this one but an additional arg to listen on the debug port.
<target name="runTool-debug" depends="build">
...same program ....
......and same args......
<jvmarg value="-agentlib:jdwp=transport=dt_socket,address=5005,server=y,suspend=n"/>
</target>
What is the best way to achieve this without duplicating the entire target?
Define a property named debug.flag for instance and use it to add the additional arguments when it is set to true:
<target name="runTool" depends="build">
<condition property="debug.jvmargs"
value="-agentlib:jdwp=transport=dt_socket,address=5005,server=y,suspend=n"
else="">
<equals arg1="${debug.flag}" arg2="true" />
</condition>
<java className="ToolMain" fork="true" clonevm="true" failonerror="true">
<arg......>
<jvmarg.....>
<jvmarg value="${debug.jvmargs}" />
....
</target>
In the condition task, when debug.flag is true, debug.jvmargs is set to -agentlib:jdwp=transport=dt_socket,address=5005,server=y,suspend=n, else it is empty.
To set the property to true, you can run ant -Ddebug.flag=true ....
Related
I have the following Ant targets in my project.xml:
<target name="to.run.under.conditions">
</target>
<target name="deploy1">
<antcall target="deploy2"/>
</target>
<target name="deploy2">
<antcall target="to.run.under.conditions"/>
</target>
<target name="another.target">
<antcall target="deploy1"/>
</target>
My intent is to be able to exclude the target to.run.under.conditions when running another.target. I am not very familiar with ANT and I am struggling to understand how to approach the issue. I have tried to employ unless="${target.running}" in and set the property as true in the condition task inside the target name ="target.running"
Can you help with this?
Thank you for your help,
I.
----EDIT UPDATED SOLUTION----
This is my current attempt (I am using ANT 1.8.2):
<target name="to.run.under.conditions" if="${target.running}">
</target>
<target name="another.target">
<property name="target.running" value="false"/>
</target>
If I am not mistaken, since the property is set to false inside another.target, then to.run.under.conditions should not be run (I might be wrong, though). Does it make sense? Any comment is much appreciated!
Try this:
<target name="build-module-A" if="module-A-present"/>
<target name="build-own-fake-module-A" unless="module-A-present"/>
In the first example, if the module-A-present property is set (to any value, e.g. false), the target will be run. In the second example, if the module-A-present property is set (again, to any value), the target will not be run.
Please see Any Targets for more information.
I have ended up with this solution that seems to be work as expected:
<target name="deploy2">
<if>
<equals arg1="${target.running}" arg2="true" />
<then>
<echo message="the target will not run" />
</then>
<else>
<echo message="the target will run" />
<antcall target="to.run.under.conditions"/>
</else>
</if>
</target>
<target name="to.run.under.conditions">
</target>
<target name="another.target">
<property name="target.running" value="true"/>
</target>
Hope this helps,
I.
It is possible to execute an Ant target conditionally by specifying an if or unless clause. As far as I can see this clause accepts only one property. How can I check for two properties?
This is an example:
<project default="test">
<property name="a" value="true"/>
<property name="b" value="true"/>
<target name="test-a" if="a">
<echo>a</echo>
</target>
<target name="test-b" if="b">
<echo>b</echo>
</target>
<target name="test-ab" if="a,b">
<echo>a and b</echo>
</target>
<target name="test" depends="test-a,test-b,test-ab"/>
</project>
If I run it, the test-ab target generates no output:
$ ant -f target-if.xml
Buildfile: target-if.xml
test-a:
[echo] a
test-b:
[echo] b
test-ab:
test:
BUILD SUCCESSFUL
Total time: 0 seconds
How to specify an and expression for the two properties?
Unfortunately, no. From the ant Targets manual:
Only one propertyname can be specified in the if/unless clause. If you
want to check multiple conditions, you can use a dependend target for
computing the result for the check:
<target name="myTarget" depends="myTarget.check" if="myTarget.run">
<echo>Files foo.txt and bar.txt are present.</echo>
</target>
<target name="myTarget.check">
<condition property="myTarget.run">
<and>
<available file="foo.txt"/>
<available file="bar.txt"/>
</and>
</condition>
</target>
This is my example with the use of the condition element:
<project default="test">
<property name="a" value="true"/>
<property name="b" value="true"/>
<target name="test-a" if="a">
<echo>a</echo>
</target>
<target name="test-b" if="b">
<echo>b</echo>
</target>
<condition property="a-and-b">
<and>
<equals arg1="${a}" arg2="true"/>
<equals arg1="${b}" arg2="true"/>
</and>
</condition>
<target name="test-ab" if="a-and-b">
<echo>a and b</echo>
</target>
<target name="test" depends="test-a,test-b,test-ab"/>
</project>
The above ant script implements if dir_is_empty then git-clone else git-fetch using Ant-1.7.1 core statements:
<target name="update" depends="git.clone, git.fetch" />
<target name="check.dir">
<fileset dir="${dir}" id="fileset"/>
<pathconvert refid="fileset" property="dir.contains-files" setonempty="false"/>
</target>
<target name="git.clone" depends="check.dir" unless="dir.contains-files">
<exec executable="git">
<arg value="clone"/>
<arg value="${repo}"/>
<arg value="${dir}"/>
</exec>
</target>
<target name="git.fetch" depends="check.dir" if="dir.contains-files" >
<exec executable="git" dir="${dir}">
<arg value="fetch"/>
</exec>
</target>
(see my other post)
But how to implement a target enabled by two conditions?
if dir_does_not_exist or dir_is_empty then git-clone else git-fetch
my current attempt:
<target name="git.clone"
depends="chk.exist, chk.empty"
unless="!dir.exist || dir.noempty" >
[...]
</target>
<target name="chk.exist">
<condition property="dir.exist">
<available file="${dir}/.git" type="dir"/>
</condition>
</target>
[...]
I would prefer Ant-1.7.1 core statements. But I am open about other possibilities as Ant contrib, or embedded script... Feel free to post your ideas...
(See also question Execute ANT task just if a condition is met)
Even when bound to Ant 1.7.1 you may combine your 3 chk targets into one, see the condition part in the snippet.
Since Ant 1.9.1 (better use Ant 1.9.3 because of bugs in Ant 1.9.1 see this answer for details) it is possible to add if and unless attributes on all tasks and nested elements, so no extra target needed, f.e. :
<project xmlns:if="ant:if" xmlns:unless="ant:unless">
<condition property="cloned" else="false">
<and>
<available file="${dir}/.git" type="dir" />
<resourcecount when="gt" count="0">
<fileset dir="${dir}/.git" />
</resourcecount>
</and>
</condition>
<exec executable="git" unless:true="${cloned}">
<arg value="clone" />
<arg value="${repo}" />
<arg value="${dir}" />
</exec>
<exec executable="git" dir="${dir}" if:true="${cloned}">
<arg value="fetch" />
</exec>
</project>
From the ant documentation on targets:
Only one propertyname can be specified in the if/unless clause.
If you want to check multiple conditions, you can use a dependend target for computing the result for the check:
<target name="myTarget" depends="myTarget.check" if="myTarget.run">
<echo>Files foo.txt and bar.txt are present.</echo>
</target>
<target name="myTarget.check">
<condition property="myTarget.run">
<and>
<available file="foo.txt"/>
<available file="bar.txt"/>
</and>
</condition>
</target>
Moreover, there were some discussions on dev#ant.apache.org and user#ant.apache.org mailing-lists:
Using multiple properties in the 'if' and 'unless' conditions (June 2006)
Support mutliple if and unless (August 2008)
Multiple conditions satisfying in an ant target (October 2008)
For example, the following target combines two properties (dir.exist and dir.noempty) to create another one (cloned) using operators <and> and <istrue> (many other operators are documented as <or>, <xor>, <not>, <isfalse>, <equals>, <length>).
<target name="chk" depends="chk.exist, chk.empty" >
<condition property="cloned">
<and>
<istrue value="dir.exist" />
<istrue value="dir.noempty" />
</and>
</condition>
</target>
The above property "cloned" is used by targets git.clone and git.fetch as follows:
<target name="update" depends="git.clone, git.fetch" />
<target name="git.clone" depends="chk" unless="cloned" >
<exec executable="git" >
<arg value="clone" />
<arg value="${repo}" />
<arg value="${dir}" />
</exec>
</target>
<target name="git.fetch" depends="chk" if="cloned" >
<exec executable="git" dir="${dir}">
<arg value="fetch"/>
</exec>
</target>
<target name="chk.exist" >
<condition property="dir.exist" >
<available file="${dir}" type="dir" />
</condition>
</target>
<target name="chk.empty" >
<fileset dir="${dir}" id="fileset" />
<pathconvert refid="fileset" property="dir.noempty" setonempty="false" />
</target>
I have some modules and a main runnable project. I have common build file, and
build.common.xml
<target name="build" >
<path id="libraries.classpath">
<fileset dir="${lib.dir}" includes="*.jar" />
</path>
<javac srcdir="${src.dir}" destdir="${build.dir}" includeantruntime="false" source="1.6">
<classpath refid="libraries.classpath" />
<classpath refid="modules.classpath" />
</javac>
</target>
..and every module declares its own dependencies in their build.xml:
<path id="modules.classpath">
<pathelement path="../ModuleA/${build.dir}" />
...
</path>
The problem is if there is no internal dependency I get the following exception:
"Reference modules.classpath not found."
What is the solution for that? How could I declare an optional classpath element?
Note: If anybody want to suggest to create jars out of my modules, please justify this. I'm going to have 5-10 rapidly changing modules, and I don't want to do unnecesary steps in the build process.
Update: I extracted the build into two different targets and created a condition for them, but did not help (it echoes the 'false' and builds with module-dependencies):
<target name="build">
<condition property="modules.classpath.set" else="false">
<isset property="modules.classpath"/>
</condition>
<echo message="modules.classpath is set: ${modules.classpath.set} " />
<antcall target="build-with-modules" />
<antcall target="build-without-modules" />
</target>
<target name="build-with-modules" if="modules.classpath.set">
<echo message="Building with module-dependencies" />
<javac srcdir="${src.dir}" destdir="${build.dir}" includeantruntime="false" source="1.6">
<classpath refid="libraries.classpath" />
<classpath refid="modules.classpath" />
</javac>
</target>
<target name="build-without-modules" unless="modules.classpath.set">
<echo message="Building with no dependent modules" />
<javac srcdir="${src.dir}" destdir="${build.dir}" includeantruntime="false" source="1.6">
<classpath refid="libraries.classpath" />
</javac>
</target>
Condition isreference:
Test whether a given reference has been defined in this project and - optionally - is of an expected type.
So, try
<condition property="modules.classpath.set" else="false">
<isreference refid="modules.classpath"/>
</condition>
Also on that page, there is a link to a page that describes custom conditions. If none of the provided conditions meets your requirement, then just write one.
Update:
The logic of if and unless in <target> is to check if the property has been set -- for if, the target runs when the property has been set; for unless, the target runs when the property has NOT been set -- not the value of the property.
I have never checked the code of the condition isreference, but I think maybe the else="false" should be removed.
If removing that part still doesn't help, then you may need to use some embedded groovy or beanshell script, or write your own condition.
I m trying to do this with Ant:
<property name="test" value="123"/>
<target name="helloworld" depends="${test}"/>
But I'm getting error "Target ${test} does not exist in this project."
So I m guessing I can do this?
You can use the AntCall Task to call a Task inside another Task.
<project>
<target name="asdf">
<property name="prop" value="qwer" />
<antcall target="${prop}" />
</target>
<target name="qwer">
<echo message="in qwer" />
</target>
</project>
To make one depend on the other, you can set a parameter in the dependent task and check it in your calling task.
Rather than depends, you can check a property using the if attribute. See the manual for more details.
For example:
<target name="helloworld" if="test"/>
Note this only checks if the property is set (you can use unless to check if it is unset).
An alternative, more complex but powerful, approach is to use a nested condition on a depended target:
<target name="helloworld" depends="myTarget.check" if="myTarget.run">
...
</target>
<target name="myTarget.check">
<condition property="test">
<and>
<available file="foo.txt"/>
<available file="bar.txt"/>
</and>
</condition>