Commit 8f5ef951 authored by Scott Frederick's avatar Scott Frederick

Use current timestamp for index files with Gradle

This commit removes changes the timestamp used when writing the
classpath and layers index files in the Gradle plugin to be the
current timestamp unless `preserveFileTimestamps=true`. It also
polishes some duplication in the handling of entry attributes
when creating the fat archive and adds a test to verify that
the Gradle plugin uses the same fixed timestamp constant as
Gradle uses internally.

See gh-21005
parent b3ccefdb
...@@ -29,11 +29,14 @@ import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; ...@@ -29,11 +29,14 @@ import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.gradle.api.file.FileTreeElement; import org.gradle.api.file.FileTreeElement;
import org.springframework.util.StreamUtils;
/** /**
* Internal utility used to copy entries from the {@code spring-boot-loader.jar}. * Internal utility used to copy entries from the {@code spring-boot-loader.jar}.
* *
* @author Andy Wilkinson * @author Andy Wilkinson
* @author Phillip Webb * @author Phillip Webb
* @author Scott Frederick
*/ */
class LoaderZipEntries { class LoaderZipEntries {
...@@ -84,11 +87,7 @@ class LoaderZipEntries { ...@@ -84,11 +87,7 @@ class LoaderZipEntries {
} }
private void copy(InputStream in, OutputStream out) throws IOException { private void copy(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[4096]; StreamUtils.copy(in, out);
int bytesRead = -1;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
} }
/** /**
......
...@@ -40,6 +40,7 @@ import java.util.zip.ZipInputStream; ...@@ -40,6 +40,7 @@ import java.util.zip.ZipInputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile; import org.apache.commons.compress.archivers.zip.ZipFile;
import org.gradle.api.Project; import org.gradle.api.Project;
import org.gradle.api.internal.file.archive.ZipCopyAction;
import org.gradle.api.tasks.bundling.AbstractArchiveTask; import org.gradle.api.tasks.bundling.AbstractArchiveTask;
import org.gradle.api.tasks.bundling.Jar; import org.gradle.api.tasks.bundling.Jar;
import org.gradle.testfixtures.ProjectBuilder; import org.gradle.testfixtures.ProjectBuilder;
...@@ -56,6 +57,7 @@ import static org.assertj.core.api.Assertions.assertThat; ...@@ -56,6 +57,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* *
* @param <T> the type of the concrete BootArchive implementation * @param <T> the type of the concrete BootArchive implementation
* @author Andy Wilkinson * @author Andy Wilkinson
* @author Scott Frederick
*/ */
abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> { abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
...@@ -330,6 +332,12 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> { ...@@ -330,6 +332,12 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
} }
} }
@Test
void constantTimestampMatchesGradleInternalTimestamp() {
assertThat(BootZipCopyAction.CONSTANT_TIME_FOR_ZIP_ENTRIES)
.isEqualTo(ZipCopyAction.CONSTANT_TIME_FOR_ZIP_ENTRIES);
}
@Test @Test
void reproducibleOrderingCanBeEnabled() throws IOException { void reproducibleOrderingCanBeEnabled() throws IOException {
this.task.setMainClassName("com.example.Main"); this.task.setMainClassName("com.example.Main");
......
...@@ -101,14 +101,10 @@ class BootJarTests extends AbstractBootArchiveTests<TestBootJar> { ...@@ -101,14 +101,10 @@ class BootJarTests extends AbstractBootArchiveTests<TestBootJar> {
assertThat(entryNames).contains("BOOT-INF/lib/first-library.jar", "BOOT-INF/lib/second-library.jar", assertThat(entryNames).contains("BOOT-INF/lib/first-library.jar", "BOOT-INF/lib/second-library.jar",
"BOOT-INF/lib/third-library-SNAPSHOT.jar", "BOOT-INF/classes/com/example/Application.class", "BOOT-INF/lib/third-library-SNAPSHOT.jar", "BOOT-INF/classes/com/example/Application.class",
"BOOT-INF/classes/application.properties", "BOOT-INF/classes/static/test.css"); "BOOT-INF/classes/application.properties", "BOOT-INF/classes/static/test.css");
ZipEntry layersIndexEntry = jarFile.getEntry("BOOT-INF/layers.idx");
assertThat(layersIndexEntry.getTime()).isEqualTo(BootZipCopyAction.CONSTANT_TIME_FOR_ZIP_ENTRIES);
List<String> index = entryLines(jarFile, "BOOT-INF/layers.idx"); List<String> index = entryLines(jarFile, "BOOT-INF/layers.idx");
assertThat(getLayerNames(index)).containsExactly("dependencies", "spring-boot-loader", assertThat(getLayerNames(index)).containsExactly("dependencies", "spring-boot-loader",
"snapshot-dependencies", "application"); "snapshot-dependencies", "application");
String layerToolsJar = "BOOT-INF/lib/" + JarModeLibrary.LAYER_TOOLS.getName(); String layerToolsJar = "BOOT-INF/lib/" + JarModeLibrary.LAYER_TOOLS.getName();
ZipEntry layerToolsEntry = jarFile.getEntry(layerToolsJar);
assertThat(layerToolsEntry.getTime()).isEqualTo(BootZipCopyAction.CONSTANT_TIME_FOR_ZIP_ENTRIES);
List<String> expected = new ArrayList<>(); List<String> expected = new ArrayList<>();
expected.add("- \"dependencies\":"); expected.add("- \"dependencies\":");
expected.add(" - \"BOOT-INF/lib/first-library.jar\""); expected.add(" - \"BOOT-INF/lib/first-library.jar\"");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment