Skip to content

Commit bf9d06d

Browse files
Jakub Goszczurnyshin-
authored andcommitted
Generating regexp from .dockerignore file in a similar way as docker-ce.
Signed-off-by: Jakub Goszczurny <[email protected]>
1 parent 48b5c07 commit bf9d06d

File tree

2 files changed

+44
-8
lines changed

2 files changed

+44
-8
lines changed

docker/utils/fnmatch.py

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,19 +65,32 @@ def translate(pat):
6565
6666
There is no way to quote meta-characters.
6767
"""
68-
recursive_mode = False
6968
i, n = 0, len(pat)
70-
res = ''
69+
res = '^'
7170
while i < n:
7271
c = pat[i]
7372
i = i + 1
7473
if c == '*':
7574
if i < n and pat[i] == '*':
76-
recursive_mode = True
75+
# is some flavor of "**"
7776
i = i + 1
78-
res = res + '.*'
77+
# Treat **/ as ** so eat the "/"
78+
if pat[i] == '/':
79+
i = i + 1
80+
if i >= n:
81+
# is "**EOF" - to align with .gitignore just accept all
82+
res = res + '.*'
83+
else:
84+
# is "**"
85+
# Note that this allows for any # of /'s (even 0) because
86+
# the .* will eat everything, even /'s
87+
res = res + '(.*/)?'
88+
else:
89+
# is "*" so map it to anything but "/"
90+
res = res + '[^/]*'
7991
elif c == '?':
80-
res = res + '.'
92+
# "?" is any char except "/"
93+
res = res + '[^/]'
8194
elif c == '[':
8295
j = i
8396
if j < n and pat[j] == '!':
@@ -96,8 +109,6 @@ def translate(pat):
96109
elif stuff[0] == '^':
97110
stuff = '\\' + stuff
98111
res = '%s[%s]' % (res, stuff)
99-
elif recursive_mode and c == '/':
100-
res = res + re.escape(c) + '?'
101112
else:
102113
res = res + re.escape(c)
103-
return res + '\Z(?ms)'
114+
return res + '$'

tests/unit/utils_test.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,14 @@ class ExcludePathsTest(unittest.TestCase):
639639
'foo',
640640
'foo/bar',
641641
'bar',
642+
'target',
643+
'target/subdir',
644+
'subdir',
645+
'subdir/target',
646+
'subdir/target/subdir',
647+
'subdir/subdir2',
648+
'subdir/subdir2/target',
649+
'subdir/subdir2/target/subdir'
642650
]
643651

644652
files = [
@@ -654,6 +662,14 @@ class ExcludePathsTest(unittest.TestCase):
654662
'foo/bar/a.py',
655663
'bar/a.py',
656664
'foo/Dockerfile3',
665+
'target/file.txt',
666+
'target/subdir/file.txt',
667+
'subdir/file.txt',
668+
'subdir/target/file.txt',
669+
'subdir/target/subdir/file.txt',
670+
'subdir/subdir2/file.txt',
671+
'subdir/subdir2/target/file.txt',
672+
'subdir/subdir2/target/subdir/file.txt',
657673
]
658674

659675
all_paths = set(dirs + files)
@@ -844,6 +860,15 @@ def test_double_wildcard(self):
844860
self.all_paths - set(['foo/bar', 'foo/bar/a.py'])
845861
)
846862

863+
def test_single_and_double_wildcard(self):
864+
assert self.exclude(['**/target/*/*']) == convert_paths(
865+
self.all_paths - set(
866+
['target/subdir/file.txt',
867+
'subdir/target/subdir/file.txt',
868+
'subdir/subdir2/target/subdir/file.txt']
869+
)
870+
)
871+
847872

848873
class TarTest(unittest.TestCase):
849874
def test_tar_with_excludes(self):

0 commit comments

Comments
 (0)