Show More
@@ -202,19 +202,107 def _donormalize(patterns, default, root | |||
|
202 | 202 | kindpats.append((kind, pat, '')) |
|
203 | 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 | 297 | def __init__(self, root, cwd, normalize, patterns, include=None, |
|
208 | 298 | exclude=None, default='glob', exact=False, auditor=None, |
|
209 | 299 | ctx=None, listsubrepos=False, warn=None, badfn=None): |
|
300 | super(matcher, self).__init__(root, cwd, badfn) | |
|
210 | 301 | if include is None: |
|
211 | 302 | include = [] |
|
212 | 303 | if exclude is None: |
|
213 | 304 | exclude = [] |
|
214 | 305 | |
|
215 | self._root = root | |
|
216 | self._cwd = cwd | |
|
217 | self._files = [] # exact files and roots of patterns | |
|
218 | 306 | self._anypats = bool(include or exclude) |
|
219 | 307 | self._always = False |
|
220 | 308 | self._pathrestricted = bool(include or exclude or patterns) |
@@ -228,9 +316,6 class matcher(object): | |||
|
228 | 316 | # dirs are directories which are non-recursively included. |
|
229 | 317 | self._includedirs = set() |
|
230 | 318 | |
|
231 | if badfn is not None: | |
|
232 | self.bad = badfn | |
|
233 | ||
|
234 | 319 | matchfns = [] |
|
235 | 320 | if include: |
|
236 | 321 | kindpats = normalize(include, 'glob', root, cwd, auditor, warn) |
@@ -281,70 +366,14 class matcher(object): | |||
|
281 | 366 | |
|
282 | 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 | 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 | 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 | 372 | @propertycache |
|
333 | 373 | def _dirs(self): |
|
334 | 374 | return set(util.dirs(self._fileset)) | {'.'} |
|
335 | 375 | |
|
336 | 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 | 377 | if self.prefix() and dir in self._fileset: |
|
349 | 378 | return 'all' |
|
350 | 379 | if dir in self._excluderoots: |
@@ -363,25 +392,15 class matcher(object): | |||
|
363 | 392 | any(parentdir in self._fileset |
|
364 | 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 | 395 | def anypats(self): |
|
371 | '''Matcher uses patterns or include/exclude.''' | |
|
372 | 396 | return self._anypats |
|
373 | 397 | |
|
374 | 398 | def always(self): |
|
375 | '''Matcher will match everything and .files() will be empty | |
|
376 | - optimization might be possible and necessary.''' | |
|
377 | 399 | return self._always |
|
378 | 400 | |
|
379 | 401 | def isexact(self): |
|
380 | 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 | 404 | def __repr__(self): |
|
386 | 405 | return ('<matcher files=%r, patterns=%r, includes=%r, excludes=%r>' % |
|
387 | 406 | (self._files, self.patternspat, self.includepat, |
General Comments 0
You need to be logged in to leave comments.
Login now