comparison mercurial/templateutil.py @ 44589:fc1fa3a07af6

templater: introduce wrapper for smartset (API) I want to add a template function which takes a revset as an argument: {somefunc(..., revset(...))} ^^^^^^^^^^^ evaluates to a revslist This wrapper will provide a method to get an underlying smartset. It should also be good for performance since count(revset(...)) will no longer have to fully consume the smartset for example, but that isn't the point of this change.
author Yuya Nishihara <yuya@tcha.org>
date Sun, 15 Mar 2020 15:12:44 +0900
parents 70d42e2ad9b4
children e3e44e6e7245
comparison
equal deleted inserted replaced
44588:2a98b0cd4995 44589:fc1fa3a07af6
13 from .i18n import _ 13 from .i18n import _
14 from .pycompat import getattr 14 from .pycompat import getattr
15 from . import ( 15 from . import (
16 error, 16 error,
17 pycompat, 17 pycompat,
18 smartset,
18 util, 19 util,
19 ) 20 )
20 from .utils import ( 21 from .utils import (
21 dateutil, 22 dateutil,
22 stringutil, 23 stringutil,
404 w = makewrapped(context, mapping, self._value) 405 w = makewrapped(context, mapping, self._value)
405 return w.tobool(context, mapping) 406 return w.tobool(context, mapping)
406 407
407 def tovalue(self, context, mapping): 408 def tovalue(self, context, mapping):
408 return _unthunk(context, mapping, self._value) 409 return _unthunk(context, mapping, self._value)
410
411
412 class revslist(wrapped):
413 """Wrapper for a smartset (a list/set of revision numbers)
414
415 If name specified, the revs will be rendered with the old-style list
416 template of the given name by default.
417 """
418
419 def __init__(self, repo, revs, name=None):
420 assert isinstance(revs, smartset.abstractsmartset)
421 self._repo = repo
422 self._revs = revs
423 self._name = name
424
425 def contains(self, context, mapping, item):
426 rev = unwrapinteger(context, mapping, item)
427 return rev in self._revs
428
429 def getmember(self, context, mapping, key):
430 raise error.ParseError(_(b'not a dictionary'))
431
432 def getmin(self, context, mapping):
433 makehybriditem = self._makehybriditemfunc()
434 return makehybriditem(self._revs.min())
435
436 def getmax(self, context, mapping):
437 makehybriditem = self._makehybriditemfunc()
438 return makehybriditem(self._revs.max())
439
440 def filter(self, context, mapping, select):
441 makehybriditem = self._makehybriditemfunc()
442 frevs = self._revs.filter(lambda r: select(makehybriditem(r)))
443 # once filtered, no need to support old-style list template
444 return revslist(self._repo, frevs, name=None)
445
446 def itermaps(self, context):
447 makemap = self._makemapfunc()
448 for r in self._revs:
449 yield makemap(r)
450
451 def _makehybriditemfunc(self):
452 makemap = self._makemapfunc()
453 return lambda r: hybriditem(None, r, r, makemap)
454
455 def _makemapfunc(self):
456 repo = self._repo
457 name = self._name
458 if name:
459 return lambda r: {name: r, b'ctx': repo[r]}
460 else:
461 return lambda r: {b'ctx': repo[r]}
462
463 def join(self, context, mapping, sep):
464 return joinitems(self._revs, sep)
465
466 def show(self, context, mapping):
467 if self._name:
468 srevs = [b'%d' % r for r in self._revs]
469 return _showcompatlist(context, mapping, self._name, srevs)
470 else:
471 return self.join(context, mapping, b' ')
472
473 def tobool(self, context, mapping):
474 return bool(self._revs)
475
476 def tovalue(self, context, mapping):
477 return list(self._revs)
409 478
410 479
411 class _mappingsequence(wrapped): 480 class _mappingsequence(wrapped):
412 """Wrapper for sequence of template mappings 481 """Wrapper for sequence of template mappings
413 482