Update extract to write files to their original, unlayered location
This commit is contained in:
@@ -83,7 +83,7 @@ class ExtractCommand extends Command {
|
||||
}
|
||||
|
||||
private void write(ZipInputStream zip, ZipEntry entry, File destination) throws IOException {
|
||||
String path = StringUtils.cleanPath(entry.getName());
|
||||
String path = StringUtils.cleanPath(this.layers.getOriginalLocation(entry));
|
||||
File file = new File(destination, path);
|
||||
if (file.getAbsolutePath().startsWith(destination.getAbsolutePath())) {
|
||||
mkParentDirs(file);
|
||||
|
||||
@@ -44,7 +44,7 @@ class IndexedLayers implements Layers {
|
||||
|
||||
private static final String SPRING_BOOT_APPLICATION_LAYER = "springbootapplication";
|
||||
|
||||
private static final Pattern LAYER_PATTERN = Pattern.compile("^BOOT-INF\\/layers\\/([a-zA-Z0-9-]+)\\/.*$");
|
||||
private static final Pattern LAYER_PATTERN = Pattern.compile("^BOOT-INF\\/layers\\/([a-zA-Z0-9-]+)\\/(.*$)");
|
||||
|
||||
private List<String> layers;
|
||||
|
||||
@@ -74,6 +74,18 @@ class IndexedLayers implements Layers {
|
||||
}
|
||||
return this.layers.contains(APPLICATION_LAYER) ? APPLICATION_LAYER : SPRING_BOOT_APPLICATION_LAYER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOriginalLocation(ZipEntry entry) {
|
||||
String name = entry.getName();
|
||||
Matcher matcher = LAYER_PATTERN.matcher(name);
|
||||
if (matcher.matches()) {
|
||||
String layer = matcher.group(1);
|
||||
Assert.state(this.layers.contains(layer), () -> "Unexpected layer '" + layer + "'");
|
||||
return "BOOT-INF/" + matcher.group(2);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an {@link IndexedLayers} instance of possible.
|
||||
|
||||
@@ -41,6 +41,13 @@ interface Layers extends Iterable<String> {
|
||||
* @return the layer that the entry is in
|
||||
*/
|
||||
String getLayer(ZipEntry entry);
|
||||
|
||||
/**
|
||||
* Returns the original, unlayered location of the given entry.
|
||||
* @param entry the entry for which the original location is required
|
||||
* @return the original location
|
||||
*/
|
||||
String getOriginalLocation(ZipEntry entry);
|
||||
|
||||
/**
|
||||
* Return a {@link Layers} instance for the currently running application.
|
||||
|
||||
@@ -70,9 +70,9 @@ class ExtractCommandTests {
|
||||
void runExtractsLayers() throws Exception {
|
||||
this.command.run(Collections.emptyMap(), Collections.emptyList());
|
||||
assertThat(this.extract.list()).containsOnly("a", "b", "c");
|
||||
assertThat(new File(this.extract, "a/a/a.jar")).exists();
|
||||
assertThat(new File(this.extract, "b/b/b.jar")).exists();
|
||||
assertThat(new File(this.extract, "c/c/c.jar")).exists();
|
||||
assertThat(new File(this.extract, "a/a.jar")).exists();
|
||||
assertThat(new File(this.extract, "b/b.jar")).exists();
|
||||
assertThat(new File(this.extract, "c/c.jar")).exists();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -81,17 +81,17 @@ class ExtractCommandTests {
|
||||
this.command.run(Collections.singletonMap(ExtractCommand.DESTINATION_OPTION, out.getAbsolutePath()),
|
||||
Collections.emptyList());
|
||||
assertThat(this.extract.list()).containsOnly("out");
|
||||
assertThat(new File(this.extract, "out/a/a/a.jar")).exists();
|
||||
assertThat(new File(this.extract, "out/b/b/b.jar")).exists();
|
||||
assertThat(new File(this.extract, "out/c/c/c.jar")).exists();
|
||||
assertThat(new File(this.extract, "out/a/a.jar")).exists();
|
||||
assertThat(new File(this.extract, "out/b/b.jar")).exists();
|
||||
assertThat(new File(this.extract, "out/c/c.jar")).exists();
|
||||
}
|
||||
|
||||
@Test
|
||||
void runWhenHasLayerParamsExtractsLimitedLayers() {
|
||||
this.command.run(Collections.emptyMap(), Arrays.asList("a", "c"));
|
||||
assertThat(this.extract.list()).containsOnly("a", "c");
|
||||
assertThat(new File(this.extract, "a/a/a.jar")).exists();
|
||||
assertThat(new File(this.extract, "c/c/c.jar")).exists();
|
||||
assertThat(new File(this.extract, "a/a.jar")).exists();
|
||||
assertThat(new File(this.extract, "c/c.jar")).exists();
|
||||
}
|
||||
|
||||
private File createJarFile(String name) throws IOException {
|
||||
@@ -133,6 +133,11 @@ class ExtractCommandTests {
|
||||
return "c";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOriginalLocation(ZipEntry entry) {
|
||||
return entry.getName().substring(2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -75,6 +75,24 @@ class IndexedLayersTests {
|
||||
IndexedLayers layers = new IndexedLayers("test");
|
||||
assertThat(layers.getLayer(mockEntry("META-INF/MANIFEST.MF"))).isEqualTo("springbootapplication");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getOriginalLocationWithLibJarReturnsBootInfLibLocation() {
|
||||
IndexedLayers layers = new IndexedLayers("test");
|
||||
assertThat(layers.getOriginalLocation(mockEntry("BOOT-INF/layers/test/lib/file.jar"))).isEqualTo("BOOT-INF/lib/file.jar");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getOriginalLocationWithClassesEntryReturnsBootInfClassesLocation() {
|
||||
IndexedLayers layers = new IndexedLayers("test");
|
||||
assertThat(layers.getOriginalLocation(mockEntry("BOOT-INF/layers/test/classes/com/example/Test.class"))).isEqualTo("BOOT-INF/classes/com/example/Test.class");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getOriginalLocationWhenDoesNotMatchLayerPatternsReturnsEntryLocationAsIs() {
|
||||
IndexedLayers layers = new IndexedLayers("test");
|
||||
assertThat(layers.getOriginalLocation(mockEntry("META-INF/MANIFEST.MF"))).isEqualTo("META-INF/MANIFEST.MF");
|
||||
}
|
||||
|
||||
private ZipEntry mockEntry(String name) {
|
||||
ZipEntry entry = mock(ZipEntry.class);
|
||||
|
||||
Reference in New Issue
Block a user