mirror of
https://github.com/borgbackup/borg.git
synced 2025-02-25 15:33:39 +00:00
Experimental --include/exclude support
This commit is contained in:
parent
9f6d2284c3
commit
6fe6812df2
3 changed files with 66 additions and 2 deletions
|
@ -8,7 +8,8 @@
|
|||
from .store import Store
|
||||
from .cache import Cache
|
||||
from .keychain import Keychain
|
||||
from .helpers import location_validator, format_file_size, format_time, format_file_mode, walk_dir
|
||||
from .helpers import location_validator, format_file_size, format_time,\
|
||||
format_file_mode, walk_dir, IncludePattern, ExcludePattern, exclude_path
|
||||
|
||||
|
||||
class Archiver(object):
|
||||
|
@ -50,6 +51,8 @@ def do_create(self, args):
|
|||
cache = Cache(store, keychain)
|
||||
for path in args.paths:
|
||||
for path, st in walk_dir(unicode(path)):
|
||||
if exclude_path(path, args.patterns):
|
||||
continue
|
||||
self.print_verbose(path)
|
||||
if stat.S_ISDIR(st.st_mode):
|
||||
archive.process_dir(path, st)
|
||||
|
@ -75,6 +78,8 @@ def do_extract(self, args):
|
|||
archive.get_items()
|
||||
dirs = []
|
||||
for item in archive.items:
|
||||
if exclude_path(item['path'], args.patterns):
|
||||
continue
|
||||
self.print_verbose(item['path'])
|
||||
archive.extract_item(item, args.dest)
|
||||
if stat.S_ISDIR(item['mode']):
|
||||
|
@ -186,6 +191,12 @@ def run(self, args=None):
|
|||
|
||||
subparser = subparsers.add_parser('create')
|
||||
subparser.set_defaults(func=self.do_create)
|
||||
subparser.add_argument('-i', '--include', dest='patterns',
|
||||
type=IncludePattern, action='append',
|
||||
help='Include condition')
|
||||
subparser.add_argument('-e', '--exclude', dest='patterns',
|
||||
type=ExcludePattern, action='append',
|
||||
help='Include condition')
|
||||
subparser.add_argument('archive', metavar='ARCHIVE',
|
||||
type=location_validator(archive=True),
|
||||
help='Archive to create')
|
||||
|
@ -194,6 +205,12 @@ def run(self, args=None):
|
|||
|
||||
subparser = subparsers.add_parser('extract')
|
||||
subparser.set_defaults(func=self.do_extract)
|
||||
subparser.add_argument('-i', '--include', dest='patterns',
|
||||
type=IncludePattern, action='append',
|
||||
help='Include condition')
|
||||
subparser.add_argument('-e', '--exclude', dest='patterns',
|
||||
type=ExcludePattern, action='append',
|
||||
help='Include condition')
|
||||
subparser.add_argument('archive', metavar='ARCHIVE',
|
||||
type=location_validator(archive=True),
|
||||
help='Archive to create')
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import argparse
|
||||
from datetime import datetime
|
||||
from fnmatch import fnmatchcase
|
||||
import grp
|
||||
import os
|
||||
import pwd
|
||||
|
@ -7,6 +8,50 @@
|
|||
import stat
|
||||
|
||||
|
||||
def exclude_path(path, patterns):
|
||||
"""Used by create and extract sub-commands to determine
|
||||
if an item should be processed or not
|
||||
"""
|
||||
for pattern in (patterns or []):
|
||||
if pattern.match(path):
|
||||
return isinstance(pattern, ExcludePattern)
|
||||
return False
|
||||
|
||||
|
||||
class IncludePattern(object):
|
||||
"""--include PATTERN
|
||||
|
||||
>>> py = IncludePattern('*.py')
|
||||
>>> foo = IncludePattern('/foo')
|
||||
>>> py.match('/foo/foo.py')
|
||||
True
|
||||
>>> py.match('/bar/foo.java')
|
||||
False
|
||||
>>> foo.match('/foo/foo.py')
|
||||
True
|
||||
>>> foo.match('/bar/foo.java')
|
||||
False
|
||||
>>> foo.match('/foobar/foo.py')
|
||||
False
|
||||
"""
|
||||
def __init__(self, pattern):
|
||||
self.pattern = self.dirpattern = pattern
|
||||
if not pattern.endswith(os.path.sep):
|
||||
self.dirpattern += os.path.sep
|
||||
|
||||
def match(self, path):
|
||||
dir, name = os.path.split(path)
|
||||
return (dir + os.path.sep).startswith(self.dirpattern) or fnmatchcase(name, self.pattern)
|
||||
|
||||
def __repr__(self):
|
||||
return '%s(%s)' % (type(self), self.pattern)
|
||||
|
||||
|
||||
class ExcludePattern(IncludePattern):
|
||||
"""
|
||||
"""
|
||||
|
||||
|
||||
def walk_dir(path):
|
||||
st = os.lstat(path)
|
||||
yield path, st
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import doctest
|
||||
import filecmp
|
||||
import os
|
||||
from StringIO import StringIO
|
||||
|
@ -10,7 +11,7 @@
|
|||
import getpass
|
||||
getpass.getpass = lambda m: 'abc123'
|
||||
|
||||
from . import store
|
||||
from . import store, helpers
|
||||
from .archiver import Archiver
|
||||
|
||||
|
||||
|
@ -118,6 +119,7 @@ def suite():
|
|||
suite = unittest.TestSuite()
|
||||
suite.addTest(unittest.TestLoader().loadTestsFromTestCase(Test))
|
||||
suite.addTest(store.suite())
|
||||
suite.addTest(doctest.DocTestSuite(helpers))
|
||||
return suite
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
Loading…
Reference in a new issue