@@ -35,6 +35,10 @@ Other changes: | |||||
java.nio.file.Path argument. | java.nio.file.Path argument. | ||||
Bugzilla Report 61042 | Bugzilla Report 61042 | ||||
* added a new magic property ant.tstamp.now that can be used to | |||||
override the current time/date used by <tstamp>. | |||||
Bugzilla Report 61079 | |||||
Changes from Ant 1.10.0 TO Ant 1.10.1 | Changes from Ant 1.10.0 TO Ant 1.10.1 | ||||
===================================== | ===================================== | ||||
@@ -40,6 +40,12 @@ time-stamped filenames, or used to replace placeholder tags inside documents | |||||
to indicate, for example, the release date. The best place for this task is | 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 | |||||
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> | |||||
<h3>Parameters</h3> | <h3>Parameters</h3> | ||||
<table border="1" cellpadding="2" cellspacing="0"> | <table border="1" cellpadding="2" cellspacing="0"> | ||||
<tr> | <tr> | ||||
@@ -485,6 +485,11 @@ org.apache.tools.ant.Executor implementation specified here. | |||||
<a href="argumentprocessor.html#repository">ArgumentProcessor internal repository</a>. | <a href="argumentprocessor.html#repository">ArgumentProcessor internal repository</a>. | ||||
</td> | </td> | ||||
</tr> | </tr> | ||||
<tr> | |||||
<td><code>ant.tstamp.now</code></td> | |||||
<td>number, seconds since the epoch (midnight 1970-01-01)</td> | |||||
<td>The value to use as current time and date for <tstamp></td> | |||||
</tr> | |||||
</table> | </table> | ||||
<p> | <p> | ||||
@@ -295,5 +295,18 @@ public final class MagicNames { | |||||
* Value {@value} | * Value {@value} | ||||
*/ | */ | ||||
public static final String HTTP_AGENT_PROPERTY = "ant.http.agent"; | public static final String HTTP_AGENT_PROPERTY = "ant.http.agent"; | ||||
/** | |||||
* 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 a number representing the date | |||||
* as seconds since the epoch.</p> | |||||
* | |||||
* Value: {@value} | |||||
* @since Ant 1.10.2 | |||||
*/ | |||||
public static final String TSTAMP_NOW = "ant.tstamp.now"; | |||||
} | } | ||||
@@ -32,6 +32,7 @@ import java.util.Vector; | |||||
import org.apache.tools.ant.BuildException; | import org.apache.tools.ant.BuildException; | ||||
import org.apache.tools.ant.Location; | import org.apache.tools.ant.Location; | ||||
import org.apache.tools.ant.MagicNames; | |||||
import org.apache.tools.ant.Project; | import org.apache.tools.ant.Project; | ||||
import org.apache.tools.ant.Task; | import org.apache.tools.ant.Task; | ||||
import org.apache.tools.ant.types.EnumeratedAttribute; | import org.apache.tools.ant.types.EnumeratedAttribute; | ||||
@@ -69,7 +70,7 @@ public class Tstamp extends Task { | |||||
@Override | @Override | ||||
public void execute() throws BuildException { | public void execute() throws BuildException { | ||||
try { | try { | ||||
Date d = new Date(); | |||||
Date d = getNow(); | |||||
customFormats.forEach(cts -> cts.execute(getProject(), d, getLocation())); | customFormats.forEach(cts -> cts.execute(getProject(), d, getLocation())); | ||||
@@ -106,6 +107,22 @@ public class Tstamp extends Task { | |||||
getProject().setNewProperty(prefix + name, value); | getProject().setNewProperty(prefix + name, value); | ||||
} | } | ||||
/** | |||||
* 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) { | |||||
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 new Date(); | |||||
} | |||||
/** | /** | ||||
* This nested element that allows a property to be set | * This nested element that allows a property to be set | ||||
* to the current date and time in a given format. | * to the current date and time in a given format. | ||||
@@ -0,0 +1,27 @@ | |||||
<?xml version="1.0"?> | |||||
<!-- | |||||
Licensed to the Apache Software Foundation (ASF) under one or more | |||||
contributor license agreements. See the NOTICE file distributed with | |||||
this work for additional information regarding copyright ownership. | |||||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
(the "License"); you may not use this file except in compliance with | |||||
the License. You may obtain a copy of the License at | |||||
http://www.apache.org/licenses/LICENSE-2.0 | |||||
Unless required by applicable law or agreed to in writing, software | |||||
distributed under the License is distributed on an "AS IS" BASIS, | |||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
See the License for the specific language governing permissions and | |||||
limitations under the License. | |||||
--> | |||||
<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit"> | |||||
<import file="../antunit-base.xml" /> | |||||
<target name="testMagicProperty"> | |||||
<local name="ant.tstamp.now"/> | |||||
<property name="ant.tstamp.now" value="100000"/> | |||||
<tstamp/> | |||||
<au:assertPropertyEquals name="DSTAMP" value="19700102"/> | |||||
</target> | |||||
</project> |