Mercurial > public > mercurial-scm > hg
comparison mercurial/fileset.py @ 38690:5d9749c598f0
fileset: remove callexisting flag and mctx.existing() (API)
They are no longer needed since any files are included as long as they are
passed in to the matcher.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sat, 09 Jun 2018 22:31:51 +0900 |
parents | ff5b6fca1082 |
children | 370ff3e34160 |
comparison
equal
deleted
inserted
replaced
38689:ff5b6fca1082 | 38690:5d9749c598f0 |
---|---|
179 hint=_('see hg help "filesets.x or y"')) | 179 hint=_('see hg help "filesets.x or y"')) |
180 | 180 |
181 def func(mctx, a, b): | 181 def func(mctx, a, b): |
182 funcname = getsymbol(a) | 182 funcname = getsymbol(a) |
183 if funcname in symbols: | 183 if funcname in symbols: |
184 enabled = mctx._existingenabled | 184 return symbols[funcname](mctx, b) |
185 mctx._existingenabled = funcname in _existingcallers | |
186 try: | |
187 return symbols[funcname](mctx, b) | |
188 finally: | |
189 mctx._existingenabled = enabled | |
190 | 185 |
191 keep = lambda fn: getattr(fn, '__doc__', None) is not None | 186 keep = lambda fn: getattr(fn, '__doc__', None) is not None |
192 | 187 |
193 syms = [s for (s, fn) in symbols.items() if keep(fn)] | 188 syms = [s for (s, fn) in symbols.items() if keep(fn)] |
194 raise error.UnknownIdentifier(funcname, syms) | 189 raise error.UnknownIdentifier(funcname, syms) |
200 # x - argument in tree form | 195 # x - argument in tree form |
201 symbols = {} | 196 symbols = {} |
202 | 197 |
203 # filesets using matchctx.status() | 198 # filesets using matchctx.status() |
204 _statuscallers = set() | 199 _statuscallers = set() |
205 | |
206 # filesets using matchctx.existing() | |
207 _existingcallers = set() | |
208 | 200 |
209 predicate = registrar.filesetpredicate() | 201 predicate = registrar.filesetpredicate() |
210 | 202 |
211 @predicate('modified()', callstatus=True) | 203 @predicate('modified()', callstatus=True) |
212 def modified(mctx, x): | 204 def modified(mctx, x): |
283 """File that is under Mercurial control.""" | 275 """File that is under Mercurial control.""" |
284 # i18n: "tracked" is a keyword | 276 # i18n: "tracked" is a keyword |
285 getargs(x, 0, 0, _("tracked takes no arguments")) | 277 getargs(x, 0, 0, _("tracked takes no arguments")) |
286 return mctx.predicate(mctx.ctx.__contains__, predrepr='tracked') | 278 return mctx.predicate(mctx.ctx.__contains__, predrepr='tracked') |
287 | 279 |
288 @predicate('binary()', callexisting=True) | 280 @predicate('binary()') |
289 def binary(mctx, x): | 281 def binary(mctx, x): |
290 """File that appears to be binary (contains NUL bytes). | 282 """File that appears to be binary (contains NUL bytes). |
291 """ | 283 """ |
292 # i18n: "binary" is a keyword | 284 # i18n: "binary" is a keyword |
293 getargs(x, 0, 0, _("binary takes no arguments")) | 285 getargs(x, 0, 0, _("binary takes no arguments")) |
294 return mctx.fpredicate(lambda fctx: fctx.isbinary(), | 286 return mctx.fpredicate(lambda fctx: fctx.isbinary(), |
295 predrepr='binary', cache=True) | 287 predrepr='binary', cache=True) |
296 | 288 |
297 @predicate('exec()', callexisting=True) | 289 @predicate('exec()') |
298 def exec_(mctx, x): | 290 def exec_(mctx, x): |
299 """File that is marked as executable. | 291 """File that is marked as executable. |
300 """ | 292 """ |
301 # i18n: "exec" is a keyword | 293 # i18n: "exec" is a keyword |
302 getargs(x, 0, 0, _("exec takes no arguments")) | 294 getargs(x, 0, 0, _("exec takes no arguments")) |
303 ctx = mctx.ctx | 295 ctx = mctx.ctx |
304 return mctx.predicate(lambda f: ctx.flags(f) == 'x', predrepr='exec') | 296 return mctx.predicate(lambda f: ctx.flags(f) == 'x', predrepr='exec') |
305 | 297 |
306 @predicate('symlink()', callexisting=True) | 298 @predicate('symlink()') |
307 def symlink(mctx, x): | 299 def symlink(mctx, x): |
308 """File that is marked as a symlink. | 300 """File that is marked as a symlink. |
309 """ | 301 """ |
310 # i18n: "symlink" is a keyword | 302 # i18n: "symlink" is a keyword |
311 getargs(x, 0, 0, _("symlink takes no arguments")) | 303 getargs(x, 0, 0, _("symlink takes no arguments")) |
352 # i18n: "portable" is a keyword | 344 # i18n: "portable" is a keyword |
353 getargs(x, 0, 0, _("portable takes no arguments")) | 345 getargs(x, 0, 0, _("portable takes no arguments")) |
354 return mctx.predicate(lambda f: util.checkwinfilename(f) is None, | 346 return mctx.predicate(lambda f: util.checkwinfilename(f) is None, |
355 predrepr='portable') | 347 predrepr='portable') |
356 | 348 |
357 @predicate('grep(regex)', callexisting=True) | 349 @predicate('grep(regex)') |
358 def grep(mctx, x): | 350 def grep(mctx, x): |
359 """File contains the given regular expression. | 351 """File contains the given regular expression. |
360 """ | 352 """ |
361 try: | 353 try: |
362 # i18n: "grep" is a keyword | 354 # i18n: "grep" is a keyword |
406 else: | 398 else: |
407 a = util.sizetoint(expr) | 399 a = util.sizetoint(expr) |
408 b = _sizetomax(expr) | 400 b = _sizetomax(expr) |
409 return lambda x: x >= a and x <= b | 401 return lambda x: x >= a and x <= b |
410 | 402 |
411 @predicate('size(expression)', callexisting=True) | 403 @predicate('size(expression)') |
412 def size(mctx, x): | 404 def size(mctx, x): |
413 """File size matches the given expression. Examples: | 405 """File size matches the given expression. Examples: |
414 | 406 |
415 - size('1k') - files from 1024 to 2047 bytes | 407 - size('1k') - files from 1024 to 2047 bytes |
416 - size('< 20k') - files less than 20480 bytes | 408 - size('< 20k') - files less than 20480 bytes |
421 expr = getstring(x, _("size requires an expression")) | 413 expr = getstring(x, _("size requires an expression")) |
422 m = sizematcher(expr) | 414 m = sizematcher(expr) |
423 return mctx.fpredicate(lambda fctx: m(fctx.size()), | 415 return mctx.fpredicate(lambda fctx: m(fctx.size()), |
424 predrepr=('size(%r)', expr), cache=True) | 416 predrepr=('size(%r)', expr), cache=True) |
425 | 417 |
426 @predicate('encoding(name)', callexisting=True) | 418 @predicate('encoding(name)') |
427 def encoding(mctx, x): | 419 def encoding(mctx, x): |
428 """File can be successfully decoded with the given character | 420 """File can be successfully decoded with the given character |
429 encoding. May not be useful for encodings other than ASCII and | 421 encoding. May not be useful for encodings other than ASCII and |
430 UTF-8. | 422 UTF-8. |
431 """ | 423 """ |
443 except UnicodeDecodeError: | 435 except UnicodeDecodeError: |
444 return False | 436 return False |
445 | 437 |
446 return mctx.fpredicate(encp, predrepr=('encoding(%r)', enc), cache=True) | 438 return mctx.fpredicate(encp, predrepr=('encoding(%r)', enc), cache=True) |
447 | 439 |
448 @predicate('eol(style)', callexisting=True) | 440 @predicate('eol(style)') |
449 def eol(mctx, x): | 441 def eol(mctx, x): |
450 """File contains newlines of the given style (dos, unix, mac). Binary | 442 """File contains newlines of the given style (dos, unix, mac). Binary |
451 files are excluded, files with mixed line endings match multiple | 443 files are excluded, files with mixed line endings match multiple |
452 styles. | 444 styles. |
453 """ | 445 """ |
564 def __init__(self, ctx, subset, status=None, badfn=None): | 556 def __init__(self, ctx, subset, status=None, badfn=None): |
565 self.ctx = ctx | 557 self.ctx = ctx |
566 self.subset = subset | 558 self.subset = subset |
567 self._status = status | 559 self._status = status |
568 self._badfn = badfn | 560 self._badfn = badfn |
569 self._existingenabled = False | 561 |
570 def status(self): | 562 def status(self): |
571 return self._status | 563 return self._status |
572 | 564 |
573 def matcher(self, patterns): | 565 def matcher(self, patterns): |
574 return self.ctx.match(patterns, badfn=self._badfn) | 566 return self.ctx.match(patterns, badfn=self._badfn) |
619 return matchmod.nevermatcher(repo.root, repo.getcwd(), | 611 return matchmod.nevermatcher(repo.root, repo.getcwd(), |
620 badfn=self._badfn) | 612 badfn=self._badfn) |
621 | 613 |
622 def filter(self, files): | 614 def filter(self, files): |
623 return [f for f in files if f in self.subset] | 615 return [f for f in files if f in self.subset] |
624 def existing(self): | |
625 if not self._existingenabled: | |
626 raise error.ProgrammingError('unexpected existing() invocation') | |
627 if self._status is not None: | |
628 removed = set(self._status[3]) | |
629 unknown = set(self._status[4] + self._status[5]) | |
630 else: | |
631 removed = set() | |
632 unknown = set() | |
633 return (f for f in self.subset | |
634 if (f in self.ctx and f not in removed) or f in unknown) | |
635 | 616 |
636 def switch(self, ctx, status=None): | 617 def switch(self, ctx, status=None): |
637 subset = self.filter(_buildsubset(ctx, status)) | 618 subset = self.filter(_buildsubset(ctx, status)) |
638 return matchctx(ctx, subset, status, self._badfn) | 619 return matchctx(ctx, subset, status, self._badfn) |
639 | 620 |
681 return getmatch(mctx, tree) | 662 return getmatch(mctx, tree) |
682 | 663 |
683 def _buildstatus(ctx, tree, basectx=None): | 664 def _buildstatus(ctx, tree, basectx=None): |
684 # do we need status info? | 665 # do we need status info? |
685 | 666 |
686 # temporaty boolean to simplify the next conditional | 667 if _intree(_statuscallers, tree): |
687 purewdir = ctx.rev() is None and basectx is None | |
688 | |
689 if (_intree(_statuscallers, tree) or | |
690 # Using matchctx.existing() on a workingctx requires us to check | |
691 # for deleted files. | |
692 (purewdir and _intree(_existingcallers, tree))): | |
693 unknown = _intree(['unknown'], tree) | 668 unknown = _intree(['unknown'], tree) |
694 ignored = _intree(['ignored'], tree) | 669 ignored = _intree(['ignored'], tree) |
695 | 670 |
696 r = ctx.repo() | 671 r = ctx.repo() |
697 if basectx is None: | 672 if basectx is None: |
709 """ | 684 """ |
710 for name, func in registrarobj._table.iteritems(): | 685 for name, func in registrarobj._table.iteritems(): |
711 symbols[name] = func | 686 symbols[name] = func |
712 if func._callstatus: | 687 if func._callstatus: |
713 _statuscallers.add(name) | 688 _statuscallers.add(name) |
714 if func._callexisting: | 689 |
715 _existingcallers.add(name) | 690 # load built-in predicates explicitly to setup _statuscallers |
716 | |
717 # load built-in predicates explicitly to setup _statuscallers/_existingcallers | |
718 loadpredicate(None, None, predicate) | 691 loadpredicate(None, None, predicate) |
719 | 692 |
720 # tell hggettext to extract docstrings from these functions: | 693 # tell hggettext to extract docstrings from these functions: |
721 i18nfunctions = symbols.values() | 694 i18nfunctions = symbols.values() |