Skip to content

Commit 85d3474

Browse files
committed
Accept / as a path separator in dockerignore patterns on all platforms
Signed-off-by: Joffrey F <[email protected]>
1 parent dbed962 commit 85d3474

File tree

2 files changed

+35
-9
lines changed

2 files changed

+35
-9
lines changed

docker/utils/utils.py

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -175,11 +175,17 @@ def should_check_directory(directory_path, exclude_patterns, include_patterns):
175175
# docker logic (2016-10-27):
176176
# https://github.com/docker/docker/blob/bc52939b0455116ab8e0da67869ec81c1a1c3e2c/pkg/archive/archive.go#L640-L671
177177

178-
path_with_slash = directory_path + os.sep
179-
possible_child_patterns = [pattern for pattern in include_patterns if
180-
(pattern + os.sep).startswith(path_with_slash)]
181-
directory_included = should_include(directory_path, exclude_patterns,
182-
include_patterns)
178+
def normalize_path(path):
179+
return path.replace(os.path.sep, '/')
180+
181+
path_with_slash = normalize_path(directory_path) + '/'
182+
possible_child_patterns = [
183+
pattern for pattern in map(normalize_path, include_patterns)
184+
if (pattern + '/').startswith(path_with_slash)
185+
]
186+
directory_included = should_include(
187+
directory_path, exclude_patterns, include_patterns
188+
)
183189
return directory_included or len(possible_child_patterns) > 0
184190

185191

@@ -195,9 +201,11 @@ def get_paths(root, exclude_patterns, include_patterns, has_exceptions=False):
195201
# by mutating the dirs we're iterating over.
196202
# This looks strange, but is considered the correct way to skip
197203
# traversal. See https://docs.python.org/2/library/os.html#os.walk
198-
dirs[:] = [d for d in dirs if
199-
should_check_directory(os.path.join(parent, d),
200-
exclude_patterns, include_patterns)]
204+
dirs[:] = [
205+
d for d in dirs if should_check_directory(
206+
os.path.join(parent, d), exclude_patterns, include_patterns
207+
)
208+
]
201209

202210
for path in dirs:
203211
if should_include(os.path.join(parent, path),
@@ -213,7 +221,7 @@ def get_paths(root, exclude_patterns, include_patterns, has_exceptions=False):
213221

214222

215223
def match_path(path, pattern):
216-
pattern = pattern.rstrip('/')
224+
pattern = pattern.rstrip('/' + os.path.sep)
217225
if pattern:
218226
pattern = os.path.relpath(pattern)
219227

tests/unit/utils_test.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,16 @@ def test_directory_with_subdir_exception(self):
780780
])
781781
)
782782

783+
@pytest.mark.skipif(
784+
not IS_WINDOWS_PLATFORM, reason='Backslash patterns only on Windows'
785+
)
786+
def test_directory_with_subdir_exception_win32_pathsep(self):
787+
assert self.exclude(['foo', '!foo\\bar']) == convert_paths(
788+
self.all_paths - set([
789+
'foo/a.py', 'foo/b.py', 'foo', 'foo/Dockerfile3'
790+
])
791+
)
792+
783793
def test_directory_with_wildcard_exception(self):
784794
assert self.exclude(['foo', '!foo/*.py']) == convert_paths(
785795
self.all_paths - set([
@@ -792,6 +802,14 @@ def test_subdirectory(self):
792802
self.all_paths - set(['foo/bar', 'foo/bar/a.py'])
793803
)
794804

805+
@pytest.mark.skipif(
806+
not IS_WINDOWS_PLATFORM, reason='Backslash patterns only on Windows'
807+
)
808+
def test_subdirectory_win32_pathsep(self):
809+
assert self.exclude(['foo\\bar']) == convert_paths(
810+
self.all_paths - set(['foo/bar', 'foo/bar/a.py'])
811+
)
812+
795813

796814
class TarTest(unittest.TestCase):
797815
def test_tar_with_excludes(self):

0 commit comments

Comments
 (0)