Show More
@@ -202,19 +202,107 b' def _donormalize(patterns, default, root' | |||||
202 | kindpats.append((kind, pat, '')) |
|
202 | kindpats.append((kind, pat, '')) | |
203 | return kindpats |
|
203 | return kindpats | |
204 |
|
204 | |||
205 | class matcher(object): |
|
205 | class basematcher(object): | |
|
206 | ||||
|
207 | def __init__(self, root, cwd, badfn=None): | |||
|
208 | self._root = root | |||
|
209 | self._cwd = cwd | |||
|
210 | if badfn is not None: | |||
|
211 | self.bad = badfn | |||
|
212 | self._files = [] # exact files and roots of patterns | |||
|
213 | self.matchfn = lambda f: False | |||
|
214 | ||||
|
215 | def __call__(self, fn): | |||
|
216 | return self.matchfn(fn) | |||
|
217 | def __iter__(self): | |||
|
218 | for f in self._files: | |||
|
219 | yield f | |||
|
220 | # Callbacks related to how the matcher is used by dirstate.walk. | |||
|
221 | # Subscribers to these events must monkeypatch the matcher object. | |||
|
222 | def bad(self, f, msg): | |||
|
223 | '''Callback from dirstate.walk for each explicit file that can't be | |||
|
224 | found/accessed, with an error message.''' | |||
|
225 | pass | |||
|
226 | ||||
|
227 | # If an explicitdir is set, it will be called when an explicitly listed | |||
|
228 | # directory is visited. | |||
|
229 | explicitdir = None | |||
|
230 | ||||
|
231 | # If an traversedir is set, it will be called when a directory discovered | |||
|
232 | # by recursive traversal is visited. | |||
|
233 | traversedir = None | |||
|
234 | ||||
|
235 | def abs(self, f): | |||
|
236 | '''Convert a repo path back to path that is relative to the root of the | |||
|
237 | matcher.''' | |||
|
238 | return f | |||
|
239 | ||||
|
240 | def rel(self, f): | |||
|
241 | '''Convert repo path back to path that is relative to cwd of matcher.''' | |||
|
242 | return util.pathto(self._root, self._cwd, f) | |||
|
243 | ||||
|
244 | def uipath(self, f): | |||
|
245 | '''Convert repo path to a display path. If patterns or -I/-X were used | |||
|
246 | to create this matcher, the display path will be relative to cwd. | |||
|
247 | Otherwise it is relative to the root of the repo.''' | |||
|
248 | return self.rel(f) | |||
|
249 | ||||
|
250 | def files(self): | |||
|
251 | '''Explicitly listed files or patterns or roots: | |||
|
252 | if no patterns or .always(): empty list, | |||
|
253 | if exact: list exact files, | |||
|
254 | if not .anypats(): list all files and dirs, | |||
|
255 | else: optimal roots''' | |||
|
256 | return self._files | |||
|
257 | ||||
|
258 | @propertycache | |||
|
259 | def _fileset(self): | |||
|
260 | return set(self._files) | |||
|
261 | ||||
|
262 | def exact(self, f): | |||
|
263 | '''Returns True if f is in .files().''' | |||
|
264 | return f in self._fileset | |||
|
265 | ||||
|
266 | def visitdir(self, dir): | |||
|
267 | '''Decides whether a directory should be visited based on whether it | |||
|
268 | has potential matches in it or one of its subdirectories. This is | |||
|
269 | based on the match's primary, included, and excluded patterns. | |||
|
270 | ||||
|
271 | Returns the string 'all' if the given directory and all subdirectories | |||
|
272 | should be visited. Otherwise returns True or False indicating whether | |||
|
273 | the given directory should be visited. | |||
|
274 | ||||
|
275 | This function's behavior is undefined if it has returned False for | |||
|
276 | one of the dir's parent directories. | |||
|
277 | ''' | |||
|
278 | return False | |||
|
279 | ||||
|
280 | def anypats(self): | |||
|
281 | '''Matcher uses patterns or include/exclude.''' | |||
|
282 | return False | |||
|
283 | ||||
|
284 | def always(self): | |||
|
285 | '''Matcher will match everything and .files() will be empty | |||
|
286 | - optimization might be possible and necessary.''' | |||
|
287 | return False | |||
|
288 | ||||
|
289 | def isexact(self): | |||
|
290 | return False | |||
|
291 | ||||
|
292 | def prefix(self): | |||
|
293 | return not self.always() and not self.isexact() and not self.anypats() | |||
|
294 | ||||
|
295 | class matcher(basematcher): | |||
206 |
|
296 | |||
207 | def __init__(self, root, cwd, normalize, patterns, include=None, |
|
297 | def __init__(self, root, cwd, normalize, patterns, include=None, | |
208 | exclude=None, default='glob', exact=False, auditor=None, |
|
298 | exclude=None, default='glob', exact=False, auditor=None, | |
209 | ctx=None, listsubrepos=False, warn=None, badfn=None): |
|
299 | ctx=None, listsubrepos=False, warn=None, badfn=None): | |
|
300 | super(matcher, self).__init__(root, cwd, badfn) | |||
210 | if include is None: |
|
301 | if include is None: | |
211 | include = [] |
|
302 | include = [] | |
212 | if exclude is None: |
|
303 | if exclude is None: | |
213 | exclude = [] |
|
304 | exclude = [] | |
214 |
|
305 | |||
215 | self._root = root |
|
|||
216 | self._cwd = cwd |
|
|||
217 | self._files = [] # exact files and roots of patterns |
|
|||
218 | self._anypats = bool(include or exclude) |
|
306 | self._anypats = bool(include or exclude) | |
219 | self._always = False |
|
307 | self._always = False | |
220 | self._pathrestricted = bool(include or exclude or patterns) |
|
308 | self._pathrestricted = bool(include or exclude or patterns) | |
@@ -228,9 +316,6 b' class matcher(object):' | |||||
228 | # dirs are directories which are non-recursively included. |
|
316 | # dirs are directories which are non-recursively included. | |
229 | self._includedirs = set() |
|
317 | self._includedirs = set() | |
230 |
|
318 | |||
231 | if badfn is not None: |
|
|||
232 | self.bad = badfn |
|
|||
233 |
|
||||
234 | matchfns = [] |
|
319 | matchfns = [] | |
235 | if include: |
|
320 | if include: | |
236 | kindpats = normalize(include, 'glob', root, cwd, auditor, warn) |
|
321 | kindpats = normalize(include, 'glob', root, cwd, auditor, warn) | |
@@ -281,70 +366,14 b' class matcher(object):' | |||||
281 |
|
366 | |||
282 | self.matchfn = m |
|
367 | self.matchfn = m | |
283 |
|
368 | |||
284 | def __call__(self, fn): |
|
|||
285 | return self.matchfn(fn) |
|
|||
286 | def __iter__(self): |
|
|||
287 | for f in self._files: |
|
|||
288 | yield f |
|
|||
289 |
|
||||
290 | # Callbacks related to how the matcher is used by dirstate.walk. |
|
|||
291 | # Subscribers to these events must monkeypatch the matcher object. |
|
|||
292 | def bad(self, f, msg): |
|
|||
293 | '''Callback from dirstate.walk for each explicit file that can't be |
|
|||
294 | found/accessed, with an error message.''' |
|
|||
295 | pass |
|
|||
296 |
|
||||
297 | # If an explicitdir is set, it will be called when an explicitly listed |
|
|||
298 | # directory is visited. |
|
|||
299 | explicitdir = None |
|
|||
300 |
|
||||
301 | # If an traversedir is set, it will be called when a directory discovered |
|
|||
302 | # by recursive traversal is visited. |
|
|||
303 | traversedir = None |
|
|||
304 |
|
||||
305 | def abs(self, f): |
|
|||
306 | '''Convert a repo path back to path that is relative to the root of the |
|
|||
307 | matcher.''' |
|
|||
308 | return f |
|
|||
309 |
|
||||
310 | def rel(self, f): |
|
|||
311 | '''Convert repo path back to path that is relative to cwd of matcher.''' |
|
|||
312 | return util.pathto(self._root, self._cwd, f) |
|
|||
313 |
|
||||
314 | def uipath(self, f): |
|
369 | def uipath(self, f): | |
315 | '''Convert repo path to a display path. If patterns or -I/-X were used |
|
|||
316 | to create this matcher, the display path will be relative to cwd. |
|
|||
317 | Otherwise it is relative to the root of the repo.''' |
|
|||
318 | return (self._pathrestricted and self.rel(f)) or self.abs(f) |
|
370 | return (self._pathrestricted and self.rel(f)) or self.abs(f) | |
319 |
|
371 | |||
320 | def files(self): |
|
|||
321 | '''Explicitly listed files or patterns or roots: |
|
|||
322 | if no patterns or .always(): empty list, |
|
|||
323 | if exact: list exact files, |
|
|||
324 | if not .anypats(): list all files and dirs, |
|
|||
325 | else: optimal roots''' |
|
|||
326 | return self._files |
|
|||
327 |
|
||||
328 | @propertycache |
|
|||
329 | def _fileset(self): |
|
|||
330 | return set(self._files) |
|
|||
331 |
|
||||
332 | @propertycache |
|
372 | @propertycache | |
333 | def _dirs(self): |
|
373 | def _dirs(self): | |
334 | return set(util.dirs(self._fileset)) | {'.'} |
|
374 | return set(util.dirs(self._fileset)) | {'.'} | |
335 |
|
375 | |||
336 | def visitdir(self, dir): |
|
376 | def visitdir(self, dir): | |
337 | '''Decides whether a directory should be visited based on whether it |
|
|||
338 | has potential matches in it or one of its subdirectories. This is |
|
|||
339 | based on the match's primary, included, and excluded patterns. |
|
|||
340 |
|
||||
341 | Returns the string 'all' if the given directory and all subdirectories |
|
|||
342 | should be visited. Otherwise returns True or False indicating whether |
|
|||
343 | the given directory should be visited. |
|
|||
344 |
|
||||
345 | This function's behavior is undefined if it has returned False for |
|
|||
346 | one of the dir's parent directories. |
|
|||
347 | ''' |
|
|||
348 | if self.prefix() and dir in self._fileset: |
|
377 | if self.prefix() and dir in self._fileset: | |
349 | return 'all' |
|
378 | return 'all' | |
350 | if dir in self._excluderoots: |
|
379 | if dir in self._excluderoots: | |
@@ -363,25 +392,15 b' class matcher(object):' | |||||
363 | any(parentdir in self._fileset |
|
392 | any(parentdir in self._fileset | |
364 | for parentdir in util.finddirs(dir))) |
|
393 | for parentdir in util.finddirs(dir))) | |
365 |
|
394 | |||
366 | def exact(self, f): |
|
|||
367 | '''Returns True if f is in .files().''' |
|
|||
368 | return f in self._fileset |
|
|||
369 |
|
||||
370 | def anypats(self): |
|
395 | def anypats(self): | |
371 | '''Matcher uses patterns or include/exclude.''' |
|
|||
372 | return self._anypats |
|
396 | return self._anypats | |
373 |
|
397 | |||
374 | def always(self): |
|
398 | def always(self): | |
375 | '''Matcher will match everything and .files() will be empty |
|
|||
376 | - optimization might be possible and necessary.''' |
|
|||
377 | return self._always |
|
399 | return self._always | |
378 |
|
400 | |||
379 | def isexact(self): |
|
401 | def isexact(self): | |
380 | return self.matchfn == self.exact |
|
402 | return self.matchfn == self.exact | |
381 |
|
403 | |||
382 | def prefix(self): |
|
|||
383 | return not self.always() and not self.isexact() and not self.anypats() |
|
|||
384 |
|
||||
385 | def __repr__(self): |
|
404 | def __repr__(self): | |
386 | return ('<matcher files=%r, patterns=%r, includes=%r, excludes=%r>' % |
|
405 | return ('<matcher files=%r, patterns=%r, includes=%r, excludes=%r>' % | |
387 | (self._files, self.patternspat, self.includepat, |
|
406 | (self._files, self.patternspat, self.includepat, |
General Comments 0
You need to be logged in to leave comments.
Login now