Generating regexp from .dockerignore file in a similar way as docker-ce.

Signed-off-by: Jakub Goszczurny <szczurmys@o2.pl>
This commit is contained in:
Jakub Goszczurny 2017-07-03 22:22:37 +02:00 committed by Joffrey F
parent c2925a384b
commit d798afca7e
2 changed files with 44 additions and 8 deletions

View File

@ -65,19 +65,32 @@ def translate(pat):
There is no way to quote meta-characters.
"""
recursive_mode = False
i, n = 0, len(pat)
res = ''
res = '^'
while i < n:
c = pat[i]
i = i + 1
if c == '*':
if i < n and pat[i] == '*':
recursive_mode = True
# is some flavor of "**"
i = i + 1
res = res + '.*'
# Treat **/ as ** so eat the "/"
if pat[i] == '/':
i = i + 1
if i >= n:
# is "**EOF" - to align with .gitignore just accept all
res = res + '.*'
else:
# is "**"
# Note that this allows for any # of /'s (even 0) because
# the .* will eat everything, even /'s
res = res + '(.*/)?'
else:
# is "*" so map it to anything but "/"
res = res + '[^/]*'
elif c == '?':
res = res + '.'
# "?" is any char except "/"
res = res + '[^/]'
elif c == '[':
j = i
if j < n and pat[j] == '!':
@ -96,8 +109,6 @@ def translate(pat):
elif stuff[0] == '^':
stuff = '\\' + stuff
res = '%s[%s]' % (res, stuff)
elif recursive_mode and c == '/':
res = res + re.escape(c) + '?'
else:
res = res + re.escape(c)
return res + '\Z(?ms)'
return res + '$'

View File

@ -639,6 +639,14 @@ class ExcludePathsTest(unittest.TestCase):
'foo',
'foo/bar',
'bar',
'target',
'target/subdir',
'subdir',
'subdir/target',
'subdir/target/subdir',
'subdir/subdir2',
'subdir/subdir2/target',
'subdir/subdir2/target/subdir'
]
files = [
@ -654,6 +662,14 @@ class ExcludePathsTest(unittest.TestCase):
'foo/bar/a.py',
'bar/a.py',
'foo/Dockerfile3',
'target/file.txt',
'target/subdir/file.txt',
'subdir/file.txt',
'subdir/target/file.txt',
'subdir/target/subdir/file.txt',
'subdir/subdir2/file.txt',
'subdir/subdir2/target/file.txt',
'subdir/subdir2/target/subdir/file.txt',
]
all_paths = set(dirs + files)
@ -844,6 +860,15 @@ class ExcludePathsTest(unittest.TestCase):
self.all_paths - set(['foo/bar', 'foo/bar/a.py'])
)
def test_single_and_double_wildcard(self):
assert self.exclude(['**/target/*/*']) == convert_paths(
self.all_paths - set(
['target/subdir/file.txt',
'subdir/target/subdir/file.txt',
'subdir/subdir2/target/subdir/file.txt']
)
)
class TarTest(unittest.TestCase):
def test_tar_with_excludes(self):