mirror of
https://github.com/borgbackup/borg.git
synced 2024-12-26 17:57:59 +00:00
add PathFullPattern
not really a pattern (as in potentially having any variable parts) - it just does a full, precise match, after the usual normalizations. the reason for adding this is mainly for later optimizations, e.g. via set membership check, so that a lot of such PathFullPatterns can be "matched" within O(1) time.
This commit is contained in:
parent
6dab80218b
commit
ebd928795e
2 changed files with 43 additions and 1 deletions
|
@ -518,6 +518,17 @@ def _match(self, path):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
|
class PathFullPattern(PatternBase):
|
||||||
|
"""Full match of a path."""
|
||||||
|
PREFIX = "pf"
|
||||||
|
|
||||||
|
def _prepare(self, pattern):
|
||||||
|
self.pattern = os.path.normpath(pattern)
|
||||||
|
|
||||||
|
def _match(self, path):
|
||||||
|
return path == self.pattern
|
||||||
|
|
||||||
|
|
||||||
# For PathPrefixPattern, FnmatchPattern and ShellPattern, we require that the pattern either match the whole path
|
# For PathPrefixPattern, FnmatchPattern and ShellPattern, we require that the pattern either match the whole path
|
||||||
# or an initial segment of the path up to but not including a path separator. To unify the two cases, we add a path
|
# or an initial segment of the path up to but not including a path separator. To unify the two cases, we add a path
|
||||||
# separator to the end of the path before matching.
|
# separator to the end of the path before matching.
|
||||||
|
@ -600,6 +611,7 @@ def _match(self, path):
|
||||||
|
|
||||||
_PATTERN_STYLES = set([
|
_PATTERN_STYLES = set([
|
||||||
FnmatchPattern,
|
FnmatchPattern,
|
||||||
|
PathFullPattern,
|
||||||
PathPrefixPattern,
|
PathPrefixPattern,
|
||||||
RegexPattern,
|
RegexPattern,
|
||||||
ShellPattern,
|
ShellPattern,
|
||||||
|
|
|
@ -25,7 +25,8 @@
|
||||||
from ..helpers import ProgressIndicatorPercent, ProgressIndicatorEndless
|
from ..helpers import ProgressIndicatorPercent, ProgressIndicatorEndless
|
||||||
from ..helpers import load_exclude_file, load_pattern_file
|
from ..helpers import load_exclude_file, load_pattern_file
|
||||||
from ..helpers import CompressionSpec, ComprSpec, CompressionDecider1, CompressionDecider2
|
from ..helpers import CompressionSpec, ComprSpec, CompressionDecider1, CompressionDecider2
|
||||||
from ..helpers import parse_pattern, PatternMatcher, RegexPattern, PathPrefixPattern, FnmatchPattern, ShellPattern
|
from ..helpers import parse_pattern, PatternMatcher
|
||||||
|
from ..helpers import PathFullPattern, PathPrefixPattern, FnmatchPattern, ShellPattern, RegexPattern
|
||||||
from ..helpers import swidth_slice
|
from ..helpers import swidth_slice
|
||||||
from ..helpers import chunkit
|
from ..helpers import chunkit
|
||||||
from ..helpers import safe_ns, safe_s
|
from ..helpers import safe_ns, safe_s
|
||||||
|
@ -254,6 +255,35 @@ def check_patterns(files, pattern, expected):
|
||||||
assert matched == (files if expected is None else expected)
|
assert matched == (files if expected is None else expected)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("pattern, expected", [
|
||||||
|
# "None" means all files, i.e. all match the given pattern
|
||||||
|
("/", []),
|
||||||
|
("/home", ["/home"]),
|
||||||
|
("/home///", ["/home"]),
|
||||||
|
("/./home", ["/home"]),
|
||||||
|
("/home/user", ["/home/user"]),
|
||||||
|
("/home/user2", ["/home/user2"]),
|
||||||
|
("/home/user/.bashrc", ["/home/user/.bashrc"]),
|
||||||
|
])
|
||||||
|
def test_patterns_full(pattern, expected):
|
||||||
|
files = ["/home", "/home/user", "/home/user2", "/home/user/.bashrc", ]
|
||||||
|
|
||||||
|
check_patterns(files, PathFullPattern(pattern), expected)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("pattern, expected", [
|
||||||
|
# "None" means all files, i.e. all match the given pattern
|
||||||
|
("", []),
|
||||||
|
("relative", []),
|
||||||
|
("relative/path/", ["relative/path"]),
|
||||||
|
("relative/path", ["relative/path"]),
|
||||||
|
])
|
||||||
|
def test_patterns_full_relative(pattern, expected):
|
||||||
|
files = ["relative/path", "relative/path2", ]
|
||||||
|
|
||||||
|
check_patterns(files, PathFullPattern(pattern), expected)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("pattern, expected", [
|
@pytest.mark.parametrize("pattern, expected", [
|
||||||
# "None" means all files, i.e. all match the given pattern
|
# "None" means all files, i.e. all match the given pattern
|
||||||
("/", None),
|
("/", None),
|
||||||
|
|
Loading…
Reference in a new issue