##// END OF EJS Templates
fileset: remove callexisting flag and mctx.existing() (API)...
Yuya Nishihara -
r38712:5d9749c5 default
parent child Browse files
Show More
@@ -181,12 +181,7 b' def listmatch(mctx, x, y):'
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
@@ -203,9 +198,6 b' symbols = {}'
203 # filesets using matchctx.status()
198 # filesets using matchctx.status()
204 _statuscallers = set()
199 _statuscallers = set()
205
200
206 # filesets using matchctx.existing()
207 _existingcallers = set()
208
209 predicate = registrar.filesetpredicate()
201 predicate = registrar.filesetpredicate()
210
202
211 @predicate('modified()', callstatus=True)
203 @predicate('modified()', callstatus=True)
@@ -285,7 +277,7 b' def tracked(mctx, x):'
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 """
@@ -294,7 +286,7 b' def binary(mctx, x):'
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 """
@@ -303,7 +295,7 b' def exec_(mctx, x):'
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 """
@@ -354,7 +346,7 b' def portable(mctx, x):'
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 """
@@ -408,7 +400,7 b' def sizematcher(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
@@ -423,7 +415,7 b' def size(mctx, x):'
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
@@ -445,7 +437,7 b' def encoding(mctx, x):'
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
@@ -566,7 +558,7 b' class matchctx(object):'
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
@@ -621,17 +613,6 b' class matchctx(object):'
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))
@@ -683,13 +664,7 b' def match(ctx, expr, badfn=None):'
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
@@ -711,10 +686,8 b' def loadpredicate(ui, extname, registrar'
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:
715 _existingcallers.add(name)
716
689
717 # load built-in predicates explicitly to setup _statuscallers/_existingcallers
690 # load built-in predicates explicitly to setup _statuscallers
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:
@@ -247,10 +247,6 b' class filesetpredicate(_funcregistrarbas'
247 implies 'matchctx.status()' at runtime or not (False, by
247 implies 'matchctx.status()' at runtime or not (False, by
248 default).
248 default).
249
249
250 Optional argument 'callexisting' indicates whether a predicate
251 implies 'matchctx.existing()' at runtime or not (False, by
252 default).
253
254 'filesetpredicate' instance in example above can be used to
250 'filesetpredicate' instance in example above can be used to
255 decorate multiple functions.
251 decorate multiple functions.
256
252
@@ -263,9 +259,8 b' class filesetpredicate(_funcregistrarbas'
263 _getname = _funcregistrarbase._parsefuncdecl
259 _getname = _funcregistrarbase._parsefuncdecl
264 _docformat = "``%s``\n %s"
260 _docformat = "``%s``\n %s"
265
261
266 def _extrasetup(self, name, func, callstatus=False, callexisting=False):
262 def _extrasetup(self, name, func, callstatus=False):
267 func._callstatus = callstatus
263 func._callstatus = callstatus
268 func._callexisting = callexisting
269
264
270 class _templateregistrarbase(_funcregistrarbase):
265 class _templateregistrarbase(_funcregistrarbase):
271 """Base of decorator to register functions as template specific one
266 """Base of decorator to register functions as template specific one
@@ -448,27 +448,6 b" Test safety of 'encoding' on removed fil"
448 mixed
448 mixed
449 unknown
449 unknown
450
450
451 Test detection of unintentional 'matchctx.existing()' invocation
452
453 $ cat > $TESTTMP/existingcaller.py <<EOF
454 > from mercurial import registrar
455 >
456 > filesetpredicate = registrar.filesetpredicate()
457 > @filesetpredicate(b'existingcaller()', callexisting=False)
458 > def existingcaller(mctx, x):
459 > # this 'mctx.existing()' invocation is unintentional
460 > existing = set(mctx.existing())
461 > return mctx.predicate(existing.__contains__, cache=False)
462 > EOF
463
464 $ cat >> .hg/hgrc <<EOF
465 > [extensions]
466 > existingcaller = $TESTTMP/existingcaller.py
467 > EOF
468
469 $ fileset 'existingcaller()' 2>&1 | tail -1
470 *ProgrammingError: *unexpected existing() invocation* (glob)
471
472 Test 'revs(...)'
451 Test 'revs(...)'
473 ================
452 ================
474
453
General Comments 0
You need to be logged in to leave comments. Login now