comparison mercurial/match.py @ 8581:101d305c1d0b

match: fold _matcher into match.__init__
author Matt Mackall <mpm@selenic.com>
date Sun, 24 May 2009 02:56:14 -0500
parents f648c096f6d0
children a4c199e12b5a
comparison
equal deleted inserted replaced
8580:f648c096f6d0 8581:101d305c1d0b
48 _match.__init__(self, root, cwd, files, self.exact, False) 48 _match.__init__(self, root, cwd, files, self.exact, False)
49 49
50 class match(_match): 50 class match(_match):
51 def __init__(self, root, cwd, patterns, include=[], exclude=[], 51 def __init__(self, root, cwd, patterns, include=[], exclude=[],
52 default='glob'): 52 default='glob'):
53 f, mf, ap = _matcher(root, cwd, patterns, include, exclude, default) 53 """build an object to match a set of file patterns
54 _match.__init__(self, root, cwd, f, mf, ap) 54
55 arguments:
56 root - the canonical root of the tree you're matching against
57 cwd - the current working directory, if relevant
58 patterns - patterns to find
59 include - patterns to include
60 exclude - patterns to exclude
61 default - if a pattern in names has no explicit type, assume this one
62
63 a pattern is one of:
64 'glob:<glob>' - a glob relative to cwd
65 're:<regexp>' - a regular expression
66 'path:<path>' - a path relative to canonroot
67 'relglob:<glob>' - an unrooted glob (*.c matches C files in all dirs)
68 'relpath:<path>' - a path relative to cwd
69 'relre:<regexp>' - a regexp that doesn't have to match the start of a name
70 '<something>' - one of the cases above, selected by the dflt_pat argument
71 """
72
73 roots = []
74 anypats = bool(include or exclude)
75
76 if patterns:
77 pats = _normalize(patterns, default, root, cwd)
78 roots = _roots(pats)
79 anypats = anypats or _anypats(pats)
80 pm = _buildmatch(pats, '$')
81 if include:
82 im = _buildmatch(_normalize(include, 'glob', root, cwd), '(?:/|$)')
83 if exclude:
84 em = _buildmatch(_normalize(exclude, 'glob', root, cwd), '(?:/|$)')
85
86 if patterns:
87 if include:
88 if exclude:
89 m = lambda f: im(f) and not em(f) and pm(f)
90 else:
91 m = lambda f: im(f) and pm(f)
92 else:
93 if exclude:
94 m = lambda f: not em(f) and pm(f)
95 else:
96 m = pm
97 else:
98 if include:
99 if exclude:
100 m = lambda f: im(f) and not em(f)
101 else:
102 m = im
103 else:
104 if exclude:
105 m = lambda f: not em(f)
106 else:
107 m = lambda f: True
108
109 _match.__init__(self, root, cwd, roots, m, anypats)
55 110
56 def patkind(pat): 111 def patkind(pat):
57 return _patsplit(pat, None)[0] 112 return _patsplit(pat, None)[0]
58 113
59 def _patsplit(pat, default): 114 def _patsplit(pat, default):
192 247
193 def _anypats(patterns): 248 def _anypats(patterns):
194 for kind, name in patterns: 249 for kind, name in patterns:
195 if kind in ('glob', 're', 'relglob', 'relre'): 250 if kind in ('glob', 're', 'relglob', 'relre'):
196 return True 251 return True
197
198 def _matcher(root, cwd='', names=[], inc=[], exc=[], dflt_pat='glob'):
199 """build a function to match a set of file patterns
200
201 arguments:
202 root - the canonical root of the tree you're matching against
203 cwd - the current working directory, if relevant
204 names - patterns to find
205 inc - patterns to include
206 exc - patterns to exclude
207 dflt_pat - if a pattern in names has no explicit type, assume this one
208
209 a pattern is one of:
210 'glob:<glob>' - a glob relative to cwd
211 're:<regexp>' - a regular expression
212 'path:<path>' - a path relative to canonroot
213 'relglob:<glob>' - an unrooted glob (*.c matches C files in all dirs)
214 'relpath:<path>' - a path relative to cwd
215 'relre:<regexp>' - a regexp that doesn't have to match the start of a name
216 '<something>' - one of the cases above, selected by the dflt_pat argument
217
218 returns:
219 a 3-tuple containing
220 - list of roots (places where one should start a recursive walk of the fs);
221 this often matches the explicit non-pattern names passed in, but also
222 includes the initial part of glob: patterns that has no glob characters
223 - a bool match(filename) function
224 - a bool indicating if any patterns were passed in
225 """
226
227 roots = []
228 anypats = bool(inc or exc)
229
230 if names:
231 pats = _normalize(names, dflt_pat, root, cwd)
232 roots = _roots(pats)
233 anypats = anypats or _anypats(pats)
234 patmatch = _buildmatch(pats, '$')
235 if inc:
236 incmatch = _buildmatch(_normalize(inc, 'glob', root, cwd), '(?:/|$)')
237 if exc:
238 excmatch = _buildmatch(_normalize(exc, 'glob', root, cwd), '(?:/|$)')
239
240 if names:
241 if inc:
242 if exc:
243 m = lambda f: incmatch(f) and not excmatch(f) and patmatch(f)
244 else:
245 m = lambda f: incmatch(f) and patmatch(f)
246 else:
247 if exc:
248 m = lambda f: not excmatch(f) and patmatch(f)
249 else:
250 m = patmatch
251 else:
252 if inc:
253 if exc:
254 m = lambda f: incmatch(f) and not excmatch(f)
255 else:
256 m = incmatch
257 else:
258 if exc:
259 m = lambda f: not excmatch(f)
260 else:
261 m = lambda f: True
262
263 return (roots, m, anypats)