exception when using if statment in ant script - ant

I am trying to compare the value of a properties variable with a string as following
<if>
<equals "${mat.projectName}"="seal">
<then>
When done so, I'm getting following message.
Element type "equals" must be followed by either attribute specifications,">" or
"/>"
I'm using eclipse framework to do this.

Read the manual first:
http://ant.apache.org/manual/Tasks/conditions.html
clearly, from the manual we know for equals:
arg1 First value to test
arg2 Second value to test
So it should be
<if>
<equals arg1="${mat.projectName}" arg2="seal" />
<then>
...
I recommend you to read guides about XML first, and then, Ant's manual.
Update:
<if> task is not provided by Ant; it is provided by Ant-Contrib. So you need <taskdef>.
For example, I have ant-contrib.jar put in my project's lib directory (${basedir}/lib), so I can write the following:
<taskdef resource="net/sf/antcontrib/antcontrib.properties">
<classpath>
<pathelement location="lib/ant-contrib.jar"/>
</classpath>
</taskdef>
For more, you can check taskdef's manual page, as well as Ant-contrib's webpage:
http://ant.apache.org/manual/Tasks/taskdef.html
http://ant-contrib.sourceforge.net/

Exactly what you're error message says...
Element type "equals" must be followed by either attribute specifications,">" or "/>"
You want this:
<if>
<equals arg1="${mat.projectName}" arg2="seal"/>
<then>
<yadda, yadda, yadda/>
</then>
</if>
This is XML, so you need parameters with values. Take a look at the equals condition on this page. It takes two parameters.
Notice the format of the <if>. The condition ends with a />. The <then> is a sub-entity of the <if>, and the if clause is a sub-entity of the <then> clause. Notice that you basically indent twice.
If you're doing a not equals condition, it would look like this:
<if>
<not>
<equals arg1="${mat.projectName}" arg2="seal"/>
</not>
<then>
<yadda, yadda, yadda/>
</then>
</if>

Related

How to check a property or variable is empty and set a value then test for that value

We are using Ant 1.8. I am not an Ant developer but I have to pretend sometimes.
A new property, ${noReportDSUpgrade}, is intended to be "true" or "false".
By default it is empty (not exist?) which is "false" for our purposes.
If this property is empty it should be set to "false".
A command line using this parameter should set it to true.
1) How do I set ${noReportDSUpgrade} to false if empty and true if supplied?
2) For the target, how to execute only if false?
I have tried several suggestions I've found but can't get it to work.
At the beginning of the script:
<target name="init">
<antcall target="setnoReportDSUpgradeProperty"/>
Further down:
<target name="setnoReportDSUpgradeProperty">
<condition>
<or>
<equals arg1="${noReportDSUpgrade}" arg2=""/>
<not>
<isset property="false"/>
</not>
</or>
</condition>
<echo message="noReportDSUpgrade set to ${noReportDSUpgrade}"/>
</target>
Here's how to set a default property value in Ant:
<property name="noReportDSUpgrade" value="false" />
That's it! Properties are immutable in Ant, so if you set a value via command line or earlier in the script, subsequent <property> tasks won't change it. This won't account for the property being set to a blank value (i.e. ""), but as a general good practice, try to avoid setting properties to blank.
Even though I don't think you need a <condition> task for your goals here, I feel I should clear some things up in your example. The <condition> task doesn't affect the <target> that it's nested in; it simply sets a property, specified by the property attribute. Additionally, the isset condition's property attribute is used to point to the name of the property you're checking, not the value.
<condition property="noReportDSUpgrade">
<or>
<equals arg1="${noReportDSUpgrade}" arg2=""/>
<not>
<isset property="noReportDSUpgrade" />
</not>
</or>
</condition>
But like I said above, don't use that unless you really need to check for a blank value for some reason. Just use <property>.
As for running targets conditionally, the <target> block supports if and unless attributes that control whether or not the entire thing runs. This can be a bit confusing because there are two modes in which this operates.
<target name="myTarget" if="myCondition">
<echo message="Running myTarget" />
</target>
The above target will run if myCondition is set (not if its value is true). So if it evaluates to "true", "false", "asdf", or just blank, the target will still run. Conversely, if we used the unless attribute, it wouldn't run if myCondition is set to anything. This is usually convenient for when you're using the <condition> task to set your properties (since <condition> does not set a value if the boolean evaluates to false).
<target name="myTarget" if="${myCondition}">
<echo message="Running myTarget" />
</target>
Notice the ${} around myCondition. When you expand the property like this, Ant will only run the target if the property's value is "true", "on", or "yes".
Lastly, you typically don't need to make a separate target just for setting conditions. In relatively simple scripts, you can just use the implicite root target (i.e. put the tasks at root level outside of all other targets).
In short, here's the simplest way to write your script.
<project name="myProject">
<property name="noReportDSUpgrade" value="false" />
<target name="myTarget" if="${noReportDSUpgrade}">
<echo message="Running myTarget" />
</target>
</project>
If you really need an initialization target (note the depends attribute):
<project name="myProject">
<target name="init">
<property name="noReportDSUpgrade" value="false" />
</target>
<target name="myTarget" if="${noReportDSUpgrade}" depends="init">
<echo message="Running myTarget" />
</target>
</project>

Removing absent entries from an ant path

I've got a situation where we're generating an Ant <path> which may contain some directories which don't actually exist. Unfortunately this is being fed into bnd, which blows up if anything in the path is missing.
So what I want is a way to filter a <path> to keep only those path elements which actually exist.
Is there a simple way to say this in Ant, or do I have to write a task?
I believe I have found an answer:
<path id="bnd.cp.existing">
<restrict>
<path refid="bnd.cp"/>
<exists/>
</restrict>
</path>
<!-- To see when it happens, add the following: -->
<echo message="bnd classpath is: ${toString:bnd.cp.existing}"/>
<iff>
<not>
<equals arg1="${toString:bnd.cp.existing}"
arg2="${toString:bnd.cp}"/>
</not>
<then>
<echo message=" trimmed from: ${toString:bnd.cp}"/>
</then>
</iff>
The restrict operation can take a path-like structure as input and return a version of it with the requested filtering applied -- in this case keep only the path elements which actually exist. This is then re-bound to a new ID for use by the <bnd> operation.

Ant conditionally set attribute

Is it possible to have a dynamically set attribute in Ant?
At the moment all of our wars have the same name: "mywar.war". I'd like to have wars built with JDK6 to be "mywar-1.6.war" and those built with JDK7 to still just be "mywar.war".
Currently:
<war warfile="${dist.dir}/mywar.war">
..
<war />
I can include the Java version like this:
<war warfile="${dist.dir}/mywar-${ant.java.version}.war">
But what I'd like to have is the logic to do something like this:
if (${ant.java.version} == "1.6") {
war.name="mywar-${ant.java.version}";
} else {
war.name="mywar";
}
<war warfile="${dist.dir}/${war.name}.war">
Is there a correct way to go about that?
The way to set properties conditionally is to use the condition task:
<condition property="war.suffix" value="-1.6" else="">
<equals arg1="${ant.java.version}" arg2="1.6"/>
</condition>
<war warfile="${dist.dir}/mywar${war.suffix}.war">
The trick here is that the else="" means that war.suffix will be an empty string on any version other than 1.6.
Yes you can use some thing like that but it's not available in ant as such. You will have to download ant-contrib.jar
And then you have some thing like this
<if>
<equals arg1="${ant.java.version}" arg2="1.6" />
<then>
war.name="mywar-${ant.java.version}";
</then>
<else>
war.name="mywar";
</else>
</if>
See this link for ant contrib

In Ant, how can I test if a property ends with a given value?

In Ant, how can I test if a property ends with a given value?
For example
<property name="destdir"
value="D:\FeiLong Soft\Essential\Development\repository\org\springframework\spring-beans" />
how can I test if ${destdir} ends with "spring-beans"?
additional:
In my ant-contrib-1.0b3.jar, without 'endswith' task~~
You can test if ${destdir} ends with "spring-beans" like this (assuming you have ant-contrib, and are using Ant 1.7 or later).
<property name="destdir" value="something\spring-beans" />
<condition property="destDirHasBeans">
<matches pattern=".*spring-beans$" string="${destdir}" />
</condition>
<if>
<equals arg1="destDirHasBeans" arg2="true" />
<then>
$destdir ends with spring-beans ...
</then>
<else> ...
</else>
</if>
The '$' in the regex pattern ".*spring-beans$" is an anchor to match at the end of the string.
As Matteo, Ant-Contrib contains a lot of nice stuff, and I use it heavily.
However, in this case can simply use the <basename> task:
<basename property="basedir.name" file="${destdir}"/>
<condition property="ends.with.spring-beans">
<equals arg1="spring-beans" arg2="${basedir.name}"/>
<condition>
The property ${ends.with.spring-beans} will contain true if ${destdir} ends with string-beans and false otherwise. You could use it in the if or unless parameter of the <target> task.
You can use the EndWith condition from Ant-Contrib
<endswith string="${destdir}" with="spring-beans"/>
For example
<if>
<endswith string="${destdir}" with="spring-beans"/>
<then>
<!-- do something -->
</then>
</if>
Edit
<endswith> is part of the Ant-Contrib package that has to be installed and enabled with
<taskdef resource="net/sf/antcontrib/antlib.xml"/>
The JavaScript power can be used for string manipulation in the ANT:
<script language="javascript"> <![CDATA[
// getting the value for property sshexec.outputproperty1
str = project.getProperty("sshexec.outputproperty1");
// get the tail , after the separator ":"
str = str.substring(str.indexOf(":")+1,str.length() ).trim();
// store the result in a new property
project.setProperty("res",str);
]]> </script>
<echo message="Responce ${res}" />

antcall based on a condition

This is what I am trying to achieve:
if a property is set then call antcall target. is this doable? can someone tell me how?
<condition>
<isset property="some.property">
<antcall target="do.something">
</isset>
</condition>
Something like this should work:
<if>
<isset property="some.property"/>
<then>
<antcall target="do.something"/>
</then>
</if>
If then conditions require ant-contrib, but so does just about anything useful in ant.
I know I'm really late to this but here is another way to do this if you are using an of ant-contrib where if doesn't support a nested antcall element (I am using antcontrib 1.02b which doesn't).
<target name="TaskUnderRightCondition" if="some.property">
...
</target>
You can further expand this to check to see if some.property should be set just before this target is called by using depends becuase depends is executed before the if attribute is evaluated. Thus you could have this:
<target name="TestSomeValue">
<condition property="some.property">
<equals arg1="${someval}" arg2="${someOtherVal}" />
</condition>
</target>
<target name="TaskUnderRightCondition" if="some.property" depends="TestSomeValue">
...
</target>
In this case TestSomeValue is called and, if someval == someOtherVal then some.property is set and finally, TaskUnderRightCondition will be executed. If someval != someOtherVal then TaskUnderRightCondition will be skipped over.
You can learn more about conditions via the documentation.
Consider also you can invoke groovy for these purposes:
<use-groovy/>
<groovy>
if (Boolean.valueOf(properties["some.property"])) {
ant.project.executeTarget("do.something")
}
</groovy>

Resources