Use a more compact layers.idx format

Update the `layers.idx` format so that it is more compact and can be
parsed by third-parties as YAML.

Closes gh-20860
This commit is contained in:
Phillip Webb
2020-04-06 15:40:54 -07:00
parent 36fd2ed249
commit 65672a1150
18 changed files with 475 additions and 168 deletions

View File

@@ -15,12 +15,14 @@
*/
package org.springframework.boot.maven;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import java.util.jar.JarFile;
import java.util.stream.Collectors;
@@ -31,7 +33,6 @@ import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.loader.tools.FileUtils;
import org.springframework.boot.loader.tools.JarModeLibrary;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.FileSystemUtils;
import static org.assertj.core.api.Assertions.assertThat;
@@ -305,12 +306,9 @@ class JarIntegrationTests extends AbstractArchiveIntegrationTests {
"BOOT-INF/lib/" + JarModeLibrary.LAYER_TOOLS.getCoordinates().getArtifactId());
try {
try (JarFile jarFile = new JarFile(repackaged)) {
ZipEntry entry = jarFile.getEntry("BOOT-INF/layers.idx");
InputStream inputStream = jarFile.getInputStream(entry);
InputStreamReader reader = new InputStreamReader(inputStream);
String[] lines = FileCopyUtils.copyToString(reader).split("\\n");
assertThat(Arrays.stream(lines).map((n) -> n.split(" ")[0]).distinct()).containsExactly(
"dependencies", "spring-boot-loader", "snapshot-dependencies", "application");
Map<String, List<String>> layerIndex = readLayerIndex(jarFile);
assertThat(layerIndex.keySet()).containsExactly("dependencies", "spring-boot-loader",
"snapshot-dependencies", "application");
}
}
catch (IOException ex) {
@@ -337,12 +335,9 @@ class JarIntegrationTests extends AbstractArchiveIntegrationTests {
.hasEntryWithNameStartingWith("BOOT-INF/lib/jar-release")
.hasEntryWithNameStartingWith("BOOT-INF/lib/jar-snapshot");
try (JarFile jarFile = new JarFile(repackaged)) {
ZipEntry entry = jarFile.getEntry("BOOT-INF/layers.idx");
InputStream inputStream = jarFile.getInputStream(entry);
InputStreamReader reader = new InputStreamReader(inputStream);
String[] lines = FileCopyUtils.copyToString(reader).split("\\n");
assertThat(Arrays.stream(lines).map((n) -> n.split(" ")[0]).distinct()).containsExactly(
"my-dependencies-name", "snapshot-dependencies", "configuration", "application");
Map<String, List<String>> layerIndex = readLayerIndex(jarFile);
assertThat(layerIndex.keySet()).containsExactly("my-dependencies-name", "snapshot-dependencies",
"configuration", "application");
}
});
}
@@ -378,4 +373,23 @@ class JarIntegrationTests extends AbstractArchiveIntegrationTests {
return jarHash.get();
}
private Map<String, List<String>> readLayerIndex(JarFile jarFile) throws IOException {
Map<String, List<String>> index = new LinkedHashMap<>();
ZipEntry indexEntry = jarFile.getEntry("BOOT-INF/layers.idx");
try (BufferedReader reader = new BufferedReader(new InputStreamReader(jarFile.getInputStream(indexEntry)))) {
String line = reader.readLine();
String layer = null;
while (line != null) {
if (line.startsWith("- ")) {
layer = line.substring(3, line.length() - 2);
}
else if (line.startsWith(" - ")) {
index.computeIfAbsent(layer, (key) -> new ArrayList<>()).add(line.substring(5, line.length() - 1));
}
line = reader.readLine();
}
return index;
}
}
}