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.
Related
During a build process using Ant, I want to update the last modified date of a generated file. I am concatenating (using concat task) several files to generate this file, and I want to set the modified date of this file to the date of the most recently modified of the source files.
I don't see any option in the touch task to use several files as the source for the date.
Here's an example solution:
<scriptdef name="filedate" language="javascript">
<attribute name="file"/>
<attribute name="property"/>
<![CDATA[
var file_name = attributes.get( "file" );
var property_to_set = attributes.get( "property" );
var file = new java.io.File( file_name );
var file_date = file.lastModified();
project.setProperty( property_to_set, file_date );
]]>
</scriptdef>
<last id="last.dir">
<sort>
<fileset dir="folder" includes="*" />
<date />
</sort>
</last>
<filedate file="${ant.refid:last.dir}" property="file.ts" />
<touch file="concat.file" millis="${file.ts}" />
The scriptdef is derived from this answer by David W. and simplified as we don't need to format the date-time, we can just use the "epoch milliseconds" that Java File lastModified() provides and the Ant touch task expects.
I've been looking all over the Internet, but couldn't find an answer anywhere. I have an MQFTE job coded in ANT script and I'm having difficulty with a process that moves files if a file doesn't have today's date. What I would like to do is a conditional stop, something like a return true value in a middle of the execution so the job is not going to go through the further routine and just end if the file is identified as to be skipped.
Is that possible in ANT? Or does it have to go through every <target> in the script?
The Ant fail task may be used to conditionally stop an Ant script. The example below initializes the property TODAY to the current date and then uses a fileset with a nested <date> element to only select files modified prior to today's date. The pathconvert task then sets the property files-not-empty only if there is at least one file in the fileset modified prior to today's date. The fail task is then used to stop the Ant script if there are no files to copy.
<target name="copy-if-not-modified-today">
<property name="copy-from.dir" value="${basedir}" />
<property name="copy-to.dir" value="${basedir}/build/copied_files" />
<mkdir dir="${copy-to.dir}" />
<tstamp>
<format property="TODAY" pattern="MM/dd/yyyy" />
</tstamp>
<fileset id="files" dir="${copy-from.dir}" includes="*">
<date datetime="${TODAY} 12:00 AM" when="before"/>
</fileset>
<pathconvert property="files-not-empty" setonempty="false" refid="files" />
<!--
Stop the Ant script if there are no files to copy that were modified prior
to today's date.
-->
<fail unless="files-not-empty" />
<copy todir="${copy-to.dir}" preservelastmodified="true">
<fileset refid="files" />
</copy>
</target>
Maybe Ant-Contrib Tasks can help you. To perform tasks based on conditions, the "If-then-else" is a possible solution - "Ant if"
I need to retrieve some values from an HTML file. I need to use Ant so I can use these values in other parts of my script.
Can this even be achieved in Ant?
As stated in the other answers you can't do this in "pure" XML. You need to embed a programming language. My personal favourite is Groovy, it's integration with ANT is excellent.
Here's a sample which retrieves the logo URL, from the groovy homepage:
parse:
print:
[echo]
[echo] Logo URL: http://groovy.codehaus.org/images/groovy-logo-medium.png
[echo]
build.xml
Build uses the ivy plug-in to retrieve all 3rd party dependencies.
<project name="demo" default="print" xmlns:ivy="antlib:org.apache.ivy.ant">
<target name="resolve">
<ivy:resolve/>
<ivy:cachepath pathid="build.path" conf="build"/>
</target>
<target name="parse" depends="resolve">
<taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy" classpathref="build.path"/>
<groovy>
import org.htmlcleaner.*
def address = 'http://groovy.codehaus.org/'
// Clean any messy HTML
def cleaner = new HtmlCleaner()
def node = cleaner.clean(address.toURL())
// Convert from HTML to XML
def props = cleaner.getProperties()
def serializer = new SimpleXmlSerializer(props)
def xml = serializer.getXmlAsString(node)
// Parse the XML into a document we can work with
def page = new XmlSlurper(false,false).parseText(xml)
// Retrieve the logo URL
properties["logo"] = page.body.div[0].div[1].div[0].div[0].div[0].img.#src
</groovy>
</target>
<target name="print" depends="parse">
<echo>
Logo URL: ${logo}
</echo>
</target>
</project>
The parsing logic is pure groovy programming. I love the way you can easily walk the page's DOM tree:
// Retrieve the logo URL
properties["logo"] = page.body.div[0].div[1].div[0].div[0].div[0].img.#src
ivy.xml
Ivy is similar to Maven. It manages your dependencies on 3rd party software. Here it's being used to pull down groovy and the HTMLCleaner library the groovy logic is using:
<ivy-module version="2.0">
<info organisation="org.myspotontheweb" module="demo"/>
<configurations defaultconfmapping="build->default">
<conf name="build" description="ANT tasks"/>
</configurations>
<dependencies>
<dependency org="org.codehaus.groovy" name="groovy-all" rev="1.8.2"/>
<dependency org="net.sourceforge.htmlcleaner" name="htmlcleaner" rev="2.2"/>
</dependencies>
</ivy-module>
How to install ivy
Ivy is a standard ANT plugin. Download it's jar and place it in one of the following directories:
$HOME/.ant/lib
$ANT_HOME/lib
I don't know why the ANT project doesn't ship with ivy.
Yes this is very possible.
Note that in order to use this solution you will need to set your JAVA_HOME variable to JRE 1.6 or later.
<project name="extractElement" default="test">
<!--Extract element from html file-->
<scriptdef name="findelement" language="javascript">
<attribute name="tag" />
<attribute name="file" />
<attribute name="property" />
<![CDATA[
var tag = attributes.get("tag");
var file = attributes.get("file");
var regex = "<" + tag + "[^>]*>(.*?)</" + tag + ">";
var patt = new RegExp(regex,"g");
project.setProperty(attributes.get("property"), patt.exec(file));
]]>
</scriptdef>
<!--Only available target...-->
<target name="test">
<!--Load html file into property-->
<loadfile srcFile="D:\Tools\CruiseControl\Build\artifacts\RECO\20110831100942\RECO_merged_report.html" property="html.file"/>
<!--Find element with specific tag and save it to property element-->
<findelement tag="title" file="${html.file}" property="element"/>
<echo message="File : ${html.file}"/>
<echo message="Title : ${element}"/>
</target>
</project>
Output : [echo] Title : <title>Test Report</title>,Test Report
As I don't know what exactly variables you were looking for this particular solution will find all elements that you specify in the tag attribute. Of course you could modify the regex to suit your own specific needs.
Also this is pure build.xml ant with no external dependencies whatsoever.
Sure, but you have to write your own task for it. Visit http://ant.apache.org/manual/develop.html#writingowntask for more information about writing own tasks for Ant. In your Ant task you may parse your HTML file as needed.
I claim, that it is not directly possible with "pure" XML (build.xml) to achieve what you want.
Take a look at the (http://ant.apache.org/manual/Tasks/xmlproperty.html) task and see if it'll work for you. It's pretty straight forward:
<xmlProperty file="${html.file}"
prefix="html."/>
After all, HTML is just a subset of XML. I've used it before to do this very task. No need to write your own task or script.
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>
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).