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).
Related
I'm fairly new to ant.
I'm currently working with the IBM MQ product.
As part of this product there are some ant executions that make use of their IBMs own defined Ant Tasks (eg below 'fte:filecopy')
<project xmlns:fte="antlib:com.ibm.wmqfte.ant.taskdefs" name="transfer" default="orchestrate_transfers">
<taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
...
<target name="copy">
<fte:filecopy src="X#Y" dst="X#Y" outcome="await" jobname="test_job" rcproperty="result">
<fte:filespec srcfilespec="/from/here" dstfile="/to/here" overwrite="true" recurse="false"/>
<fte:metadata>
<fte:entry name="mykey" value="myvalue"/>
</fte:metadata>
</fte:filecopy>
</target>
...
I need to execute this and tasks like it, but with a bit of controlling logic that assigns a variable number of metadata entries. I could potentially do this with javascript.
Now, I know I can execute/perform tasks from javascript (eg, The below tasks are equivalent, but one is implemented natively and the other via javascript) but project.createTask("filecopy") creates a null object.
<project name="demo">
<target name="test_task">
<echo message="Hello World"/>
</target>
<target name="test_script">
<script language="script">
var echo = project.createTask("echo")
echo.setMessage("Hello World")
echo.perform()
</script>
</target>
</project>
Does anyone know how you would normally call a custom task from inside the script?
I need to calculate time difference using Ant.
Basically it has 2 variables. One is assigned the current time, and the other one has a different time. I need to get the time difference using Ant. Something like below. If anyone have code please reply.
variable a = current time;
variable b = different time
echo (a - b) ;
Here is a much simpler solution:
<script language="javascript">
project.setProperty('startTime', new Date().getTime());
</script>
...
<script language="javascript">
project.setProperty('elapsedTime', new Date().getTime() - startTime)
</script>
<echo>Elapsed time: ${elapsedTime} ms</echo>
Alternative to #LeFunes answer (and uses the tstamp task)
<tstamp prefix="task.start">
<format property="millis" pattern="SSS"/>
</tstamp>
<tstamp prefix="task">
<format property="start" pattern="E, dd MMM YYYY hh:mm:ss"/>
</tstamp>
<time-consuming-task/>
<tstamp prefix="task.stop">
<format property="millis" pattern="SSS"/>
</tstamp>
<tstamp prefix="task">
<format property="stop" pattern="E, dd MMM YYYY hh:mm:ss"/>
</tstamp>
<script language="javascript">
project.setProperty("task.diff",
Math.abs(
(Date.parse(project.getProperty("task.stop")) +
+project.getProperty("task.stop.millis")) -
(Date.parse(project.getProperty("task.start")) +
+project.getProperty("task.start.millis"))))
</script>
<echo>
task completed in ${task.diff} ms
</echo>
NOTE:
this doesn't consider milliseconds
updated to consider the milliseconds
<?xml version="1.0" encoding="UTF-8"?>
<project name="TEST ANT" default="test" basedir="..">
<target name="test" description="">
<script language="javascript"> <![CDATA[
var ts1 = new Date();
project.setProperty("current.time.1", ts1.toLocaleString());
project.setProperty("current.time.1.mill", ts1.getTime());
]]></script>
<echo>Timestamp 1: ${current.time.1} [${current.time.1.mill}]</echo>
<sleep milliseconds="1300"></sleep>
<script language="javascript"> <![CDATA[
var ts2 = new Date();
project.setProperty("current.time.2", ts2.toLocaleString());
project.setProperty("current.time.2.mill", ts2.getTime());
]]></script>
<echo>Timestamp 2: ${current.time.2} [${current.time.2.mill}]</echo>
<script language="javascript"> <![CDATA[
project.setProperty("res", project.getProperty("current.time.2.mill")-project.getProperty("current.time.1.mill"));
]]></script>
<echo>Diff: ${res}</echo>
</target>
</project>
If you don't want to use JavaScript, you can use the Math task provided by the Ant-Contrib utilities.
The Ant-Contrib are fairly old, and I don't know if anyone is still maintaining them, but they're very popular to use in Ant build files since they add some very useful tasks.
I recommend including the ant-contrib-1.0b3.jar into the project itself. When other people use your project, they'll also have the Ant-Contrib jar. I put ant-lib/ac/ant-contrib-1.0b3.jar under your project's home directory. I use ant-lib for all of my optional jars:
<project name="my.project"
...
xmlns:ac="antlib:net.sf.antcontrib">
...
<taskdef uri="antlib:net.sf.antcontrib"
resource="net/sf/antcontrib/antlib.xml">
<classpath>
<fileset dir="${basedir}/antlib/ac"/>
</classpath>
</taskdef>
....
Now, you can use your math task like this:
<ac:math result="time.diff"
operation="-"
operand1="${diff.time}"
operand2="${initial.time}"/>
The ac: is an XML namespace that was declared in your <project/> entity, and was connected to your tasks via the uri parameter in the <taskdef/> entity. This allows you to have multiple optional Ant tasks that may have tasks with duplicate names. This is a good idea in case you use multiple optional task libraries that have the same task names.
I'm trying to read a property after updating it using propertyfile task. Something like
<property file="test.properties" />
<echo>before :: ${modules}</echo>
<propertyfile file="test.properties" >
<entry key="modules" type="string" operation="+" value="foo" />
</propertyfile>
<property file="${status.path}/test.properties" />
<echo>after :: ${modules}</echo>.
It doesn't seem to load the second time. But the property file is updated.
You can invoke a new ant runtime with the antcall task that ignores the properties of your main target runtime - just make sure to include inheritAll="false"
<target name="main">
<property file="test.properties"/>
<echo>before :: ${modules}</echo>
<propertyfile file="test.properties">
<entry key="modules" type="string" operation="+" value="foo" />
</propertyfile>
<antcall target="second-runtime" inheritAll="false"/>
</target>
<target name="second-runtime">
<property file="${status.path}/test.properties" />
<echo>after :: ${modules}</echo>
</target>
antcall refrence
As sudocode already mentioned, in Core Ant properties are immutable - for good reasons.
With the unset task from Antelope Ant Tasks you're able to unset all properties set in a file with a one liner :
<unset file="test.properties"/>
afterwards
<propertyfile file="test.properties" >
<entry key="modules" type="string" operation="+" value="foo" />
</propertyfile>
will work.
Hint : the task works only for normal properties, not for xmlproperties.
But there's a simple workararound, simply use <echoproperties prefix="..." destfile="foo.properties"/> and afterwards <unset file="foo.properties"/>
If you don't want to use Antelope for that specific task only, you may write a macrodef or own task with similar features.
For this case, when whole properties file is loaded twice, I suggest using different prefixes for the first and second load. First load with aprefix attribute equal to first. Access the properties with this prefix, that is property foo will be accessible as first.foo. Then save the properties file and load again, but this time without a prefix. You will get modified properties in suitable place.
Without using the prefix the second load will do nothing, as ant prevents properties from overriding. Others pointed that already.
Ant properties are immutable - once set, they are fixed. So reloading the properties file will not refresh the value of a property already set.
this macro allow you to change the property value after fixed one
<macrodef name="set" >
<attribute name="name"/>
<attribute name="value"/>
<sequential>
<script language="javascript">
<![CDATA[
project.setProperty("#{name}", "#{value}");
]]>
</script>
</sequential>
</macrodef>
you can create a new properties file and save the property in the new file.
Provide the reference of the file in the next line.
Done :)
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>
I would like to create a macro as such:
<macrodef name="testing">
<element name="test" implicit="yes"/>
<sequential>
<test/>
</sequential>
</macrodef>
And then use it:
<testing>
<echo message="hello world"/>
</testing>
However, I would like to specify a default for the implicit element... something like:
<macrodef name="testing">
<element name="test" implicit="yes">
<echo message="hello world"/>
</element>
<sequential>
<test/>
</sequential>
</macrodef>
So I can then use it as such:
<testing/>
Except where I want to change the default element.
Is this possible without defining a task via a Java class? So far, I don't see any documentation that indicates how to do it, if so.
Update
I ended up resolving my particular issue by using refid for filesets (which is what I actually was trying to pull into an element). Using the refid, it was simple to just use a macrodef attribute, which CAN have a default value.
Another alternative would be to create a new base macro which uses the element, and then I could have kept my existing macro as using that one... but still, there is no real default mechanism for an element (which would be nice).
So, Simon gets the answer since he's correct! Thanks!
This is not possible based on the nested element element documentation for the macrodef task.
There is a Bugzilla issue open for exactly the functionality you describe, unfortunately it has been open since 2004.
if you define your macrodef as:
<macrodef name="testing">
<element name="additional" optional="true"/>
<sequential>
<echo message="hello"/>
<additional/>
</sequential>
</macrodef>
the following invocation:
<target name="testing-call">
<mylib:testing/>
<mylib:testing>
<additional>
<echo message="world!"/>
</additional>
</mylib:testing>
</target>
will output:
[echo] hello
[echo] hello
[echo] world!