Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions attic/archiver.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
from attic.cache import Cache
from attic.key import key_creator
from attic.helpers import Error, location_validator, format_time, \
format_file_mode, ExcludePattern, exclude_path, adjust_patterns, to_localtime, \
get_cache_dir, get_keys_dir, format_timedelta, prune_within, prune_split, \
format_file_mode, ExcludePattern, exclude_path, adjust_include_patterns, adjust_exclude_patterns, \
to_localtime, get_cache_dir, get_keys_dir, format_timedelta, prune_within, prune_split, \
Manifest, remove_surrogates, update_excludes, format_archive, check_extension_modules, Statistics, \
is_cachedir, bigint_to_int
from attic.remote import RepositoryServer, RemoteRepository
Expand Down Expand Up @@ -125,7 +125,8 @@ def do_create(self, args):
continue
else:
restrict_dev = None
self._process(archive, cache, args.excludes, args.exclude_caches, skip_inodes, path, restrict_dev)
excludes = adjust_exclude_patterns(path, args.excludes)
self._process(archive, cache, excludes, args.exclude_caches, skip_inodes, path, restrict_dev)
archive.save()
if args.stats:
t = datetime.now()
Expand Down Expand Up @@ -192,7 +193,7 @@ def do_extract(self, args):
manifest, key = Manifest.load(repository)
archive = Archive(repository, key, manifest, args.archive.archive,
numeric_owner=args.numeric_owner)
patterns = adjust_patterns(args.paths, args.excludes)
patterns = adjust_include_patterns(args.paths, args.excludes)
dry_run = args.dry_run
strip_components = args.strip_components
dirs = []
Expand Down
10 changes: 8 additions & 2 deletions attic/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,13 +198,20 @@ def update_excludes(args):
file.close()


def adjust_patterns(paths, excludes):
def adjust_include_patterns(paths, excludes):
if paths:
return (excludes or []) + [IncludePattern(path) for path in paths] + [ExcludePattern('*')]
else:
return excludes


def adjust_exclude_patterns(path, excludes):
if excludes:
return [pattern for pattern in excludes if not pattern.match(path)]
else:
return []


def exclude_path(path, patterns):
"""Used by create and extract sub-commands to determine
whether or not an item should be processed.
Expand Down Expand Up @@ -566,4 +573,3 @@ def int_to_bigint(value):
if value.bit_length() > 63:
return value.to_bytes((value.bit_length() + 9) // 8, 'little', signed=True)
return value

11 changes: 11 additions & 0 deletions attic/testsuite/archiver.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,17 @@ def test_extract_include_exclude(self):
self.attic('extract', '--exclude-from=' + self.exclude_file_path, self.repository_location + '::test')
self.assert_equal(sorted(os.listdir('output/input')), ['file1', 'file3'])

def test_subtree_include_exclude(self):
self.attic('init', self.repository_location)
self.create_regular_file('file1', size=1024 * 80)
self.create_regular_file('unwanted/file2', size=1024 * 80)
self.create_regular_file('unwanted/wanted/file3', size=1024 * 80)
self.attic('create', '--exclude=input/unwanted', self.repository_location + '::test', 'input', 'input/unwanted/wanted')
with changedir('output'):
self.attic('extract', self.repository_location + '::test', 'input')
self.assert_equal(sorted(os.listdir('output/input')), ['file1', 'unwanted'])
self.assert_equal(sorted(os.listdir('output/input/unwanted')), ['wanted'])

def test_exclude_caches(self):
self.attic('init', self.repository_location)
self.create_regular_file('file1', size=1024 * 80)
Expand Down
4 changes: 2 additions & 2 deletions attic/testsuite/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import os
import tempfile
import unittest
from attic.helpers import adjust_patterns, exclude_path, Location, format_timedelta, IncludePattern, ExcludePattern, make_path_safe, UpgradableLock, prune_within, prune_split, to_localtime, \
from attic.helpers import adjust_include_patterns, exclude_path, Location, format_timedelta, IncludePattern, ExcludePattern, make_path_safe, UpgradableLock, prune_within, prune_split, to_localtime, \
StableDict, int_to_bigint, bigint_to_int
from attic.testsuite import AtticTestCase
import msgpack
Expand Down Expand Up @@ -73,7 +73,7 @@ class PatternTestCase(AtticTestCase):
]

def evaluate(self, paths, excludes):
patterns = adjust_patterns(paths, [ExcludePattern(p) for p in excludes])
patterns = adjust_include_patterns(paths, [ExcludePattern(p) for p in excludes])
return [path for path in self.files if not exclude_path(path, patterns)]

def test(self):
Expand Down