Patchwork [4,of,5] registrar: add templatefunc to mark a function as template function (API)

login
register
mail settings
Submitter Katsunori FUJIWARA
Date March 29, 2016, 5:15 p.m.
Message ID <d4952c55c4b16a79bb4a.1459271742@feefifofum>
Download mbox | patch
Permalink /patch/14147/
State Accepted
Headers show

Comments

Katsunori FUJIWARA - March 29, 2016, 5:15 p.m.
# HG changeset patch
# User FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
# Date 1459271444 -32400
#      Wed Mar 30 02:10:44 2016 +0900
# Node ID d4952c55c4b16a79bb4af1335a2b613a97a535c8
# Parent  6a44183e3ca6ce60339f38e491cb0d2d6c30b460
registrar: add templatefunc to mark a function as template function (API)

This patch also adds loadfunction() to templater, because this
combination helps to figure out how they cooperate with each other.

Listing up loadfunction() in dispatch.extraloaders causes implicit
loading template function at loading (3rd party) extension.

This patch explicitly tests whether templatefunc decorator works as
expected, because there is no bundled extension, which defines
template function.

This change requires that "templatefunc" attribute of (3rd party)
extension is registrar.templatefunc or so.

Patch

diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -37,6 +37,7 @@  from . import (
     revset,
     templatefilters,
     templatekw,
+    templater,
     ui as uimod,
     util,
 )
@@ -768,6 +769,7 @@  extraloaders = [
     ('filesetpredicate', fileset, 'loadpredicate'),
     ('revsetpredicate', revset, 'loadpredicate'),
     ('templatefilter', templatefilters, 'loadfilter'),
+    ('templatefunc', templater, 'loadfunction'),
     ('templatekeyword', templatekw, 'loadkeyword'),
 ]
 
diff --git a/mercurial/registrar.py b/mercurial/registrar.py
--- a/mercurial/registrar.py
+++ b/mercurial/registrar.py
@@ -216,3 +216,29 @@  class templatefilter(_templateregistrarb
 
     Otherwise, explicit 'templatefilters.loadkeyword()' is needed.
     """
+
+class templatefunc(_templateregistrarbase):
+    """Decorator to register template function
+
+    Usage::
+
+        templatefunc = registrar.templatefunc()
+
+        @templatefunc('myfunc(arg1, arg2[, arg3])')
+        def myfuncfunc(context, mapping, args):
+            '''Explanation of this template function ....
+            '''
+            pass
+
+    The first string argument is used also in online help.
+
+    'templatefunc' instance in example above can be used to
+    decorate multiple functions.
+
+    Decorated functions are registered automatically at loading
+    extension, if an instance named as 'templatefunc' is used for
+    decorating in extension.
+
+    Otherwise, explicit 'templater.loadfunction()' is needed.
+    """
+    _getname = _funcregistrarbase._parsefuncdecl
diff --git a/mercurial/templater.py b/mercurial/templater.py
--- a/mercurial/templater.py
+++ b/mercurial/templater.py
@@ -1069,5 +1069,11 @@  def stylemap(styles, paths=None):
 
     raise RuntimeError("No hgweb templates found in %r" % paths)
 
+def loadfunction(ui, extname, registrarobj):
+    """Load template function from specified registrarobj
+    """
+    for name, func in registrarobj._table.iteritems():
+        funcs[name] = func
+
 # tell hggettext to extract docstrings from these functions:
 i18nfunctions = funcs.values()
diff --git a/tests/test-command-template.t b/tests/test-command-template.t
--- a/tests/test-command-template.t
+++ b/tests/test-command-template.t
@@ -3691,3 +3691,26 @@  utf8 filter:
   [255]
 
   $ cd ..
+
+Test that template function in extension is registered as expected
+
+  $ cd a
+
+  $ cat <<EOF > $TESTTMP/customfunc.py
+  > from mercurial import registrar
+  > 
+  > templatefunc = registrar.templatefunc()
+  > 
+  > @templatefunc('custom()')
+  > def custom(context, mapping, args):
+  >     return 'custom'
+  > EOF
+  $ cat <<EOF > .hg/hgrc
+  > [extensions]
+  > customfunc = $TESTTMP/customfunc.py
+  > EOF
+
+  $ hg log -r . -T "{custom()}\n" --config customfunc.enabled=true
+  custom
+
+  $ cd ..