|
@@ -391,18 +391,23 @@ def parse_timestamp(timestamp):
|
|
|
return datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%S').replace(tzinfo=timezone.utc)
|
|
|
|
|
|
|
|
|
-def parse_add_pattern(patternstr, roots, patterns):
|
|
|
+def parse_add_pattern(patternstr, roots, patterns, fallback):
|
|
|
"""Parse a pattern string and add it to roots or patterns depending on the pattern type."""
|
|
|
- pattern = parse_inclexcl_pattern(patternstr)
|
|
|
+ pattern = parse_inclexcl_pattern(patternstr, fallback=fallback)
|
|
|
if pattern.ptype is RootPath:
|
|
|
roots.append(pattern.pattern)
|
|
|
+ elif pattern.ptype is PatternStyle:
|
|
|
+ fallback = pattern.pattern
|
|
|
else:
|
|
|
patterns.append(pattern)
|
|
|
+ return fallback
|
|
|
|
|
|
|
|
|
-def load_pattern_file(fileobj, roots, patterns):
|
|
|
+def load_pattern_file(fileobj, roots, patterns, fallback=None):
|
|
|
+ if fallback is None:
|
|
|
+ fallback = ShellPattern # ShellPattern is defined later in this module
|
|
|
for patternstr in clean_lines(fileobj):
|
|
|
- parse_add_pattern(patternstr, roots, patterns)
|
|
|
+ fallback = parse_add_pattern(patternstr, roots, patterns, fallback)
|
|
|
|
|
|
|
|
|
def load_exclude_file(fileobj, patterns):
|
|
@@ -415,7 +420,7 @@ class ArgparsePatternAction(argparse.Action):
|
|
|
super().__init__(nargs=nargs, **kw)
|
|
|
|
|
|
def __call__(self, parser, args, values, option_string=None):
|
|
|
- parse_add_pattern(values[0], args.paths, args.patterns)
|
|
|
+ parse_add_pattern(values[0], args.paths, args.patterns, ShellPattern)
|
|
|
|
|
|
|
|
|
class ArgparsePatternFileAction(argparse.Action):
|
|
@@ -614,6 +619,14 @@ _PATTERN_STYLE_BY_PREFIX = dict((i.PREFIX, i) for i in _PATTERN_STYLES)
|
|
|
|
|
|
InclExclPattern = namedtuple('InclExclPattern', 'pattern ptype')
|
|
|
RootPath = object()
|
|
|
+PatternStyle = object()
|
|
|
+
|
|
|
+
|
|
|
+def get_pattern_style(prefix):
|
|
|
+ try:
|
|
|
+ return _PATTERN_STYLE_BY_PREFIX[prefix]
|
|
|
+ except KeyError:
|
|
|
+ raise ValueError("Unknown pattern style: {}".format(prefix)) from None
|
|
|
|
|
|
|
|
|
def parse_pattern(pattern, fallback=FnmatchPattern):
|
|
@@ -621,14 +634,9 @@ def parse_pattern(pattern, fallback=FnmatchPattern):
|
|
|
"""
|
|
|
if len(pattern) > 2 and pattern[2] == ":" and pattern[:2].isalnum():
|
|
|
(style, pattern) = (pattern[:2], pattern[3:])
|
|
|
-
|
|
|
- cls = _PATTERN_STYLE_BY_PREFIX.get(style, None)
|
|
|
-
|
|
|
- if cls is None:
|
|
|
- raise ValueError("Unknown pattern style: {}".format(style))
|
|
|
+ cls = get_pattern_style(style)
|
|
|
else:
|
|
|
cls = fallback
|
|
|
-
|
|
|
return cls(pattern)
|
|
|
|
|
|
|
|
@@ -646,6 +654,8 @@ def parse_inclexcl_pattern(pattern, fallback=ShellPattern):
|
|
|
'+': True,
|
|
|
'R': RootPath,
|
|
|
'r': RootPath,
|
|
|
+ 'P': PatternStyle,
|
|
|
+ 'p': PatternStyle,
|
|
|
}
|
|
|
try:
|
|
|
ptype = type_prefix_map[pattern[0]]
|
|
@@ -656,6 +666,11 @@ def parse_inclexcl_pattern(pattern, fallback=ShellPattern):
|
|
|
raise argparse.ArgumentTypeError("Unable to parse pattern: {}".format(pattern))
|
|
|
if ptype is RootPath:
|
|
|
pobj = pattern
|
|
|
+ elif ptype is PatternStyle:
|
|
|
+ try:
|
|
|
+ pobj = get_pattern_style(pattern)
|
|
|
+ except ValueError:
|
|
|
+ raise argparse.ArgumentTypeError("Unable to parse pattern: {}".format(pattern))
|
|
|
else:
|
|
|
pobj = parse_pattern(pattern, fallback)
|
|
|
return InclExclPattern(pobj, ptype)
|