X Tutup
Skip to content

Commit 33fdd71

Browse files
author
Marcus Linke
committed
Fix issue #286
1 parent ae107a5 commit 33fdd71

File tree

7 files changed

+88
-21
lines changed

7 files changed

+88
-21
lines changed

src/main/java/com/github/dockerjava/core/GoLangFileMatch.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package com.github.dockerjava.core;
55

66
import java.io.File;
7+
import java.util.ArrayList;
78
import java.util.List;
89

910
import org.apache.commons.lang.StringUtils;
@@ -23,16 +24,16 @@
2324
* character class (must be non-empty)
2425
* c matches character c (c != '*', '?', '\\', '[')
2526
* '\\' c matches character c
26-
*
27+
*
2728
* character-range:
2829
* c matches character c (c != '\\', '-', ']')
2930
* '\\' c matches character c
3031
* lo '-' hi matches character c for lo <= c <= hi
31-
*
32+
*
3233
* Match requires pattern to match all of name, not just a substring.
3334
* The only possible returned error is ErrBadPattern, when pattern
3435
* is malformed.
35-
*
36+
*
3637
* On Windows, escaping is disabled. Instead, '\\' is treated as
3738
* path separator.
3839
* </pre>
@@ -45,20 +46,24 @@ public class GoLangFileMatch {
4546
public static final boolean IS_WINDOWS = File.separatorChar == '\\';
4647

4748
public static boolean match(List<String> patterns, File file) {
48-
return match(patterns, file.getPath());
49+
return !match(patterns, file.getPath()).isEmpty();
4950
}
5051

5152
public static boolean match(String pattern, File file) {
5253
return match(pattern, file.getPath());
5354
}
5455

55-
public static boolean match(List<String> patterns, String name) {
56+
/**
57+
* Returns the matching patterns for the given string
58+
*/
59+
public static List<String> match(List<String> patterns, String name) {
60+
List<String> matches = new ArrayList<String>();
5661
for (String pattern : patterns) {
5762
if (match(pattern, name)) {
58-
return true;
63+
matches.add(pattern);
5964
}
6065
}
61-
return false;
66+
return matches;
6267
}
6368

6469
public static boolean match(String pattern, String name) {

src/main/java/com/github/dockerjava/core/GoLangMatchFileFilter.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ public GoLangMatchFileFilter(File base, List<String> patterns) {
2424
public boolean accept(File file) {
2525
String relativePath = FilePathUtil.relativize(base, file);
2626

27-
boolean match = GoLangFileMatch.match(patterns, relativePath);
28-
return !match;
27+
return GoLangFileMatch.match(patterns, relativePath).isEmpty();
2928
}
3029

3130
}

src/main/java/com/github/dockerjava/core/dockerfile/Dockerfile.java

Lines changed: 61 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import com.google.common.base.Objects;
1111
import com.google.common.base.Optional;
1212
import com.google.common.collect.Collections2;
13+
1314
import org.apache.commons.io.FileUtils;
1415
import org.apache.commons.io.FilenameUtils;
1516
import org.apache.commons.io.IOUtils;
@@ -89,12 +90,6 @@ public List<String> getIgnores() throws IOException {
8990
}
9091
pattern = FilenameUtils.normalize(pattern);
9192
try {
92-
// validate pattern and make sure we aren't excluding Dockerfile
93-
if (GoLangFileMatch.match(pattern, "Dockerfile")) {
94-
throw new DockerClientException(String.format(
95-
"Dockerfile is excluded by pattern '%s' on line %s in .dockerignore file", pattern,
96-
lineNumber));
97-
}
9893
ignores.add(pattern);
9994
} catch (GoLangFileMatchException e) {
10095
throw new DockerClientException(String.format(
@@ -169,7 +164,15 @@ public String toString() {
169164
public ScannedResult() throws IOException {
170165

171166
ignores = getIgnores();
172-
filesToAdd.add(dockerFile);
167+
168+
String matchingIgnorePattern = effectiveMatchingIgnorePattern(dockerFile);
169+
170+
if (matchingIgnorePattern == null) {
171+
filesToAdd.add(dockerFile);
172+
} else {
173+
throw new DockerClientException(String.format(
174+
"Dockerfile is excluded by pattern '%s' in .dockerignore file", matchingIgnorePattern));
175+
}
173176

174177
for (DockerfileStatement statement : getStatements()) {
175178
if (statement instanceof DockerfileStatement.Env) {
@@ -180,6 +183,56 @@ public ScannedResult() throws IOException {
180183
}
181184
}
182185

186+
/**
187+
* Returns all matching ignore patterns for the given file name.
188+
*/
189+
private List<String> matchingIgnorePatterns(String fileName) {
190+
List<String> matches = new ArrayList<String>();
191+
192+
int lineNumber = 0;
193+
for (String pattern : ignores) {
194+
lineNumber++;
195+
try {
196+
if (GoLangFileMatch.match(pattern, fileName)) {
197+
matches.add(pattern);
198+
}
199+
} catch (GoLangFileMatchException e) {
200+
throw new DockerClientException(String.format(
201+
"Invalid pattern '%s' on line %s in .dockerignore file", pattern, lineNumber));
202+
}
203+
}
204+
205+
return matches;
206+
}
207+
208+
/**
209+
* Returns the matching ignore pattern for the given file or null if it should NOT be ignored.
210+
* Exception rules like "!Dockerfile" will be respected.
211+
*/
212+
private String effectiveMatchingIgnorePattern(File file) {
213+
String relativeFilename = FilePathUtil.relativize(getDockerFolder(), file);
214+
215+
List<String> matchingPattern = matchingIgnorePatterns(relativeFilename);
216+
217+
if (matchingPattern.isEmpty())
218+
return null;
219+
220+
String lastMatchingPattern = matchingPattern.get(matchingPattern.size() - 1);
221+
222+
int lastMatchingPatternIndex = ignores.lastIndexOf(lastMatchingPattern);
223+
224+
if(lastMatchingPatternIndex == ignores.size() - 1) return lastMatchingPattern;
225+
226+
List<String> remainingIgnorePattern = ignores.subList(lastMatchingPatternIndex + 1, ignores.size());
227+
228+
for (String ignorePattern : remainingIgnorePattern) {
229+
if (ignorePattern.equals("!" + relativeFilename))
230+
return null;
231+
}
232+
233+
return lastMatchingPattern;
234+
}
235+
183236
private void processAddStatement(DockerfileStatement.Add add) throws IOException {
184237

185238
add = add.transform(environmentMap);
@@ -202,7 +255,7 @@ private void processAddStatement(DockerfileStatement.Add add) throws IOException
202255
Collection<File> files = FileUtils.listFiles(src, new GoLangMatchFileFilter(src, ignores),
203256
TrueFileFilter.INSTANCE);
204257
filesToAdd.addAll(files);
205-
} else if (!GoLangFileMatch.match(ignores, FilePathUtil.relativize(dockerFolder, src))) {
258+
} else if (effectiveMatchingIgnorePattern(src) == null) {
206259
filesToAdd.add(src);
207260
} else {
208261
throw new DockerClientException(String.format(
@@ -234,10 +287,7 @@ private Collection<File> resolveWildcards(File file, List<String> ignores) {
234287
}
235288

236289
private void processEnvStatement(DockerfileStatement.Env env) {
237-
238290
environmentMap.put(env.variable, env.value);
239291
}
240-
241292
}
242-
243293
}

src/main/java/com/github/dockerjava/core/dockerfile/DockerfileStatement.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
/**
2020
* A statement present in a dockerfile.
2121
*/
22-
public abstract class DockerfileStatement<T extends DockerfileStatement> {
22+
public abstract class DockerfileStatement<T extends DockerfileStatement<?>> {
2323

2424
private DockerfileStatement() {
2525
}

src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,14 @@ public void testDockerfileIgnored() throws Exception {
171171
dockerClient.buildImageCmd(baseDir).withNoCache().exec(new BuildImageResultCallback()).awaitImageId();
172172
}
173173

174+
@Test
175+
public void testDockerfileNotIgnored() throws Exception {
176+
File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testDockerfileNotIgnored")
177+
.getFile());
178+
179+
dockerClient.buildImageCmd(baseDir).withNoCache().exec(new BuildImageResultCallback()).awaitImageId();
180+
}
181+
174182
@Test(expectedExceptions = { DockerClientException.class })
175183
public void testInvalidDockerIgnorePattern() throws Exception {
176184
File baseDir = new File(Thread.currentThread().getContextClassLoader()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*
2+
!Dockerfile
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
FROM ubuntu:latest
2+
3+
CMD ["echo", "Success"]

0 commit comments

Comments
 (0)
X Tutup