Skip to content

Commit 9e75609

Browse files
authored
Merge pull request #1904 from docker/c5672-dockerignore-abspath
Correctly support absolute paths in .dockerignore
2 parents 7c19772 + 34d5048 commit 9e75609

File tree

2 files changed

+30
-17
lines changed

2 files changed

+30
-17
lines changed

docker/utils/build.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def exclude_paths(root, patterns, dockerfile=None):
4646
)
4747

4848

49-
def should_include(path, exclude_patterns, include_patterns):
49+
def should_include(path, exclude_patterns, include_patterns, root):
5050
"""
5151
Given a path, a list of exclude patterns, and a list of inclusion patterns:
5252
@@ -61,11 +61,15 @@ def should_include(path, exclude_patterns, include_patterns):
6161
for pattern in include_patterns:
6262
if match_path(path, pattern):
6363
return True
64+
if os.path.isabs(pattern) and match_path(
65+
os.path.join(root, path), pattern):
66+
return True
6467
return False
6568
return True
6669

6770

68-
def should_check_directory(directory_path, exclude_patterns, include_patterns):
71+
def should_check_directory(directory_path, exclude_patterns, include_patterns,
72+
root):
6973
"""
7074
Given a directory path, a list of exclude patterns, and a list of inclusion
7175
patterns:
@@ -91,7 +95,7 @@ def normalize_path(path):
9195
if (pattern + '/').startswith(path_with_slash)
9296
]
9397
directory_included = should_include(
94-
directory_path, exclude_patterns, include_patterns
98+
directory_path, exclude_patterns, include_patterns, root
9599
)
96100
return directory_included or len(possible_child_patterns) > 0
97101

@@ -110,26 +114,28 @@ def get_paths(root, exclude_patterns, include_patterns, has_exceptions=False):
110114
# traversal. See https://docs.python.org/2/library/os.html#os.walk
111115
dirs[:] = [
112116
d for d in dirs if should_check_directory(
113-
os.path.join(parent, d), exclude_patterns, include_patterns
117+
os.path.join(parent, d), exclude_patterns, include_patterns,
118+
root
114119
)
115120
]
116121

117122
for path in dirs:
118123
if should_include(os.path.join(parent, path),
119-
exclude_patterns, include_patterns):
124+
exclude_patterns, include_patterns, root):
120125
paths.append(os.path.join(parent, path))
121126

122127
for path in files:
123128
if should_include(os.path.join(parent, path),
124-
exclude_patterns, include_patterns):
129+
exclude_patterns, include_patterns, root):
125130
paths.append(os.path.join(parent, path))
126131

127132
return paths
128133

129134

130135
def match_path(path, pattern):
136+
131137
pattern = pattern.rstrip('/' + os.path.sep)
132-
if pattern:
138+
if pattern and not os.path.isabs(pattern):
133139
pattern = os.path.relpath(pattern)
134140

135141
pattern_components = pattern.split(os.path.sep)

tests/unit/utils_test.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,13 @@ def test_trailing_double_wildcard(self):
876876
)
877877
)
878878

879+
def test_exclude_include_absolute_path(self):
880+
base = make_tree([], ['a.py', 'b.py'])
881+
assert exclude_paths(
882+
base,
883+
['/*', '!' + os.path.join(base, '*.py')]
884+
) == set(['a.py', 'b.py'])
885+
879886

880887
class TarTest(unittest.TestCase):
881888
def test_tar_with_excludes(self):
@@ -1026,52 +1033,52 @@ class ShouldCheckDirectoryTest(unittest.TestCase):
10261033

10271034
def test_should_check_directory_not_excluded(self):
10281035
assert should_check_directory(
1029-
'not_excluded', self.exclude_patterns, self.include_patterns
1036+
'not_excluded', self.exclude_patterns, self.include_patterns, '.'
10301037
)
10311038
assert should_check_directory(
10321039
convert_path('dir/with'), self.exclude_patterns,
1033-
self.include_patterns
1040+
self.include_patterns, '.'
10341041
)
10351042

10361043
def test_shoud_check_parent_directories_of_excluded(self):
10371044
assert should_check_directory(
1038-
'dir', self.exclude_patterns, self.include_patterns
1045+
'dir', self.exclude_patterns, self.include_patterns, '.'
10391046
)
10401047
assert should_check_directory(
10411048
convert_path('dir/with'), self.exclude_patterns,
1042-
self.include_patterns
1049+
self.include_patterns, '.'
10431050
)
10441051

10451052
def test_should_not_check_excluded_directories_with_no_exceptions(self):
10461053
assert not should_check_directory(
10471054
'exclude_rather_large_directory', self.exclude_patterns,
1048-
self.include_patterns
1055+
self.include_patterns, '.'
10491056
)
10501057
assert not should_check_directory(
10511058
convert_path('dir/with/subdir_excluded'), self.exclude_patterns,
1052-
self.include_patterns
1059+
self.include_patterns, '.'
10531060
)
10541061

10551062
def test_should_check_excluded_directory_with_exceptions(self):
10561063
assert should_check_directory(
10571064
convert_path('dir/with/exceptions'), self.exclude_patterns,
1058-
self.include_patterns
1065+
self.include_patterns, '.'
10591066
)
10601067
assert should_check_directory(
10611068
convert_path('dir/with/exceptions/in'), self.exclude_patterns,
1062-
self.include_patterns
1069+
self.include_patterns, '.'
10631070
)
10641071

10651072
def test_should_not_check_siblings_of_exceptions(self):
10661073
assert not should_check_directory(
10671074
convert_path('dir/with/exceptions/but_not_here'),
1068-
self.exclude_patterns, self.include_patterns
1075+
self.exclude_patterns, self.include_patterns, '.'
10691076
)
10701077

10711078
def test_should_check_subdirectories_of_exceptions(self):
10721079
assert should_check_directory(
10731080
convert_path('dir/with/exceptions/like_this_one/subdir'),
1074-
self.exclude_patterns, self.include_patterns
1081+
self.exclude_patterns, self.include_patterns, '.'
10751082
)
10761083

10771084

0 commit comments

Comments
 (0)