summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docker/utils/build.py2
-rw-r--r--tests/unit/utils_test.py15
2 files changed, 16 insertions, 1 deletions
diff --git a/docker/utils/build.py b/docker/utils/build.py
index 1622ec3..894b299 100644
--- a/docker/utils/build.py
+++ b/docker/utils/build.py
@@ -93,7 +93,7 @@ def walk(root, patterns, default=True):
# Whether this file is implicitely included / excluded.
matched = default if hit is None else hit
sub = list(filter(lambda p: p[1], sub))
- if os.path.isdir(cur):
+ if os.path.isdir(cur) and not os.path.islink(cur):
# Entirely skip directories if there are no chance any subfile will
# be included.
if all(not p[0] for p in sub) and not matched:
diff --git a/tests/unit/utils_test.py b/tests/unit/utils_test.py
index 56800f9..00456e8 100644
--- a/tests/unit/utils_test.py
+++ b/tests/unit/utils_test.py
@@ -1058,6 +1058,21 @@ class TarTest(unittest.TestCase):
assert tar_data.getnames() == ['th.txt']
assert tar_data.getmember('th.txt').mtime == -3600
+ @pytest.mark.skipif(IS_WINDOWS_PLATFORM, reason='No symlinks on Windows')
+ def test_tar_directory_link(self):
+ dirs = ['a', 'b', 'a/c']
+ files = ['a/hello.py', 'b/utils.py', 'a/c/descend.py']
+ base = make_tree(dirs, files)
+ self.addCleanup(shutil.rmtree, base)
+ os.symlink(os.path.join(base, 'b'), os.path.join(base, 'a/c/b'))
+ with tar(base) as archive:
+ tar_data = tarfile.open(fileobj=archive)
+ names = tar_data.getnames()
+ for member in dirs + files:
+ assert member in names
+ assert 'a/c/b' in names
+ assert 'a/c/b/utils.py' not in names
+
class FormatEnvironmentTest(unittest.TestCase):
def test_format_env_binary_unicode_value(self):