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()