How to get substring of a string in ANT property - ant

I have a requirement to get a substring out of a string in to ant property.
Example string:
1=tibunit-1.4.2.projlib\=
I want to extract the part before .projlib\= and after the first =.
The result should be:
tibunit-1.4.2
Any ideas?

Use script task with builtin javascript engine (JDK >= 1.6.0_06) and something like :
if you need substring 'tibunit-1.4.2.projlib\' :
<project>
<property name="foo" value="1=tibunit-1.4.2.projlib\="/>
<script language="javascript">
// simple echo
println(project.getProperty('foo').split('=')[1]);
// create property for later use
project.setProperty('foobar', project.getProperty('foo').split('=')[1]);
</script>
<echo>$${foobar} => ${foobar}</echo>
</project>
output :
[script] tibunit-1.4.2.projlib\
[echo] ${foobar} => tibunit-1.4.2.projlib\
if you need substring 'tibunit-1.4.2' :
<project>
<property name="foo" value="1=tibunit-1.4.2.projlib\="/>
<script language="javascript">
s = project.getProperty('foo').split('=')[1];
// simple echo
println(s.substring(0, s.lastIndexOf(".")));
// create property for later use
project.setProperty('foobar', s.substring(0, s.lastIndexOf(".")));
</script>
<echo>$${foobar} => ${foobar}</echo>
</project>
output:
[script] tibunit-1.4.2
[echo] ${foobar} => tibunit-1.4.2
For reuse put that stuff into a macrodef.

Use the ant-contrib task PropertyRegex :
<propertyregex property="tibunit.version"
input="1=tibunit-1.4.2.projlib\="
regexp="1=(tibnunit-[0-9]+.[0-9]+.[0-9]+).+"
select="\1"
casesensitive="false" />

Related

How to convert a dirset value into a string

I am writing a javascript ant task using scriptdef:
<scriptdef name="xxx" language="javascript">
<element name="dirset" type="dirset"/>
<![CDATA[
importClass(java.io.File);
var dirsets = elements.get("dirset");
var t = dirsets.get(0);
self.log(t.indexOf("T"));
]]>
</scriptdef>
When I run this script, it complains that it can't find the indexOf function. Any ideas?
You can use the pathconvert ANT task:
<pathconvert property="dirs.str" pathsep=" " refid="dirset.id"/>

Ant: Convert class name to file path

How do I convert Java class names into file paths using Ant tasks?
For example, given a property containing foo.bar.Duck I'd like to get out foo/bar/Duck.class.
I tried (and failed) to implement this in terms of <pathconvert> and <regexpmapper>.
Here's a possible way to do this:
<property name="class.name" value="foo.bar.Duck"/>
<loadresource property="file.name">
<string value="${class.name}" />
<filterchain>
<replaceregex pattern="\." replace="/" flags="g" />
<replaceregex pattern="$" replace=".class" />
</filterchain>
</loadresource>
This puts the desired foo/bar/Duck.class into the file.name property.
Here's another way, using Ant resources and an unpackagemapper, which is designed for this purpose. The opposite package mapper is also available.
<property name="class.name" value="foo.bar.Duck"/>
<resources id="file.name">
<mappedresources>
<string value="${class.name}" />
<unpackagemapper from="*" to="*.class" />
</mappedresources>
</resources>
You use the resource value by means of the property helper syntax ${toString:...}, e.g.:
<echo message="File: ${toString:file.name}" />
Yields
[echo] File: foo/bar/Duck.class
I feel using ant script-javascript for this is much simpler
<property name="class.name" value="foo.bar.duck" />
<script language="javascript">
var className = project.getProperty("class.name");
println("before: " + className);
var filePath= className.replace("\\", "/");
println("File Path: "+filePath);
project.setProperty("filePath", filePath);
</script>
<echo message="${filePath}" />
note: that naming your variable same as argument e.g var wsPath may give error, it gave to me!
courtesy: https://stackoverflow.com/a/16099717/4979331

How can I compare two properties with numeric values?

How can I find out which of two numeric properties is the greatest?
Here's how to check wheather two are equal:
<condition property="isEqual">
<equals arg1="1" arg2="2"/>
</condition>
The Ant script task allows you to implement a task in a scripting language. If you have JDK 1.6 installed, Ant can execute JavaScript without needing any additional dependent libraries. For example, this JavaScript reads an Ant property value and then sets another Ant property depending on a condition:
<property name="version" value="2"/>
<target name="init">
<script language="javascript"><![CDATA[
var version = parseInt(project.getProperty('version'));
project.setProperty('isGreater', version > 1);
]]></script>
<echo message="${isGreater}"/>
</target>
Unfortunately, Ant's built in condition task does not have an IsGreaterThan element. However, you could use the IsGreaterThan condition available in the Ant-Contrib project. Another option would be to roll out your own task for greater than comparison. I'd prefer the former, because it's easier and faster, and you also get a host of other useful tasks from Ant-Contrib.
If you don't want to (or cannot) use the Ant-Contrib libraries, you can define a compare task using javascript:
<!-- returns the same results as Java's compareTo() method: -->
<!-- -1 if arg1 < arg2, 0 if arg1 = arg2, 1 if arg1 > arg2 -->
<scriptdef language="javascript" name="compare">
<attribute name="arg1" />
<attribute name="arg2" />
<attribute name="result" />
<![CDATA[
var val1 = parseInt(attributes.get("arg1"));
var val2 = parseInt(attributes.get("arg2"));
var result = (val1 > val2 ? 1 : (val1 < val2 ? -1 : 0));
project.setProperty(attributes.get("result"), result);
]]>
</scriptdef>
You can use it like this:
<property name="myproperty" value="20" />
...
<local name="compareResult" />
<compare arg1="${myproperty}" arg2="19" result="compareResult" />
<fail message="myproperty (${myproperty}) is greater than 19!">
<condition>
<equals arg1="${compareResult}" arg2="1" />
</condition>
</fail>

Ant macrodef: Is there a way to get the contents of an element parameter?

I'm trying to debug a macrodef in Ant. I cannot seem to find a way to display the contents of a parameter sent as an element.
<project name='debug.macrodef'>
<macrodef name='def.to.debug'>
<attribute name='attr' />
<element name='elem' />
<sequential>
<echo>Sure, the attribute is easy to debug: #{attr}</echo>
<echo>The element works only in restricted cases: <elem /> </echo>
<!-- This works only if <elem /> doesn't contain anything but a
textnode, if there were any elements in there echo would
complain it doesn't understand them. -->
</sequential>
</macrodef>
<target name='works'>
<def.to.debug attr='contents of attribute'>
<elem>contents of elem</elem>
</def.to.debug>
</target>
<target name='does.not.work'>
<def.to.debug attr='contents of attribute'>
<elem><sub.elem>contents of sub.elem</sub.elem></elem>
</def.to.debug>
</target>
</project>
Example run:
$ ant works
...
works:
[echo] Sure, the attribute is easy to debug: contents of attribute
[echo] The element works only in restricted cases: contents of elem
...
$ ant does.not.work
...
does.not.work:
[echo] Sure, the attribute is easy to debug: contents of attribute
BUILD FAILED
.../build.xml:21: The following error occurred while executing this line:
.../build.xml:7: echo doesn't support the nested "sub.elem" element.
...
So I guess I need either a way to get the contents of the <elem /> into a property somehow (some extended macrodef implementation might have that), or I need a sort of <element-echo><elem /></element-echo> that could print out whatever XML tree you put inside. Does anyone know of an implementation of either of these? Any third, unanticipated way of getting the data out is of course also welcome.
How about the echoxml task?
In your example build file replacing the line
<echo>The element works only in restricted cases: <elem /> </echo>
with
<echoxml><elem /></echoxml>
results in
$ ant does.not.work
...
does.not.work:
[echo] Sure, the attribute is easy to debug: contents of attribute
<?xml version="1.0" encoding="UTF-8"?>
<sub.elem>contents of sub.elem</sub.elem>
Perhaps the XML declaration is not wanted though. You might use the echoxml file attribute to put the output to a temporary file, then read that file and remove the declaration, or reformat the information as you see fit.
edit
On reflection, you can probably get close to what you describe, for example this sequential body of your macrodef
<sequential>
<echo>Sure, the attribute is easy to debug: #{attr}</echo>
<echoxml file="macro_elem.xml"><elem /></echoxml>
<loadfile property="elem" srcFile="macro_elem.xml">
<filterchain>
<LineContainsRegexp negate="yes">
<regexp pattern=".xml version=.1.0. encoding=.UTF-8..." />
</LineContainsRegexp>
</filterchain>
</loadfile>
<echo message="${elem}" />
</sequential>
gives
$ ant does.not.work
...
does.not.work:
[echo] Sure, the attribute is easy to debug: contents of attribute
[echo] <sub.elem>contents of sub.elem</sub.elem>

How can I get the value of the current target ant?

How can I get the value of the current target ant?
Does it exist a special variable something called TARGET?
Based on the issue you have to patch ant or used javascript:
<target name="test">
<script language="javascript">
project.setNewProperty("current_target", self.getOwningTarget());
</script>
<echo>${current_target}</echo>
</target>
In ant 1.8.2 you can use ${ant.project.invoked-targets}
However, looking at the commit logs
http://svn.apache.org/viewvc?view=revision&revision=663061
I'm guessing its been available since 1.7.1
My answer, using antcontrib
<macrodef name="showtargetname">
<attribute name="property"/>
<sequential>
<!-- make temporary variable -->
<propertycopy name="__tempvar__" from="#{property}"/>
<!-- Using Javascript functions to convert the string -->
<script language="javascript"> <![CDATA[
currValue = [project-name].getThreadTask(java.lang.Thread.currentThread()).getTask().getOwningTarget().getName();
[project-name].setProperty("__tempvar__", currValue);
]]>
</script>
<!-- copy result -->
<var name="#{property}" value="${__tempvar__}"/>
<!-- remove temp var -->
<var name="__tempvar__" unset="true"/>
</sequential>
</macrodef>
Usage:
<showtargetname property="mycurrenttarget"/>
I think you can't, unless you spend some time coding your own custom tasks (http://ant.apache.org/manual/tutorial-writing-tasks.html)
The built-in properties you can display are: basedir, ant.file, ant.version, ant.project.name, ant.java.version
If you run ant using the -projecthelp arg:
ant -projecthelp
you will get a listing of the main targets specified in the build.xml (or other build file as declared on the commandline).

Resources