registrar: define revsetpredicate to decorate revset predicate

revsetpredicate is used to replace revset.predicate and
revset.extpredicate in subsequent patches.

This patch also adds loadpredicate() to revset, because this
combination helps to figure out how the name of safe predicate is put
into safesymbols.

This patch still uses safesymbols set to examine whether the predicate
corresponded to the 'name' is safe from DoS attack or not, because
just setting func._safe property needs changes below for such
examination.

  before:
      name in revset.safesymbols

  after:
      getattr(revset.symbols.get(name, None), '_safe', False)

"automatic registration" described in help doc of revsetpredicate
class will be achieved by the subsequent patch, which lists
loadpredicate() up in dispatch.extraloaders.
This commit is contained in:
FUJIWARA Katsunori 2016-03-08 23:04:53 +09:00
parent e72a9be81f
commit 8227e106c7
2 changed files with 41 additions and 0 deletions

View File

@ -205,3 +205,36 @@ class _funcregistrarbase(object):
"""Execute exra setup for registered function, if needed
"""
pass
class revsetpredicate(_funcregistrarbase):
"""Decorator to register revset predicate
Usage::
revsetpredicate = registrar.revsetpredicate()
@revsetpredicate('mypredicate(arg1, arg2[, arg3])')
def mypredicatefunc(repo, subset, x):
'''Explanation of this revset predicate ....
'''
pass
The first string argument is used also in online help.
Optional argument 'safe' indicates whether a predicate is safe for
DoS attack (False by default).
'revsetpredicate' instance in example above can be used to
decorate multiple functions.
Decorated functions are registered automatically at loading
extension, if an instance named as 'revsetpredicate' is used for
decorating in extension.
Otherwise, explicit 'revset.loadpredicate()' is needed.
"""
_getname = _funcregistrarbase._parsefuncdecl
_docformat = "``%s``\n %s"
def _extrasetup(self, name, func, safe=False):
func._safe = safe

View File

@ -3628,5 +3628,13 @@ def prettyformatset(revs):
p = q
return '\n'.join(' ' * l + s for l, s in lines)
def loadpredicate(ui, extname, registrarobj):
"""Load revset predicates from specified registrarobj
"""
for name, func in registrarobj._table.iteritems():
symbols[name] = func
if func._safe:
safesymbols.add(name)
# tell hggettext to extract docstrings from these functions:
i18nfunctions = symbols.values()