MASSEMBLY-921 make archives reproducible, reusing m-source-p PoC
diff --git a/pom.xml b/pom.xml
index 7be8e1c..c64de1f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -30,7 +30,7 @@
</parent>
<artifactId>maven-assembly-plugin</artifactId>
- <version>3.1.2-SNAPSHOT</version>
+ <version>3.2.0-SNAPSHOT</version>
<packaging>maven-plugin</packaging>
<name>Apache Maven Assembly Plugin</name>
@@ -64,7 +64,7 @@
<properties>
<javaVersion>7</javaVersion>
<mdoVersion>2.0.0</mdoVersion>
- <mavenArchiverVersion>3.4.0</mavenArchiverVersion>
+ <mavenArchiverVersion>3.5.0</mavenArchiverVersion>
<mavenFilteringVersion>3.1.1</mavenFilteringVersion>
<mavenVersion>3.0</mavenVersion>
<testOutputToFile>true</testOutputToFile>
@@ -137,7 +137,7 @@
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-archiver</artifactId>
- <version>4.1.0</version>
+ <version>4.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.maven.shared</groupId>
@@ -162,7 +162,7 @@
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-io</artifactId>
- <version>3.1.1</version>
+ <version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
@@ -172,13 +172,14 @@
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
- <version>3.2.0</version>
+ <version>3.3.0</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.6</version>
</dependency>
+
<dependency>
<groupId>org.apache.maven.plugin-testing</groupId>
<artifactId>maven-plugin-testing-harness</artifactId>
@@ -267,7 +268,6 @@
<plugin>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-component-metadata</artifactId>
- <version>1.7</version>
<executions>
<execution>
<id>descriptors</id>
@@ -402,6 +402,7 @@
<pomInclude>projects/*/*/pom.xml</pomInclude>
<pomInclude>projects/descriptor-refs/*/*/pom.xml</pomInclude>
<pomInclude>projects/multimodule/multimodule-siblingParent/parent/pom.xml</pomInclude>
+ <pomInclude>projects/reproducible/pom.xml</pomInclude>
</pomIncludes>
<pomExcludes>
<pomExclude>projects/repositories/repo-with-snapshot-parents/pom.xml</pomExclude>
diff --git a/src/it/projects/reproducible/invoker.properties b/src/it/projects/reproducible/invoker.properties
new file mode 100644
index 0000000..cec67fc
--- /dev/null
+++ b/src/it/projects/reproducible/invoker.properties
@@ -0,0 +1,18 @@
+# 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.
+
+invoker.goals=org.apache.maven.plugins:maven-assembly-plugin:${testVersion}:single deploy:deploy
diff --git a/src/it/projects/reproducible/pom.xml b/src/it/projects/reproducible/pom.xml
new file mode 100644
index 0000000..e21fba1
--- /dev/null
+++ b/src/it/projects/reproducible/pom.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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 xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.maven.plugin.assembly.test</groupId>
+ <artifactId>it-project-parent</artifactId>
+ <version>1</version>
+ </parent>
+
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>reproducible</artifactId>
+ <version>1.0</version>
+
+ <name>Test for reproducibility of assembly archives</name>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <project.build.outputTimestamp>2019-08-21T18:28:52Z</project.build.outputTimestamp>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <configuration>
+ <tarLongFileMode>posix</tarLongFileMode>
+ <descriptors>
+ <descriptor>src/assemble/src.xml</descriptor>
+ </descriptors>
+ <archive>
+ <manifest>
+ <!-- remove default entries since it contains "Created-By: Maven Source Plugin <current plugin version>"
+ which varies over time in this IT -->
+ <addDefaultEntries>false</addDefaultEntries>
+ </manifest>
+ </archive>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.8.2</version>
+ <configuration>
+ <!-- Deployments will be written to ${basedir}/target -->
+ <altDeploymentRepository>mine::default::file://${basedir}/target/repo</altDeploymentRepository>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/src/it/projects/reproducible/src/assemble/src.xml b/src/it/projects/reproducible/src/assemble/src.xml
new file mode 100644
index 0000000..3f4ab15
--- /dev/null
+++ b/src/it/projects/reproducible/src/assemble/src.xml
@@ -0,0 +1,47 @@
+<?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.
+-->
+
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
+ <id>src</id>
+ <formats>
+ <format>zip</format>
+ <format>tar</format>
+ <format>jar</format>
+ </formats>
+ <includeBaseDirectory>false</includeBaseDirectory>
+ <fileSets>
+ <fileSet>
+ <outputDirectory></outputDirectory>
+ <directory>src</directory>
+ <filtered>true</filtered>
+ <lineEnding>lf</lineEnding>
+ </fileSet>
+ </fileSets>
+ <files>
+ <file>
+ <source>src/main/resources/executable.txt</source>
+ <fileMode>0755</fileMode>
+ <filtered>true</filtered>
+ <lineEnding>lf</lineEnding>
+ </file>
+ </files>
+</assembly>
diff --git a/src/it/projects/reproducible/src/main/resources/Uppercase.txt b/src/it/projects/reproducible/src/main/resources/Uppercase.txt
new file mode 100644
index 0000000..00ae6c0
--- /dev/null
+++ b/src/it/projects/reproducible/src/main/resources/Uppercase.txt
@@ -0,0 +1,17 @@
+# 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.
+
diff --git a/src/it/projects/reproducible/src/main/resources/dir-A/A2.txt b/src/it/projects/reproducible/src/main/resources/dir-A/A2.txt
new file mode 100644
index 0000000..00ae6c0
--- /dev/null
+++ b/src/it/projects/reproducible/src/main/resources/dir-A/A2.txt
@@ -0,0 +1,17 @@
+# 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.
+
diff --git a/src/it/projects/reproducible/src/main/resources/dir-A/A4.txt b/src/it/projects/reproducible/src/main/resources/dir-A/A4.txt
new file mode 100644
index 0000000..00ae6c0
--- /dev/null
+++ b/src/it/projects/reproducible/src/main/resources/dir-A/A4.txt
@@ -0,0 +1,17 @@
+# 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.
+
diff --git a/src/it/projects/reproducible/src/main/resources/dir-A/a1.txt b/src/it/projects/reproducible/src/main/resources/dir-A/a1.txt
new file mode 100644
index 0000000..ca0e172
--- /dev/null
+++ b/src/it/projects/reproducible/src/main/resources/dir-A/a1.txt
@@ -0,0 +1,34 @@
+# 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.
+
+# 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.
+
diff --git a/src/it/projects/reproducible/src/main/resources/dir-A/a3.txt b/src/it/projects/reproducible/src/main/resources/dir-A/a3.txt
new file mode 100644
index 0000000..00ae6c0
--- /dev/null
+++ b/src/it/projects/reproducible/src/main/resources/dir-A/a3.txt
@@ -0,0 +1,17 @@
+# 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.
+
diff --git a/src/it/projects/reproducible/src/main/resources/dir-C/C.txt b/src/it/projects/reproducible/src/main/resources/dir-C/C.txt
new file mode 100644
index 0000000..00ae6c0
--- /dev/null
+++ b/src/it/projects/reproducible/src/main/resources/dir-C/C.txt
@@ -0,0 +1,17 @@
+# 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.
+
diff --git a/src/it/projects/reproducible/src/main/resources/dir-b/B2/B2.txt b/src/it/projects/reproducible/src/main/resources/dir-b/B2/B2.txt
new file mode 100644
index 0000000..00ae6c0
--- /dev/null
+++ b/src/it/projects/reproducible/src/main/resources/dir-b/B2/B2.txt
@@ -0,0 +1,17 @@
+# 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.
+
diff --git a/src/it/projects/reproducible/src/main/resources/dir-b/B4/B4.txt b/src/it/projects/reproducible/src/main/resources/dir-b/B4/B4.txt
new file mode 100644
index 0000000..00ae6c0
--- /dev/null
+++ b/src/it/projects/reproducible/src/main/resources/dir-b/B4/B4.txt
@@ -0,0 +1,17 @@
+# 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.
+
diff --git a/src/it/projects/reproducible/src/main/resources/dir-b/b.txt b/src/it/projects/reproducible/src/main/resources/dir-b/b.txt
new file mode 100644
index 0000000..00ae6c0
--- /dev/null
+++ b/src/it/projects/reproducible/src/main/resources/dir-b/b.txt
@@ -0,0 +1,17 @@
+# 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.
+
diff --git a/src/it/projects/reproducible/src/main/resources/dir-b/b1/b1.txt b/src/it/projects/reproducible/src/main/resources/dir-b/b1/b1.txt
new file mode 100644
index 0000000..00ae6c0
--- /dev/null
+++ b/src/it/projects/reproducible/src/main/resources/dir-b/b1/b1.txt
@@ -0,0 +1,17 @@
+# 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.
+
diff --git a/src/it/projects/reproducible/src/main/resources/dir-b/b3/b3.txt b/src/it/projects/reproducible/src/main/resources/dir-b/b3/b3.txt
new file mode 100644
index 0000000..00ae6c0
--- /dev/null
+++ b/src/it/projects/reproducible/src/main/resources/dir-b/b3/b3.txt
@@ -0,0 +1,17 @@
+# 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.
+
diff --git a/src/it/projects/reproducible/src/main/resources/dir-d/d.txt b/src/it/projects/reproducible/src/main/resources/dir-d/d.txt
new file mode 100644
index 0000000..00ae6c0
--- /dev/null
+++ b/src/it/projects/reproducible/src/main/resources/dir-d/d.txt
@@ -0,0 +1,17 @@
+# 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.
+
diff --git a/src/it/projects/reproducible/src/main/resources/executable.txt b/src/it/projects/reproducible/src/main/resources/executable.txt
new file mode 100755
index 0000000..00ae6c0
--- /dev/null
+++ b/src/it/projects/reproducible/src/main/resources/executable.txt
@@ -0,0 +1,17 @@
+# 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.
+
diff --git a/src/it/projects/reproducible/src/main/resources/lowercase.txt b/src/it/projects/reproducible/src/main/resources/lowercase.txt
new file mode 100644
index 0000000..00ae6c0
--- /dev/null
+++ b/src/it/projects/reproducible/src/main/resources/lowercase.txt
@@ -0,0 +1,17 @@
+# 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.
+
diff --git a/src/it/projects/reproducible/verify.groovy b/src/it/projects/reproducible/verify.groovy
new file mode 100644
index 0000000..2693e3a
--- /dev/null
+++ b/src/it/projects/reproducible/verify.groovy
@@ -0,0 +1,30 @@
+
+/*
+ * 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.
+ */
+
+//import java.util.zip.*;
+import org.apache.commons.compress.archivers.zip.*;
+
+File deployDir = new File( basedir, 'target/repo/org/apache/maven/its/reproducible/1.0' )
+
+assert deployDir.exists()
+
+assert new File( deployDir, 'reproducible-1.0-src.zip.sha1' ).text == '5ce34fc133d47cbc9c81195877dbe10b9ec7d864'
+assert new File( deployDir, 'reproducible-1.0-src.tar.sha1' ).text == '0b9dc1da069705a93b4954a198c18bd248822bf8'
+assert new File( deployDir, 'reproducible-1.0-src.jar.sha1' ).text == '9b41cf2a80bc91c1f56b769bbef61c5dfd57974c'
diff --git a/src/main/java/org/apache/maven/plugins/assembly/archive/AssemblyArchiver.java b/src/main/java/org/apache/maven/plugins/assembly/archive/AssemblyArchiver.java
index e8c5c9d..36d2b4a 100644
--- a/src/main/java/org/apache/maven/plugins/assembly/archive/AssemblyArchiver.java
+++ b/src/main/java/org/apache/maven/plugins/assembly/archive/AssemblyArchiver.java
@@ -25,6 +25,7 @@
import org.apache.maven.plugins.assembly.model.Assembly;
import java.io.File;
+import java.util.Date;
/**
* Creates an archive
@@ -55,12 +56,13 @@
* @param configSource The {@link org.apache.maven.plugins.assembly.AssemblerConfigurationSource}
* @param recompressZippedFiles recompress zipped files.
* @param mergeManifestMode How to handle already existing Manifest files (skip, merge, mergewithoutmain)
+ * @param sourceDateEpoch Timestamp for reproducible archive entries
* @return The resulting archive file.
* @throws ArchiveCreationException when creation fails
* @throws org.apache.maven.plugins.assembly.format.AssemblyFormattingException when formatting fails
- * @throws org.apache.maven.plugins.assembly.InvalidAssemblerConfigurationException when the configurationis bad
+ * @throws org.apache.maven.plugins.assembly.InvalidAssemblerConfigurationException when the configuration is bad
*/
File createArchive( Assembly assembly, String fullName, String format, AssemblerConfigurationSource configSource,
- boolean recompressZippedFiles, String mergeManifestMode )
+ boolean recompressZippedFiles, String mergeManifestMode, Date outputTimestamp )
throws ArchiveCreationException, AssemblyFormattingException, InvalidAssemblerConfigurationException;
}
diff --git a/src/main/java/org/apache/maven/plugins/assembly/archive/DefaultAssemblyArchiver.java b/src/main/java/org/apache/maven/plugins/assembly/archive/DefaultAssemblyArchiver.java
index 8419f3d..6ee3e4c 100644
--- a/src/main/java/org/apache/maven/plugins/assembly/archive/DefaultAssemblyArchiver.java
+++ b/src/main/java/org/apache/maven/plugins/assembly/archive/DefaultAssemblyArchiver.java
@@ -73,6 +73,7 @@
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Date;
import java.util.List;
import java.util.Map;
@@ -134,7 +135,7 @@
@Override
public File createArchive( final Assembly assembly, final String fullName, final String format,
final AssemblerConfigurationSource configSource, boolean recompressZippedFiles,
- String mergeManifestMode )
+ String mergeManifestMode, Date outputTimestamp )
throws ArchiveCreationException, AssemblyFormattingException, InvalidAssemblerConfigurationException
{
validate( assembly );
@@ -172,7 +173,7 @@
final Archiver archiver =
createArchiver( format, assembly.isIncludeBaseDirectory(), basedir, configSource, containerHandlers,
- recompressZippedFiles, mergeManifestMode );
+ recompressZippedFiles, mergeManifestMode, outputTimestamp );
archiver.setDestFile( destFile );
@@ -284,7 +285,7 @@
protected Archiver createArchiver( final String format, final boolean includeBaseDir, final String finalName,
final AssemblerConfigurationSource configSource,
final List<ContainerDescriptorHandler> containerHandlers,
- boolean recompressZippedFiles, String mergeManifestMode )
+ boolean recompressZippedFiles, String mergeManifestMode, Date outputTimestamp )
throws NoSuchArchiverException
{
Archiver archiver;
@@ -346,6 +347,12 @@
archiver.setIgnorePermissions( configSource.isIgnorePermissions() );
archiver.setForced( !configSource.isUpdateOnly() );
+ // configure for Reproducible Builds based on outputTimestamp value
+ if ( outputTimestamp != null )
+ {
+ archiver.configureReproducible( outputTimestamp );
+ }
+
return archiver;
}
diff --git a/src/main/java/org/apache/maven/plugins/assembly/archive/archiver/AssemblyProxyArchiver.java b/src/main/java/org/apache/maven/plugins/assembly/archive/archiver/AssemblyProxyArchiver.java
index 7b9a621..a8ec9ba 100644
--- a/src/main/java/org/apache/maven/plugins/assembly/archive/archiver/AssemblyProxyArchiver.java
+++ b/src/main/java/org/apache/maven/plugins/assembly/archive/archiver/AssemblyProxyArchiver.java
@@ -44,6 +44,8 @@
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Date;
import java.util.List;
import java.util.Map;
@@ -1029,4 +1031,76 @@
}
}
+ @Override
+ public void setLastModifiedDate( Date lastModifiedDate )
+ {
+ delegate.setLastModifiedDate( lastModifiedDate );
+ }
+
+ @Override
+ public Date getLastModifiedDate()
+ {
+ return delegate.getLastModifiedDate();
+ }
+
+ @Override
+ public void setFilenameComparator( Comparator<String> filenameComparator )
+ {
+ delegate.setFilenameComparator( filenameComparator );
+ }
+
+ @Override
+ public void configureReproducible( Date outputTimestamp )
+ {
+ delegate.configureReproducible( outputTimestamp );
+ }
+
+ @Override
+ public void setOverrideUid( int uid )
+ {
+ delegate.setOverrideUid( uid );
+ }
+
+ @Override
+ public void setOverrideUserName( String userName )
+ {
+ delegate.setOverrideUserName( userName );
+ }
+
+ @Override
+ public int getOverrideUid()
+ {
+ return delegate.getOverrideUid();
+ }
+
+ @Override
+ public String getOverrideUserName()
+ {
+ return delegate.getOverrideUserName();
+ }
+
+ @Override
+ public void setOverrideGid( int gid )
+ {
+ delegate.setOverrideGid( gid );
+ }
+
+ @Override
+ public void setOverrideGroupName( String groupName )
+ {
+ delegate.setOverrideGroupName( groupName );
+ }
+
+ @Override
+ public int getOverrideGid()
+ {
+ return delegate.getOverrideGid();
+ }
+
+ @Override
+ public String getOverrideGroupName()
+ {
+ return delegate.getOverrideGroupName();
+ }
+
}
diff --git a/src/main/java/org/apache/maven/plugins/assembly/mojos/AbstractAssemblyMojo.java b/src/main/java/org/apache/maven/plugins/assembly/mojos/AbstractAssemblyMojo.java
index 2989a41..3432c75 100644
--- a/src/main/java/org/apache/maven/plugins/assembly/mojos/AbstractAssemblyMojo.java
+++ b/src/main/java/org/apache/maven/plugins/assembly/mojos/AbstractAssemblyMojo.java
@@ -20,6 +20,7 @@
*/
import org.apache.maven.archiver.MavenArchiveConfiguration;
+import org.apache.maven.archiver.MavenArchiver;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
@@ -50,6 +51,7 @@
import javax.annotation.Nonnull;
import java.io.File;
import java.util.Collections;
+import java.util.Date;
import java.util.List;
import java.util.Properties;
@@ -390,6 +392,16 @@
@Parameter
private List<String> delimiters;
+ /**
+ * Timestamp for reproducible output archive entries, either formatted as ISO 8601
+ * <code>yyyy-MM-dd'T'HH:mm:ssXXX</code> or as an int representing seconds since the epoch (like
+ * <a href="https://reproducible-builds.org/docs/source-date-epoch/">SOURCE_DATE_EPOCH</a>).
+ *
+ * @since 3.2.0
+ */
+ @Parameter( defaultValue = "${project.build.outputTimestamp}" )
+ private String outputTimestamp;
+
public static FixedStringSearchInterpolator mainProjectInterpolator( MavenProject mainProject )
{
if ( mainProject != null )
@@ -450,6 +462,9 @@
// TODO: include dependencies marked for distribution under certain formats
// TODO: how, might we plug this into an installer, such as NSIS?
+ MavenArchiver mavenArchiver = new MavenArchiver();
+ Date outputDate = mavenArchiver.parseOutputTimestamp( outputTimestamp );
+
boolean warnedAboutMainProjectArtifact = false;
for ( final Assembly assembly : assemblies )
{
@@ -472,7 +487,7 @@
{
final File destFile =
assemblyArchiver.createArchive( assembly, fullName, format,
- this, isRecompressZippedFiles(), getMergeManifestMode() );
+ this, isRecompressZippedFiles(), getMergeManifestMode(), outputDate );
final MavenProject project = getProject();
final String type = project.getArtifact().getType();
diff --git a/src/test/java/org/apache/maven/plugins/assembly/archive/DefaultAssemblyArchiverTest.java b/src/test/java/org/apache/maven/plugins/assembly/archive/DefaultAssemblyArchiverTest.java
index dbb6cf4..2b1f23f 100644
--- a/src/test/java/org/apache/maven/plugins/assembly/archive/DefaultAssemblyArchiverTest.java
+++ b/src/test/java/org/apache/maven/plugins/assembly/archive/DefaultAssemblyArchiverTest.java
@@ -127,7 +127,7 @@
mm.replayAll();
final DefaultAssemblyArchiver archiver = createSubject( macMgr, null, null );
- archiver.createArchive( new Assembly(), "full-name", "zip", configSource, false, null );
+ archiver.createArchive( new Assembly(), "full-name", "zip", configSource, false, null, null );
mm.verifyAll();
}
@@ -196,7 +196,7 @@
final DefaultAssemblyArchiver subject = createSubject( macMgr, Collections.singletonList( phase ), null );
- subject.createArchive( assembly, "full-name", "zip", configSource, false, null );
+ subject.createArchive( assembly, "full-name", "zip", configSource, false, null, null );
mm.verifyAll();
}
@@ -245,7 +245,7 @@
final DefaultAssemblyArchiver subject =
createSubject( macArchiverManager, new ArrayList<AssemblyArchiverPhase>(), null );
- subject.createArchiver( "dummy", false, "finalName", configSource, null, false, null );
+ subject.createArchiver( "dummy", false, "finalName", configSource, null, false, null, null );
assertEquals( simpleConfig, archiver.getSimpleConfig() );
@@ -273,7 +273,7 @@
final DefaultAssemblyArchiver subject = setupStdExpectations( mm, macArchiverManager, configSource );
- subject.createArchiver( "tar", false, "finalName", configSource, null, false, null );
+ subject.createArchiver( "tar", false, "finalName", configSource, null, false, null, null );
assertNull( ttArchiver.compressionMethod );
assertEquals( TarLongFileMode.fail, ttArchiver.longFileMode );
@@ -319,7 +319,7 @@
expect( configSource.getMavenSession() ).andReturn( null ).anyTimes();
final DefaultAssemblyArchiver subject = setupStdExpectations( mm, macArchiverManager, configSource );
- subject.createArchiver( "war", false, null, configSource, null, false, null );
+ subject.createArchiver( "war", false, null, configSource, null, false, null, null );
assertFalse( twArchiver.ignoreWebxml );
}
@@ -350,7 +350,7 @@
final DefaultAssemblyArchiver subject =
createSubject( macArchiverManager, new ArrayList<AssemblyArchiverPhase>(), null );
- subject.createArchiver( "zip", false, null, configSource, null, false, null );
+ subject.createArchiver( "zip", false, null, configSource, null, false, null, null );
}
@Test