summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Goszczurny <szczurmys@o2.pl>2017-07-03 22:22:37 +0200
committerJoffrey F <f.joffrey@gmail.com>2017-08-17 13:38:40 -0700
commitbf9d06db251fc3befbdbe560bc03d2009ce927e7 (patch)
tree9e3d6025cc37a11cd389b8263c7cd8253d2b6303
parent48b5c07c3a7c008befe5349095eee0117ba8e3de (diff)
downloaddocker-py-bf9d06db251fc3befbdbe560bc03d2009ce927e7.tar.gz
Generating regexp from .dockerignore file in a similar way as docker-ce.
Signed-off-by: Jakub Goszczurny <szczurmys@o2.pl>
-rw-r--r--docker/utils/fnmatch.py27
-rw-r--r--tests/unit/utils_test.py25
2 files changed, 44 insertions, 8 deletions
diff --git a/docker/utils/fnmatch.py b/docker/utils/fnmatch.py
index e95b63c..e51bd81 100644
--- a/docker/utils/fnmatch.py
+++ b/docker/utils/fnmatch.py
@@ -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 + '$'
diff --git a/tests/unit/utils_test.py b/tests/unit/utils_test.py
index a2d463d..7045d23 100644
--- a/tests/unit/utils_test.py
+++ b/tests/unit/utils_test.py
@@ -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):