From 7a7307bc999be080c99412b1c67d111af1366ef7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Mat=C3=A8rne?= Date: Tue, 9 May 2017 11:01:51 +0200 Subject: [PATCH] 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 --- manual/Tasks/tstamp.html | 10 ++-- manual/running.html | 4 ++ src/main/org/apache/tools/ant/MagicNames.java | 13 +++++ .../org/apache/tools/ant/taskdefs/Tstamp.java | 47 ++++++++++++++++--- src/tests/antunit/taskdefs/tstamp-test.xml | 17 +++++++ 5 files changed, 80 insertions(+), 11 deletions(-) diff --git a/manual/Tasks/tstamp.html b/manual/Tasks/tstamp.html index c9a83c992..f35d55873 100644 --- a/manual/Tasks/tstamp.html +++ b/manual/Tasks/tstamp.html @@ -41,10 +41,12 @@ to indicate, for example, the release date. The best place for this task is probably in an initialization target.

Since Ant 1.10.2 the magic - property ant.tstamp.now 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).

+property ant.tstamp.now 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 ant.tstamp.now.iso you could also specify that +value in ISO-8601 format (1972-04-17T08:07:00Z). If you specify a value +in an invalid format an INFO message will be logged and the value will be ignored.

Parameters

diff --git a/manual/running.html b/manual/running.html index 3bfb500c8..dac2ef31b 100644 --- a/manual/running.html +++ b/manual/running.html @@ -490,6 +490,10 @@ org.apache.tools.ant.Executor implementation specified here. + + + +
number, seconds since the epoch (midnight 1970-01-01) The value to use as current time and date for <tstamp>
ant.tstamp.now.isoISO-8601 timestamp string like 1972-04-17T08:07:00Z

diff --git a/src/main/org/apache/tools/ant/MagicNames.java b/src/main/org/apache/tools/ant/MagicNames.java index 5f6aec9ca..cfd4cc769 100644 --- a/src/main/org/apache/tools/ant/MagicNames.java +++ b/src/main/org/apache/tools/ant/MagicNames.java @@ -308,5 +308,18 @@ public final class MagicNames { * @since Ant 1.10.2 */ 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. + * + *

The value is expected to be in ISO time format + * (1972-04-17T08:07)

+ * + * Value: {@value} + * @since Ant 1.10.2 + */ + public static final String TSTAMP_NOW_ISO = "ant.tstamp.now.iso"; } diff --git a/src/main/org/apache/tools/ant/taskdefs/Tstamp.java b/src/main/org/apache/tools/ant/taskdefs/Tstamp.java index 98dd77927..3f5c172f4 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Tstamp.java +++ b/src/main/org/apache/tools/ant/taskdefs/Tstamp.java @@ -19,6 +19,7 @@ package org.apache.tools.ant.taskdefs; import java.text.SimpleDateFormat; +import java.time.Instant; import java.util.Calendar; import java.util.Date; import java.util.HashMap; @@ -26,9 +27,12 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.NoSuchElementException; +import java.util.Optional; import java.util.StringTokenizer; import java.util.TimeZone; 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.Location; @@ -111,16 +115,45 @@ public class Tstamp extends Task { * Return the {@link Date} instance to use as base for DSTAMP, TSTAMP and TODAY. */ protected Date getNow() { - String magicNow = getProject().getProperty(MagicNames.TSTAMP_NOW); - if (magicNow != null && magicNow.length() > 0) { + Optional 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 getNow(String propertyName, Function map, BiFunction log) { + String property = getProject().getProperty(propertyName); + if (property != null && property.length() > 0) { 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(); } /** diff --git a/src/tests/antunit/taskdefs/tstamp-test.xml b/src/tests/antunit/taskdefs/tstamp-test.xml index c9bebf866..c358262bf 100644 --- a/src/tests/antunit/taskdefs/tstamp-test.xml +++ b/src/tests/antunit/taskdefs/tstamp-test.xml @@ -24,4 +24,21 @@ + + + + + + + + + + + + + + + + +