Browse Source

add magic property that override's tstamp's idea of "now" in ISO-8601 format

https://bz.apache.org/bugzilla/show_bug.cgi?id=61079
master
Jan Matrne 8 years ago
parent
commit
7a7307bc99
5 changed files with 80 additions and 11 deletions
  1. +6
    -4
      manual/Tasks/tstamp.html
  2. +4
    -0
      manual/running.html
  3. +13
    -0
      src/main/org/apache/tools/ant/MagicNames.java
  4. +40
    -7
      src/main/org/apache/tools/ant/taskdefs/Tstamp.java
  5. +17
    -0
      src/tests/antunit/taskdefs/tstamp-test.xml

+ 6
- 4
manual/Tasks/tstamp.html View File

@@ -41,10 +41,12 @@ to indicate, for example, the release date. The best place for this task is
probably in an initialization target.</p> probably in an initialization target.</p>


<p><em>Since Ant 1.10.2</em> the magic <p><em>Since Ant 1.10.2</em> the magic
property <code>ant.tstamp.now</code> can be used to specify a fixed
date value in order to create reproducible builds. Its value must be
a number and is interpreted as seconds since the epoch (midnight
1970-01-01).</p>
property <code>ant.tstamp.now</code> can be used to specify a fixed
date value in order to create reproducible builds. Its value must be
a number and is interpreted as seconds since the epoch (midnight
1970-01-01). With <code>ant.tstamp.now.iso</code> you could also specify that
value in ISO-8601 format (<code>1972-04-17T08:07:00Z</code>). If you specify a value
in an invalid format an INFO message will be logged and the value will be ignored.</p>


<h3>Parameters</h3> <h3>Parameters</h3>
<table border="1" cellpadding="2" cellspacing="0"> <table border="1" cellpadding="2" cellspacing="0">


+ 4
- 0
manual/running.html View File

@@ -490,6 +490,10 @@ org.apache.tools.ant.Executor implementation specified here.
<td>number, seconds since the epoch (midnight 1970-01-01)</td> <td>number, seconds since the epoch (midnight 1970-01-01)</td>
<td>The value to use as current time and date for &lt;tstamp&gt;</td> <td>The value to use as current time and date for &lt;tstamp&gt;</td>
</tr> </tr>
<tr>
<td><code>ant.tstamp.now.iso</code></td>
<td>ISO-8601 timestamp string like <code>1972-04-17T08:07:00Z</code></td>
</tr>
</table> </table>


<p> <p>


+ 13
- 0
src/main/org/apache/tools/ant/MagicNames.java View File

@@ -308,5 +308,18 @@ public final class MagicNames {
* @since Ant 1.10.2 * @since Ant 1.10.2
*/ */
public static final String TSTAMP_NOW = "ant.tstamp.now"; public static final String TSTAMP_NOW = "ant.tstamp.now";

/**
* Magic property that can be set to contain a value for tstamp's
* "now" in order to make builds that use the task create
* reproducible results.
*
* <p>The value is expected to be in ISO time format
* (<i>1972-04-17T08:07</i>)</p>
*
* Value: {@value}
* @since Ant 1.10.2
*/
public static final String TSTAMP_NOW_ISO = "ant.tstamp.now.iso";
} }



+ 40
- 7
src/main/org/apache/tools/ant/taskdefs/Tstamp.java View File

@@ -19,6 +19,7 @@
package org.apache.tools.ant.taskdefs; package org.apache.tools.ant.taskdefs;


import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
@@ -26,9 +27,12 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import java.util.TimeZone; import java.util.TimeZone;
import java.util.Vector; import java.util.Vector;
import java.util.function.BiFunction;
import java.util.function.Function;


import org.apache.tools.ant.BuildException; import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Location; import org.apache.tools.ant.Location;
@@ -111,16 +115,45 @@ public class Tstamp extends Task {
* Return the {@link Date} instance to use as base for DSTAMP, TSTAMP and TODAY. * Return the {@link Date} instance to use as base for DSTAMP, TSTAMP and TODAY.
*/ */
protected Date getNow() { protected Date getNow() {
String magicNow = getProject().getProperty(MagicNames.TSTAMP_NOW);
if (magicNow != null && magicNow.length() > 0) {
Optional<Date> now = getNow(
MagicNames.TSTAMP_NOW_ISO,
s -> Date.from(Instant.parse(s)),
(k, v) -> "magic property " + k + " ignored as '" + v + "' is not in valid ISO pattern"
);
if (now.isPresent()) {
return now.get();
}

now = getNow(
MagicNames.TSTAMP_NOW,
s -> new Date(1000 * Long.parseLong(s)),
(k, v) -> "magic property " + k + " ignored as " + v + " is not a valid number"
);
if (now.isPresent()) {
return now.get();
}

return new Date();
}

/**
* Checks and returns a Date if the specified property is set.
* @param propertyName name of the property to check
* @param map convertion of the property value as string to Date
* @param log supplier of the log message containg the property name and value if
* the convertion fails
* @return Optional containing the Date or null
*/
protected Optional<Date> getNow(String propertyName, Function<String, Date> map, BiFunction<String, String, String> log) {
String property = getProject().getProperty(propertyName);
if (property != null && property.length() > 0) {
try { try {
return new Date(1000 * Long.parseLong(magicNow));
} catch (NumberFormatException ex) {
log("magic property " + MagicNames.TSTAMP_NOW + " ignored as "
+ magicNow + " is not a valid number");
return Optional.ofNullable(map.apply(property));
} catch (Exception e) {
log(log.apply(propertyName, property));
} }
} }
return new Date();
return Optional.empty();
} }


/** /**


+ 17
- 0
src/tests/antunit/taskdefs/tstamp-test.xml View File

@@ -24,4 +24,21 @@
<tstamp/> <tstamp/>
<au:assertPropertyEquals name="DSTAMP" value="19700102"/> <au:assertPropertyEquals name="DSTAMP" value="19700102"/>
</target> </target>

<target name="testMagicPropertyIso">
<local name="ant.tstamp.now.iso"/>
<property name="ant.tstamp.now.iso" value="1972-04-17T08:07:00Z"/>
<tstamp/>
<au:assertPropertyEquals name="DSTAMP" value="19720417"/>
</target>

<target name="testMagicPropertyBoth">
<local name="ant.tstamp.now"/>
<local name="ant.tstamp.now.iso"/>
<property name="ant.tstamp.now" value="100000"/>
<property name="ant.tstamp.now.iso" value="1972-04-17T08:07:22Z"/>
<tstamp/>
<!-- 'iso' overrides 'simple' -->
<au:assertPropertyEquals name="DSTAMP" value="19720417"/>
</target>
</project> </project>

Loading…
Cancel
Save