1010import com .google .common .base .Objects ;
1111import com .google .common .base .Optional ;
1212import com .google .common .collect .Collections2 ;
13+
1314import org .apache .commons .io .FileUtils ;
1415import org .apache .commons .io .FilenameUtils ;
1516import 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}
0 commit comments