|
@@ -1,6 +1,7 @@
|
|
|
import argparse
|
|
|
import binascii
|
|
|
from collections import namedtuple
|
|
|
+from functools import wraps
|
|
|
import grp
|
|
|
import os
|
|
|
import pwd
|
|
@@ -222,9 +223,22 @@ def exclude_path(path, patterns):
|
|
|
# unify the two cases, we add a path separator to the end of
|
|
|
# the path before matching.
|
|
|
|
|
|
-##### !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
|
-##### For discussion only, don't merge this code!
|
|
|
-##### !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
|
+def normalized(func):
|
|
|
+ """ Decorator for the Pattern match methods, returning a wrapper that
|
|
|
+ normalizes OSX paths to match the normalized pattern on OSX, and
|
|
|
+ returning the original method on other platforms"""
|
|
|
+ @wraps(func)
|
|
|
+ def normalize_wrapper(self, path):
|
|
|
+ return func(self, unicodedata.normalize("NFD", path))
|
|
|
+
|
|
|
+ if sys.platform in ('darwin',):
|
|
|
+ # HFS+ converts paths to a canonical form, so users shouldn't be
|
|
|
+ # required to enter an exact match
|
|
|
+ return normalize_wrapper
|
|
|
+ else:
|
|
|
+ # Windows and Unix filesystems allow different forms, so users
|
|
|
+ # always have to enter an exact match
|
|
|
+ return func
|
|
|
|
|
|
class IncludePattern:
|
|
|
"""Literal files or directories listed on the command line
|
|
@@ -233,23 +247,15 @@ class IncludePattern:
|
|
|
path match as well. A trailing slash makes no difference.
|
|
|
"""
|
|
|
def __init__(self, pattern):
|
|
|
- def match(path):
|
|
|
- return (path+os.path.sep).startswith(self.pattern)
|
|
|
-
|
|
|
- # HFS+ converts paths to a canonical form, so users shouldn't be
|
|
|
- # required to enter an exact match
|
|
|
if sys.platform in ('darwin',):
|
|
|
- # repository paths will be mostly in NFD, as the OSX exception list
|
|
|
- # to NFD is small, so normalize to that form for best performance
|
|
|
pattern = unicodedata.normalize("NFD", pattern)
|
|
|
- self.match = lambda p: match(unicodedata.normalize("NFD", p))
|
|
|
- # Windows and Unix filesystems allow different forms, so users
|
|
|
- # always have to enter an exact match
|
|
|
- else:
|
|
|
- self.match = match
|
|
|
|
|
|
self.pattern = os.path.normpath(pattern).rstrip(os.path.sep)+os.path.sep
|
|
|
|
|
|
+ @normalized
|
|
|
+ def match(self, path):
|
|
|
+ return (path+os.path.sep).startswith(self.pattern)
|
|
|
+
|
|
|
def __repr__(self):
|
|
|
return '%s(%s)' % (type(self), self.pattern)
|
|
|
|
|
@@ -259,30 +265,22 @@ class ExcludePattern(IncludePattern):
|
|
|
exclude the contents of a directory, but not the directory itself.
|
|
|
"""
|
|
|
def __init__(self, pattern):
|
|
|
- def match(path):
|
|
|
- return self.regex.match(path+os.path.sep) is not None
|
|
|
-
|
|
|
if pattern.endswith(os.path.sep):
|
|
|
self.pattern = os.path.normpath(pattern).rstrip(os.path.sep)+os.path.sep+'*'+os.path.sep
|
|
|
else:
|
|
|
self.pattern = os.path.normpath(pattern)+os.path.sep+'*'
|
|
|
|
|
|
- # HFS+ converts paths to a canonical form, so users shouldn't be
|
|
|
- # required to enter an exact match
|
|
|
if sys.platform in ('darwin',):
|
|
|
- # repository paths will be mostly in NFD, as the OSX exception list
|
|
|
- # to NFD is small, so normalize to that form for best performance
|
|
|
self.pattern = unicodedata.normalize("NFD", self.pattern)
|
|
|
- self.match = lambda p: match(unicodedata.normalize("NFD", p))
|
|
|
- # Windows and Unix filesystems allow different forms, so users
|
|
|
- # always have to enter an exact match
|
|
|
- else:
|
|
|
- self.match = match
|
|
|
|
|
|
# fnmatch and re.match both cache compiled regular expressions.
|
|
|
# Nevertheless, this is about 10 times faster.
|
|
|
self.regex = re.compile(translate(self.pattern))
|
|
|
|
|
|
+ @normalized
|
|
|
+ def match(self, path):
|
|
|
+ return self.regex.match(path+os.path.sep) is not None
|
|
|
+
|
|
|
def __repr__(self):
|
|
|
return '%s(%s)' % (type(self), self.pattern)
|
|
|
|