141 one. |
141 one. |
142 """ |
142 """ |
143 m = copy.copy(match) |
143 m = copy.copy(match) |
144 m.bad = badfn |
144 m.bad = badfn |
145 return m |
145 return m |
|
146 |
|
147 def _donormalize(patterns, default, root, cwd, auditor, warn): |
|
148 '''Convert 'kind:pat' from the patterns list to tuples with kind and |
|
149 normalized and rooted patterns and with listfiles expanded.''' |
|
150 kindpats = [] |
|
151 for kind, pat in [_patsplit(p, default) for p in patterns]: |
|
152 if kind in ('glob', 'relpath'): |
|
153 pat = pathutil.canonpath(root, cwd, pat, auditor) |
|
154 elif kind in ('relglob', 'path', 'rootfilesin'): |
|
155 pat = util.normpath(pat) |
|
156 elif kind in ('listfile', 'listfile0'): |
|
157 try: |
|
158 files = util.readfile(pat) |
|
159 if kind == 'listfile0': |
|
160 files = files.split('\0') |
|
161 else: |
|
162 files = files.splitlines() |
|
163 files = [f for f in files if f] |
|
164 except EnvironmentError: |
|
165 raise error.Abort(_("unable to read file list (%s)") % pat) |
|
166 for k, p, source in _donormalize(files, default, root, cwd, |
|
167 auditor, warn): |
|
168 kindpats.append((k, p, pat)) |
|
169 continue |
|
170 elif kind == 'include': |
|
171 try: |
|
172 fullpath = os.path.join(root, util.localpath(pat)) |
|
173 includepats = readpatternfile(fullpath, warn) |
|
174 for k, p, source in _donormalize(includepats, default, |
|
175 root, cwd, auditor, warn): |
|
176 kindpats.append((k, p, source or pat)) |
|
177 except error.Abort as inst: |
|
178 raise error.Abort('%s: %s' % (pat, inst[0])) |
|
179 except IOError as inst: |
|
180 if warn: |
|
181 warn(_("skipping unreadable pattern file '%s': %s\n") % |
|
182 (pat, inst.strerror)) |
|
183 continue |
|
184 # else: re or relre - which cannot be normalized |
|
185 kindpats.append((kind, pat, '')) |
|
186 return kindpats |
146 |
187 |
147 class matcher(object): |
188 class matcher(object): |
148 |
189 |
149 def __init__(self, root, cwd, patterns, include=None, exclude=None, |
190 def __init__(self, root, cwd, patterns, include=None, exclude=None, |
150 default='glob', exact=False, auditor=None, ctx=None, |
191 default='glob', exact=False, auditor=None, ctx=None, |
323 |
364 |
324 def prefix(self): |
365 def prefix(self): |
325 return not self.always() and not self.isexact() and not self.anypats() |
366 return not self.always() and not self.isexact() and not self.anypats() |
326 |
367 |
327 def _normalize(self, patterns, default, root, cwd, auditor, warn): |
368 def _normalize(self, patterns, default, root, cwd, auditor, warn): |
328 '''Convert 'kind:pat' from the patterns list to tuples with kind and |
369 return _donormalize(patterns, default, root, cwd, auditor, warn) |
329 normalized and rooted patterns and with listfiles expanded.''' |
|
330 kindpats = [] |
|
331 for kind, pat in [_patsplit(p, default) for p in patterns]: |
|
332 if kind in ('glob', 'relpath'): |
|
333 pat = pathutil.canonpath(root, cwd, pat, auditor) |
|
334 elif kind in ('relglob', 'path', 'rootfilesin'): |
|
335 pat = util.normpath(pat) |
|
336 elif kind in ('listfile', 'listfile0'): |
|
337 try: |
|
338 files = util.readfile(pat) |
|
339 if kind == 'listfile0': |
|
340 files = files.split('\0') |
|
341 else: |
|
342 files = files.splitlines() |
|
343 files = [f for f in files if f] |
|
344 except EnvironmentError: |
|
345 raise error.Abort(_("unable to read file list (%s)") % pat) |
|
346 for k, p, source in self._normalize(files, default, root, cwd, |
|
347 auditor, warn): |
|
348 kindpats.append((k, p, pat)) |
|
349 continue |
|
350 elif kind == 'include': |
|
351 try: |
|
352 fullpath = os.path.join(root, util.localpath(pat)) |
|
353 includepats = readpatternfile(fullpath, warn) |
|
354 for k, p, source in self._normalize(includepats, default, |
|
355 root, cwd, auditor, |
|
356 warn): |
|
357 kindpats.append((k, p, source or pat)) |
|
358 except error.Abort as inst: |
|
359 raise error.Abort('%s: %s' % (pat, inst[0])) |
|
360 except IOError as inst: |
|
361 if warn: |
|
362 warn(_("skipping unreadable pattern file '%s': %s\n") % |
|
363 (pat, inst.strerror)) |
|
364 continue |
|
365 # else: re or relre - which cannot be normalized |
|
366 kindpats.append((kind, pat, '')) |
|
367 return kindpats |
|
368 |
370 |
369 class subdirmatcher(matcher): |
371 class subdirmatcher(matcher): |
370 """Adapt a matcher to work on a subdirectory only. |
372 """Adapt a matcher to work on a subdirectory only. |
371 |
373 |
372 The paths are remapped to remove/insert the path as needed: |
374 The paths are remapped to remove/insert the path as needed: |