mercurial/match.py
changeset 8587 8f15d54437b9
parent 8586 347fe1ac4f21
child 8613 4dea46d4e3f8
equal deleted inserted replaced
8586:347fe1ac4f21 8587:8f15d54437b9
     5 # This software may be used and distributed according to the terms of the
     5 # This software may be used and distributed according to the terms of the
     6 # GNU General Public License version 2, incorporated herein by reference.
     6 # GNU General Public License version 2, incorporated herein by reference.
     7 
     7 
     8 import util, re
     8 import util, re
     9 
     9 
    10 class _match(object):
    10 class match(object):
    11     def __init__(self, root, cwd, files, mf, ap):
    11     def __init__(self, root, cwd, patterns, include=[], exclude=[],
       
    12                  default='glob', exact=False):
       
    13         """build an object to match a set of file patterns
       
    14 
       
    15         arguments:
       
    16         root - the canonical root of the tree you're matching against
       
    17         cwd - the current working directory, if relevant
       
    18         patterns - patterns to find
       
    19         include - patterns to include
       
    20         exclude - patterns to exclude
       
    21         default - if a pattern in names has no explicit type, assume this one
       
    22         exact - patterns are actually literals
       
    23 
       
    24         a pattern is one of:
       
    25         'glob:<glob>' - a glob relative to cwd
       
    26         're:<regexp>' - a regular expression
       
    27         'path:<path>' - a path relative to canonroot
       
    28         'relglob:<glob>' - an unrooted glob (*.c matches C files in all dirs)
       
    29         'relpath:<path>' - a path relative to cwd
       
    30         'relre:<regexp>' - a regexp that needn't match the start of a name
       
    31         '<something>' - a pattern of the specified default type
       
    32         """
       
    33 
    12         self._root = root
    34         self._root = root
    13         self._cwd = cwd
    35         self._cwd = cwd
    14         self._files = files
    36         self._files = []
    15         self._fmap = set(files)
    37         self._anypats = bool(include or exclude)
    16         self.matchfn = mf
    38 
    17         self._anypats = ap
    39         if include:
       
    40             im = _buildmatch(_normalize(include, 'glob', root, cwd), '(?:/|$)')
       
    41         if exclude:
       
    42             em = _buildmatch(_normalize(exclude, 'glob', root, cwd), '(?:/|$)')
       
    43         if exact:
       
    44             self._files = patterns
       
    45             pm = self.exact
       
    46         elif patterns:
       
    47             pats = _normalize(patterns, default, root, cwd)
       
    48             self._files = _roots(pats)
       
    49             self._anypats = self._anypats or _anypats(pats)
       
    50             pm = _buildmatch(pats, '$')
       
    51 
       
    52         if patterns or exact:
       
    53             if include:
       
    54                 if exclude:
       
    55                     m = lambda f: im(f) and not em(f) and pm(f)
       
    56                 else:
       
    57                     m = lambda f: im(f) and pm(f)
       
    58             else:
       
    59                 if exclude:
       
    60                     m = lambda f: not em(f) and pm(f)
       
    61                 else:
       
    62                     m = pm
       
    63         else:
       
    64             if include:
       
    65                 if exclude:
       
    66                     m = lambda f: im(f) and not em(f)
       
    67                 else:
       
    68                     m = im
       
    69             else:
       
    70                 if exclude:
       
    71                     m = lambda f: not em(f)
       
    72                 else:
       
    73                     m = lambda f: True
       
    74 
       
    75         self.matchfn = m
       
    76         self._fmap = set(self._files)
       
    77 
    18     def __call__(self, fn):
    78     def __call__(self, fn):
    19         return self.matchfn(fn)
    79         return self.matchfn(fn)
    20     def __iter__(self):
    80     def __iter__(self):
    21         for f in self._files:
    81         for f in self._files:
    22             yield f
    82             yield f
    32         return util.pathto(self._root, self._cwd, f)
    92         return util.pathto(self._root, self._cwd, f)
    33     def files(self):
    93     def files(self):
    34         return self._files
    94         return self._files
    35     def anypats(self):
    95     def anypats(self):
    36         return self._anypats
    96         return self._anypats
    37 
       
    38 class match(_match):
       
    39     def __init__(self, root, cwd, patterns, include=[], exclude=[],
       
    40                  default='glob', exact=False):
       
    41         """build an object to match a set of file patterns
       
    42 
       
    43         arguments:
       
    44         root - the canonical root of the tree you're matching against
       
    45         cwd - the current working directory, if relevant
       
    46         patterns - patterns to find
       
    47         include - patterns to include
       
    48         exclude - patterns to exclude
       
    49         default - if a pattern in names has no explicit type, assume this one
       
    50         exact - patterns are actually literals
       
    51 
       
    52         a pattern is one of:
       
    53         'glob:<glob>' - a glob relative to cwd
       
    54         're:<regexp>' - a regular expression
       
    55         'path:<path>' - a path relative to canonroot
       
    56         'relglob:<glob>' - an unrooted glob (*.c matches C files in all dirs)
       
    57         'relpath:<path>' - a path relative to cwd
       
    58         'relre:<regexp>' - a regexp that doesn't have to match the start of a name
       
    59         '<something>' - one of the cases above, selected by the dflt_pat argument
       
    60         """
       
    61 
       
    62         roots = []
       
    63         anypats = bool(include or exclude)
       
    64 
       
    65         if include:
       
    66             im = _buildmatch(_normalize(include, 'glob', root, cwd), '(?:/|$)')
       
    67         if exclude:
       
    68             em = _buildmatch(_normalize(exclude, 'glob', root, cwd), '(?:/|$)')
       
    69         if exact:
       
    70             roots = patterns
       
    71             pm = self.exact
       
    72         elif patterns:
       
    73             pats = _normalize(patterns, default, root, cwd)
       
    74             roots = _roots(pats)
       
    75             anypats = anypats or _anypats(pats)
       
    76             pm = _buildmatch(pats, '$')
       
    77 
       
    78         if patterns or exact:
       
    79             if include:
       
    80                 if exclude:
       
    81                     m = lambda f: im(f) and not em(f) and pm(f)
       
    82                 else:
       
    83                     m = lambda f: im(f) and pm(f)
       
    84             else:
       
    85                 if exclude:
       
    86                     m = lambda f: not em(f) and pm(f)
       
    87                 else:
       
    88                     m = pm
       
    89         else:
       
    90             if include:
       
    91                 if exclude:
       
    92                     m = lambda f: im(f) and not em(f)
       
    93                 else:
       
    94                     m = im
       
    95             else:
       
    96                 if exclude:
       
    97                     m = lambda f: not em(f)
       
    98                 else:
       
    99                     m = lambda f: True
       
   100 
       
   101         _match.__init__(self, root, cwd, roots, m, anypats)
       
   102 
    97 
   103 class exact(match):
    98 class exact(match):
   104     def __init__(self, root, cwd, files):
    99     def __init__(self, root, cwd, files):
   105         match.__init__(self, root, cwd, files, exact = True)
   100         match.__init__(self, root, cwd, files, exact = True)
   106 
   101