Skip to content
This repository has been archived by the owner on Mar 21, 2022. It is now read-only.

Add archive extract files support #208

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 106 additions & 7 deletions src/main/java/com/spotify/docker/BuildMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,24 @@
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.StandardCopyOption;
import java.nio.file.StandardOpenOption;
import java.nio.file.attribute.BasicFileAttributes;
import java.text.MessageFormat;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipInputStream;

import static com.google.common.base.CharMatcher.WHITESPACE;
import static com.google.common.base.Strings.isNullOrEmpty;
Expand Down Expand Up @@ -218,7 +225,11 @@ public class BuildMojo extends AbstractDockerMojo {
*/
@Parameter(property = "dockerResources")
private List<Resource> resources;


/** Flag to enable archive extracting (only if dockerDirectory is set). Defaults to false. */
@Parameter(property = "dockerExtractArchives", defaultValue = "false")
private boolean extractArchives;

/** Built image will be given this name. */
@Parameter(property = "dockerImageName")
private String imageName;
Expand Down Expand Up @@ -745,12 +756,39 @@ private List<String> copyResources(String destination) throws IOException {
} else {
for (String included : includedFiles) {
final Path sourcePath = Paths.get(resource.getDirectory()).resolve(included);
final Path destPath = Paths.get(destination, targetPath).resolve(included);
getLog().info(String.format("Copying %s -> %s", sourcePath, destPath));
// ensure all directories exist because copy operation will fail if they don't
Files.createDirectories(destPath.getParent());
Files.copy(sourcePath, destPath, StandardCopyOption.REPLACE_EXISTING,
StandardCopyOption.COPY_ATTRIBUTES);

if (extractArchives && checkIfArchiveFile(sourcePath)) {
String archive = sourcePath.getFileName().toString();

int pos = archive.lastIndexOf('.');
if (pos > 0) {
archive = archive.substring(0, pos);
}

final Path destPath = Paths.get(destination, targetPath, archive);

// ensure all directories exist because copy operation will fail if
// they don't
Files.createDirectories(destPath);

getLog().info(String.format("Extracting %s -> %s", sourcePath, destPath));

FileSystem zipFileSystem = FileSystems.newFileSystem(sourcePath, null);
final Path root = zipFileSystem.getPath("/");

Files.walkFileTree(root, new ArchiveFileExtractor(destPath));
} else {
final Path destPath = Paths.get(destination, targetPath).resolve(included);

// ensure all directories exist because copy operation will fail if
// they don't
Files.createDirectories(destPath.getParent());

getLog().info(String.format("Copying %s -> %s", sourcePath, destPath));

Files.copy(sourcePath, destPath, StandardCopyOption.REPLACE_EXISTING,
StandardCopyOption.COPY_ATTRIBUTES);
}

copiedPaths.add(separatorsToUnix(Paths.get(targetPath).resolve(included).toString()));
}
Expand Down Expand Up @@ -798,4 +836,65 @@ private DockerClient.BuildParam[] buildParams()
}
return buildParams.toArray(new DockerClient.BuildParam[buildParams.size()]);
}

/**
* Check if the given path is an archive file.
*
* @param filePath
* the path to the file to check
* @return <code>true</code> if the file is an archive; <code>false> otherwise
*/
private boolean checkIfArchiveFile(final Path filePath) {
boolean result = false;

ZipInputStream zipFileInputStream = null;

try {
zipFileInputStream = new ZipInputStream(
Files.newInputStream(filePath, StandardOpenOption.READ));
if (zipFileInputStream.getNextEntry() != null) {
result = true;
}
} catch (IOException e) {
} finally {
if (zipFileInputStream != null) {
try {
zipFileInputStream.close();
} catch (IOException e) {
}
}
}

return result;
}

private static final class ArchiveFileExtractor extends SimpleFileVisitor<Path> {
private final Path destPath;

private ArchiveFileExtractor(Path destPath) {
this.destPath = destPath;
}

@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
throws IOException {
final Path destDir = Paths.get(destPath.toString(), dir.toString());

if (Files.notExists(destDir)) {
Files.createDirectory(destDir);
}

return FileVisitResult.CONTINUE;
}

@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
final Path destFile = Paths.get(destPath.toString(), file.toString());

Files.copy(file, destFile, StandardCopyOption.REPLACE_EXISTING,
StandardCopyOption.COPY_ATTRIBUTES);

return FileVisitResult.CONTINUE;
}
}
}