Output several timestamps in ant

32,936

Solution 1

Use a <macrodef> task together with the <local> task (introduced in Ant 1.8):

<macrodef name="echotimestamp">
  <sequential>
    <local name="timestamp" />
    <tstamp>
      <format property="timestamp" pattern="yyyy-MM-dd HH:mm:ss" />
    </tstamp>
    <echo message="${timestamp}" />
  </sequential>
</macrodef>
<echotimestamp />

Solution 2

Update: You can use an antcall to invoke a task, and create/echo a new timestamp within the scope of that call.

This example shows how to pass a message to the call and echo the current timestamp with a message:

<target name="timestamp2">
  <tstamp>
    <format property="current.time" pattern="MM/dd/yyyy hh:mm:ss aa" />
  </tstamp>

  <echo message="${message} ${current.time}" />      
</target>

<target name="test">
  <antcall target="timestamp2">
    <param name="message" value="hello" />
  </antcall>

  <sleep seconds="5"/>

  <antcall target="timestamp2">
    <param name="message" value="world" />
  </antcall>
</target>

The output when this is run is:

test:

timestamp2:
     [echo] hello 09/24/2009 05:33:22 PM

timestamp2:
     [echo] world 09/24/2009 05:33:24 PM

Solution 3

Following on from @Niek's answer, we can build a macro that behaves like echo but with a time stamp

<macrodef name="echoTS">
  <attribute name="message"/>
  <sequential>
    <var name="current.time" unset="true"/>
    <tstamp><format property="current.time" pattern="yyyy-MM-dd HH:mm:ss" /></tstamp>
    <echo message="${current.time}> @{message}" />
  </sequential> 
</macrodef>

<target name="test-timestamp">
  <echoTS message="hi" />
</target>

which will give output

test-timestamp:
     [echo] 2013-05-03 12:02:38> hi

Solution 4

I like the macrodef solution if indeed it is more efficient than the target one, but I use a var unset=true to force a resetting of the variable, like:

<macrodef name="echoTimestamp">
   <sequential>
      <var name="current.time" unset="true"/>
         <tstamp>
            <format property="current.time" pattern="yyyy-MM-dd HH:mm:ss" />
         </tstamp>
         <echo message="${current.time}" />
   </sequential> 
</macrodef>

Usage

<echoTimestamp />
<sleep seconds="3"/>
<echoTimestamp />

Solution 5

I found that if you use it as a macro rather than an ant target, it works better since it doesn't loop thru the ant file from the beginning everytime you do a antcall target= (less check if you have dependencies and property sets).

<target name="testMe">
    <MyTimestamp></MyTimestamp>
    <sleep seconds="5"></sleep>
    <MyTimestamp></MyTimestamp>
</target>

<macrodef name="MyTimestamp">
    <sequential >
        <tstamp>
            <format property="current.time" pattern="MM/dd/yyyy hh:mm:ss aa"/>
        </tstamp>
        <echo message="RUN_TIME: ${current.time}"/>
    </sequential>
</macrodef>
Share:
32,936
andersonbd1
Author by

andersonbd1

Updated on July 09, 2022

Comments

  • andersonbd1
    andersonbd1 almost 2 years

    The Ant buildfile snippet below is an attempt to simply output the time before and after each sql script is run. I cannot change the structure of the Ant targets (create-tables must call run-sql-script just as it does). The problem is that the properties (time and time2) are immutable (http://ant.apache.org/manual/Tasks/property.html) and thus only time the first operation and not the second. Is there no way to do what I'm trying to do in Ant?

      <target name="create-tables">
        <antcall target="run-sql-script">
          <param name="db.script" value="teams.sql"/>
        </antcall>
    
        <!-- Create the base UDM schema. -->
        <antcall target="run-sql-script">
          <param name="db.script" value="players.sql"/>
        </antcall>
      </target>
      <target name="run-sql-script">
        <tstamp>
          <format property="time" pattern="MM/dd/yyyy hh:mm:ss aa"
              offset="-5" unit="hour"/>
        </tstamp>
        <echo>before: ${time}</echo>
        <sql
            classpath="${classpath}"
            driver="${db.driver}"
            url="${db.url}"
            userid="${db.userid}"
            password="${db.password}"
            src="${script.dir}/${db.script}"
            delimiter="${script.delimiter}"
            onerror="abort">
        </sql>              
        <tstamp>
          <format property="time2" pattern="MM/dd/yyyy hh:mm:ss aa"
                offset="-5" unit="hour"/>
        </tstamp>
        <echo>after: ${time2}</echo>
      </target>
    
  • andersonbd1
    andersonbd1 over 14 years
    @Rich - what did you change? what was the difference between Aaron's original and your change?
  • Rich Seller
    Rich Seller over 14 years
    @andersonbd1, in the first instance the macrodef will set a property with the timestamp, once the timestamp is set it is used everywhere in the build with the original value. In the second version the timestamp variable is scoped to the inner call, so will have a new value each time
  • Slav
    Slav over 10 years
    This displays the same timestamp every time
  • user6741701
    user6741701 about 9 years
    One advantage to using the macrodef is that you don't clutter the output with the name of the timestamp2 target. The output just looks like an annotated echo message.
  • zb226
    zb226 over 6 years
    Note that the var task is not from core ant, but ant-contrib.
  • Vladimir Nabokov
    Vladimir Nabokov almost 6 years
    This is not working as required. It produce the same output in each invocation of echotimestamp