Skip to content

Commit f61e22c

Browse files
committed
Implement --keep-tag-files to preserve directory roots/tag-files
We also add --keep-tag-files to keep in the archive the root directory and the tag/exclusion file in the archive.
1 parent 3462a9c commit f61e22c

3 files changed

Lines changed: 32 additions & 9 deletions

File tree

attic/archiver.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,8 @@ def do_create(self, args):
125125
continue
126126
else:
127127
restrict_dev = None
128-
self._process(archive, cache, args.excludes, args.exclude_caches,
129-
args.exclude_if_present, skip_inodes, path, restrict_dev)
128+
self._process(archive, cache, args.excludes, args.exclude_caches, args.exclude_if_present,
129+
args.keep_tag_files, skip_inodes, path, restrict_dev)
130130
archive.save()
131131
if args.stats:
132132
t = datetime.now()
@@ -143,7 +143,7 @@ def do_create(self, args):
143143
return self.exit_code
144144

145145
def _process(self, archive, cache, excludes, exclude_caches, exclude_if_present,
146-
skip_inodes, path, restrict_dev):
146+
keep_tag_files, skip_inodes, path, restrict_dev):
147147
if exclude_path(path, excludes):
148148
return
149149
try:
@@ -166,7 +166,11 @@ def _process(self, archive, cache, excludes, exclude_caches, exclude_if_present,
166166
except IOError as e:
167167
self.print_error('%s: %s', path, e)
168168
elif stat.S_ISDIR(st.st_mode):
169-
if dir_is_tagged(path, exclude_caches, exclude_if_present):
169+
tag_path = dir_is_tagged(path, exclude_caches, exclude_if_present)
170+
if tag_path:
171+
if keep_tag_files:
172+
archive.process_item(path, st)
173+
archive.process_item(tag_path, st)
170174
return
171175
archive.process_item(path, st)
172176
try:
@@ -176,7 +180,7 @@ def _process(self, archive, cache, excludes, exclude_caches, exclude_if_present,
176180
else:
177181
for filename in sorted(entries):
178182
self._process(archive, cache, excludes, exclude_caches, exclude_if_present,
179-
skip_inodes, os.path.join(path, filename), restrict_dev)
183+
keep_tag_files, skip_inodes, os.path.join(path, filename), restrict_dev)
180184
elif stat.S_ISLNK(st.st_mode):
181185
archive.process_symlink(path, st)
182186
elif stat.S_ISFIFO(st.st_mode):
@@ -546,6 +550,9 @@ def run(self, args=None):
546550
subparser.add_argument('--exclude-if-present', dest='exclude_if_present',
547551
metavar='FILENAME', action='append', type=str,
548552
help='exclude directories that contain the specified file')
553+
subparser.add_argument('--keep-tag-files', dest='keep_tag_files',
554+
action='store_true', default=False,
555+
help='keep tag files of excluded caches/directories')
549556
subparser.add_argument('-c', '--checkpoint-interval', dest='checkpoint_interval',
550557
type=int, default=300, metavar='SECONDS',
551558
help='write checkpoint every SECONDS seconds (Default: 300)')

attic/helpers.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -279,16 +279,18 @@ def dir_is_cachedir(path):
279279

280280
def dir_is_tagged(path, exclude_caches, exclude_if_present):
281281
"""Determines whether the specified path is excluded by being a cache
282-
directory or containing the user-specified tag file.
282+
directory or containing the user-specified tag file. Returns the
283+
path of the tag file (either CACHEDIR.TAG or the matching
284+
user-specified file)
283285
"""
284286
if exclude_caches and dir_is_cachedir(path):
285-
return True
287+
return os.path.join(path, 'CACHEDIR.TAG')
286288
if exclude_if_present is not None:
287289
for tag in exclude_if_present:
288290
tag_path = os.path.join(path, tag)
289291
if os.path.isfile(tag_path):
290-
return True
291-
return False
292+
return tag_path
293+
return None
292294

293295

294296
def format_time(t):

attic/testsuite/archiver.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,20 @@ def test_exclude_tagged(self):
219219
self.attic('extract', self.repository_location + '::test')
220220
self.assert_equal(sorted(os.listdir('output/input')), ['file1', 'tagged3'])
221221

222+
def test_exclude_keep_tagged(self):
223+
self.attic('init', self.repository_location)
224+
self.create_regular_file('file1', size=1024 * 80)
225+
self.create_regular_file('tagged1/.NOBACKUP')
226+
self.create_regular_file('tagged1/file2', size=1024 * 80)
227+
self.create_regular_file('tagged2/CACHEDIR.TAG', contents = b'Signature: 8a477f597d28d172789f06886806bc55 extra stuff')
228+
self.create_regular_file('tagged2/file3', size=1024 * 80)
229+
self.attic('create', '--exclude-if-present', '.NOBACKUP', '--exclude-caches', '--keep-tag-files', self.repository_location + '::test', 'input')
230+
with changedir('output'):
231+
self.attic('extract', self.repository_location + '::test')
232+
self.assert_equal(sorted(os.listdir('output/input')), ['file1', 'tagged1', 'tagged2'])
233+
self.assert_equal(sorted(os.listdir('output/input/tagged1')), ['.NOBACKUP'])
234+
self.assert_equal(sorted(os.listdir('output/input/tagged2')), ['CACHEDIR.TAG'])
235+
222236
def test_path_normalization(self):
223237
self.attic('init', self.repository_location)
224238
self.create_regular_file('dir1/dir2/file', size=1024 * 80)

0 commit comments

Comments
 (0)