From 15c8a6323f98a04c68cc2050e2754583055758e8 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Sun, 14 Dec 2014 19:15:54 +0100 Subject: [PATCH] Normalize source/exclude paths before matching This normalizes the file names in the dot directory when specified explicitly, along with exclude/include patterns. This fixes several mismatches when including relative paths that involve the current directory. --- attic/archiver.py | 3 ++- attic/helpers.py | 6 +++--- attic/testsuite/archiver.py | 19 +++++++++++++++++++ 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/attic/archiver.py b/attic/archiver.py index 47650c2d..3f579e0e 100644 --- a/attic/archiver.py +++ b/attic/archiver.py @@ -173,8 +173,9 @@ def _process(self, archive, cache, excludes, exclude_caches, skip_inodes, path, self.print_error('%s: %s', path, e) else: for filename in sorted(entries): + entry_path = os.path.normpath(os.path.join(path, filename)) self._process(archive, cache, excludes, exclude_caches, skip_inodes, - os.path.join(path, filename), restrict_dev) + entry_path, restrict_dev) elif stat.S_ISLNK(st.st_mode): archive.process_symlink(path, st) elif stat.S_ISFIFO(st.st_mode): diff --git a/attic/helpers.py b/attic/helpers.py index ac526698..9fadbd1d 100644 --- a/attic/helpers.py +++ b/attic/helpers.py @@ -228,7 +228,7 @@ class IncludePattern: path match as well. A trailing slash makes no difference. """ def __init__(self, pattern): - self.pattern = pattern.rstrip(os.path.sep)+os.path.sep + self.pattern = os.path.normpath(pattern).rstrip(os.path.sep)+os.path.sep def match(self, path): return (path+os.path.sep).startswith(self.pattern) @@ -243,9 +243,9 @@ class ExcludePattern(IncludePattern): """ def __init__(self, pattern): if pattern.endswith(os.path.sep): - self.pattern = pattern+'*'+os.path.sep + self.pattern = os.path.normpath(pattern).rstrip(os.path.sep)+os.path.sep+'*'+os.path.sep else: - self.pattern = pattern+os.path.sep+'*' + self.pattern = os.path.normpath(pattern)+os.path.sep+'*' # fnmatch and re.match both cache compiled regular expressions. # Nevertheless, this is about 10 times faster. self.regex = re.compile(translate(self.pattern)) diff --git a/attic/testsuite/archiver.py b/attic/testsuite/archiver.py index 382fcc85..160b3624 100644 --- a/attic/testsuite/archiver.py +++ b/attic/testsuite/archiver.py @@ -217,6 +217,25 @@ def test_path_normalization(self): self.assert_not_in('..', output) self.assert_in(' input/dir1/dir2/file', output) + def test_exclude_normalization(self): + self.attic('init', self.repository_location) + self.create_regular_file('file1', size=1024 * 80) + self.create_regular_file('file2', size=1024 * 80) + with changedir('input'): + self.attic('create', '--exclude=file1', self.repository_location + '::test1', '.') + with changedir('output'): + self.attic('extract', self.repository_location + '::test1') + self.assert_equal(sorted(os.listdir('output')), ['file2']) + with changedir('input'): + self.attic('create', '--exclude=./file1', self.repository_location + '::test2', '.') + with changedir('output'): + self.attic('extract', self.repository_location + '::test2') + self.assert_equal(sorted(os.listdir('output')), ['file2']) + self.attic('create', '--exclude=input/./file1', self.repository_location + '::test3', 'input') + with changedir('output'): + self.attic('extract', self.repository_location + '::test3') + self.assert_equal(sorted(os.listdir('output/input')), ['file2']) + def test_repeated_files(self): self.create_regular_file('file1', size=1024 * 80) self.attic('init', self.repository_location)