diff --git a/tools/maven-bundle-plugin/src/main/java/org/apache/felix/bundleplugin/BundlePlugin.java b/tools/maven-bundle-plugin/src/main/java/org/apache/felix/bundleplugin/BundlePlugin.java index b0dac50b7a6..8326bde853a 100644 --- a/tools/maven-bundle-plugin/src/main/java/org/apache/felix/bundleplugin/BundlePlugin.java +++ b/tools/maven-bundle-plugin/src/main/java/org/apache/felix/bundleplugin/BundlePlugin.java @@ -32,6 +32,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.Date; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; @@ -1561,6 +1562,19 @@ private static StringBuffer printLicenses( List licenses ) } + private static Date getReproducibleBuildDate() { + String envVariable = System.getenv("SOURCE_DATE_EPOCH"); + if (envVariable == null) { + return null; + } + try { + return new Date(Long.parseLong(envVariable)*1000); + } catch (Exception e) { + return null; + } + } + + /** * @param jar * @throws IOException @@ -1579,7 +1593,8 @@ private void doMavenMetadata( MavenProject currentProject, Jar jar ) throws IOEx jar.putResource( path + "/pom.xml", new FileResource( pomFile ) ); } - Properties p = new Properties(); + java.util.Date buildDate = getReproducibleBuildDate(); + Properties p = buildDate == null ? new Properties() : new TimestampedProperties(buildDate); p.put( "version", currentProject.getVersion() ); p.put( "groupId", currentProject.getGroupId() ); p.put( "artifactId", currentProject.getArtifactId() ); diff --git a/tools/maven-bundle-plugin/src/main/java/org/apache/felix/bundleplugin/TimestampedProperties.java b/tools/maven-bundle-plugin/src/main/java/org/apache/felix/bundleplugin/TimestampedProperties.java new file mode 100644 index 00000000000..d30ac2e91a2 --- /dev/null +++ b/tools/maven-bundle-plugin/src/main/java/org/apache/felix/bundleplugin/TimestampedProperties.java @@ -0,0 +1,48 @@ +package org.apache.felix.bundleplugin; + +import java.io.*; +import java.text.*; +import java.util.*; +import java.util.regex.*; + +/** + * Properties file timestamped with a specified date. + */ +class TimestampedProperties extends Properties +{ + private Date date; + + public TimestampedProperties(Date date) { + this.date = date; + } + + @Override + public void store(OutputStream out, String comments) throws IOException { + store(new OutputStreamWriter(out, "ISO-8859-1"), comments); + } + + @Override + public void store(Writer out, String comments) throws IOException { + // store the properties file in memory + StringWriter buffer = new StringWriter(); + super.store(buffer, comments); + + // Replace the date on the second line of the file + SimpleDateFormat fmt = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH); + fmt.setTimeZone(TimeZone.getTimeZone("UTC")); + String[] lines = buffer.toString().split(Pattern.quote(System.getProperty("line.separator"))); + lines[1] = "#" + fmt.format(date); + + // write the file + BufferedWriter writer = new BufferedWriter(out); + try { + for (String line : lines) { + writer.write(line); + writer.newLine(); + } + writer.flush(); + } finally { + writer.close(); + } + } +}