diff --git a/docker/utils/utils.py b/docker/utils/utils.py index 4404c217..61e5a8dc 100644 --- a/docker/utils/utils.py +++ b/docker/utils/utils.py @@ -128,7 +128,13 @@ def exclude_paths(root, patterns, dockerfile=None): paths = get_paths(root, exclude_patterns, include_patterns, has_exceptions=len(exceptions) > 0) - return set(paths) + return set(paths).union( + # If the Dockerfile is in a subdirectory that is excluded, get_paths + # will not descend into it and the file will be skipped. This ensures + # it doesn't happen. + set([dockerfile]) + if os.path.exists(os.path.join(root, dockerfile)) else set() + ) def should_include(path, exclude_patterns, include_patterns): diff --git a/tests/unit/utils_test.py b/tests/unit/utils_test.py index df29b9d3..a0a96bbe 100644 --- a/tests/unit/utils_test.py +++ b/tests/unit/utils_test.py @@ -736,6 +736,7 @@ class ExcludePathsTest(base.BaseTestCase): 'foo/b.py', 'foo/bar/a.py', 'bar/a.py', + 'foo/Dockerfile3', ] all_paths = set(dirs + files) @@ -775,6 +776,14 @@ class ExcludePathsTest(base.BaseTestCase): assert self.exclude(['*'], dockerfile='Dockerfile.alt') == \ set(['Dockerfile.alt', '.dockerignore']) + assert self.exclude(['*'], dockerfile='foo/Dockerfile3') == \ + set(['foo/Dockerfile3', '.dockerignore']) + + def test_exclude_dockerfile_child(self): + includes = self.exclude(['foo/'], dockerfile='foo/Dockerfile3') + assert 'foo/Dockerfile3' in includes + assert 'foo/a.py' not in includes + def test_single_filename(self): assert self.exclude(['a.py']) == self.all_paths - set(['a.py']) @@ -825,28 +834,31 @@ class ExcludePathsTest(base.BaseTestCase): def test_directory(self): assert self.exclude(['foo']) == self.all_paths - set([ 'foo', 'foo/a.py', 'foo/b.py', - 'foo/bar', 'foo/bar/a.py', + 'foo/bar', 'foo/bar/a.py', 'foo/Dockerfile3' ]) def test_directory_with_trailing_slash(self): assert self.exclude(['foo']) == self.all_paths - set([ 'foo', 'foo/a.py', 'foo/b.py', - 'foo/bar', 'foo/bar/a.py', + 'foo/bar', 'foo/bar/a.py', 'foo/Dockerfile3' ]) def test_directory_with_single_exception(self): assert self.exclude(['foo', '!foo/bar/a.py']) == self.all_paths - set([ - 'foo/a.py', 'foo/b.py', 'foo', 'foo/bar' + 'foo/a.py', 'foo/b.py', 'foo', 'foo/bar', + 'foo/Dockerfile3' ]) def test_directory_with_subdir_exception(self): assert self.exclude(['foo', '!foo/bar']) == self.all_paths - set([ - 'foo/a.py', 'foo/b.py', 'foo' + 'foo/a.py', 'foo/b.py', 'foo', + 'foo/Dockerfile3' ]) def test_directory_with_wildcard_exception(self): assert self.exclude(['foo', '!foo/*.py']) == self.all_paths - set([ - 'foo/bar', 'foo/bar/a.py', 'foo' + 'foo/bar', 'foo/bar/a.py', 'foo', + 'foo/Dockerfile3' ]) def test_subdirectory(self):