diff --git a/docker-java-core/src/main/java/com/github/dockerjava/core/dockerfile/Dockerfile.java b/docker-java-core/src/main/java/com/github/dockerjava/core/dockerfile/Dockerfile.java index 752935e19..dba924f7b 100644 --- a/docker-java-core/src/main/java/com/github/dockerjava/core/dockerfile/Dockerfile.java +++ b/docker-java-core/src/main/java/com/github/dockerjava/core/dockerfile/Dockerfile.java @@ -4,10 +4,14 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.UUID; +import java.util.stream.Collectors; +import java.util.stream.Stream; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; @@ -17,7 +21,6 @@ import com.github.dockerjava.core.GoLangFileMatch; import com.github.dockerjava.core.exception.GoLangFileMatchException; import com.github.dockerjava.core.util.CompressArchiveUtil; -import com.github.dockerjava.core.util.FilePathUtil; import com.google.common.base.Function; import com.google.common.base.MoreObjects; import com.google.common.base.Optional; @@ -201,23 +204,42 @@ private void addFilesInDirectory(File directory) { throw new DockerClientException("Failed to read build context directory: " + baseDirectory.getAbsolutePath()); } - if (files.length != 0) { - for (File f : files) { - if (f.isDirectory()) { - addFilesInDirectory(f); - } else if (effectiveMatchingIgnorePattern(f) == null) { - filesToAdd.add(f); - } + try (final Stream pathStream = Files.walk(directory.toPath()) + .parallel() + .filter(this::isNotIgnored) + .map(Path::toFile) + ) { + filesToAdd.addAll(pathStream.collect(Collectors.toList())); + } catch (IOException e) { + throw new DockerClientException("Failed to walk directory", e); + } + + } + + private boolean isNotIgnored(Path path) { + if (Files.isRegularFile(path)) { + return isEffectivelyNotIgnored(path); + } + if (Files.isDirectory(path)) { + try { + return isEmptyDirectory(path) && !isBaseDirectory(path) && isEffectivelyNotIgnored(path); + } catch (IOException e) { + throw new DockerClientException("Failed to list directory", e); } - // base directory should at least contains Dockerfile, but better check - } else if (!isBaseDirectory(directory)) { - // add empty directory - filesToAdd.add(directory); } + return false; } - private boolean isBaseDirectory(File directory) { - return directory.compareTo(baseDirectory) == 0; + private boolean isEmptyDirectory(Path path) throws IOException { + return Files.list(path).count() == 0; + } + + private boolean isEffectivelyNotIgnored(Path path) { + return effectiveMatchingIgnorePattern(path.toFile()) == null; + } + + private boolean isBaseDirectory(Path directory) { + return directory.equals(baseDirectory.toPath()); } /** @@ -249,7 +271,7 @@ private List matchingIgnorePatterns(String fileName) { */ private String effectiveMatchingIgnorePattern(File file) { // normalize path to replace '/' to '\' on Windows - String relativeFilename = FilenameUtils.normalize(FilePathUtil.relativize(baseDirectory, file)); + final String relativeFilename = FilenameUtils.normalize(relativizeToBaseDirectory(file)); List matchingPattern = matchingIgnorePatterns(relativeFilename); @@ -260,6 +282,10 @@ private String effectiveMatchingIgnorePattern(File file) { String lastMatchingPattern = matchingPattern.get(matchingPattern.size() - 1); return !lastMatchingPattern.startsWith("!") ? lastMatchingPattern : null; - } + } + + private String relativizeToBaseDirectory(File file) { + return baseDirectory.toPath().toUri().relativize(file.toPath().toUri()).getPath(); + } } }