Patchwork [4,of,8] formatter: add support for docheader and docfooter templates

login
register
mail settings
Submitter Yuya Nishihara
Date June 20, 2017, 3:57 p.m.
Message ID <546b89efa96a23908d59.1497974246@mimosa>
Download mbox | patch
Permalink /patch/21536/
State Accepted
Headers show

Comments

Yuya Nishihara - June 20, 2017, 3:57 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1492865174 -32400
#      Sat Apr 22 21:46:14 2017 +0900
# Node ID 546b89efa96a23908d59ff76ef13dbe8604d1ae9
# Parent  2126758ba0a19d028d59add12f8420ede690dfc9
formatter: add support for docheader and docfooter templates

templatepartsmap() is a minimal copy of changeset_templater.__init__(). I
tried to factor out a common function, but it was unnecessarily complicated.

Patch

diff --git a/mercurial/formatter.py b/mercurial/formatter.py
--- a/mercurial/formatter.py
+++ b/mercurial/formatter.py
@@ -350,8 +350,12 @@  class templateformatter(baseformatter):
         spec = lookuptemplate(ui, topic, opts.get('template', ''))
         self._tref = spec.ref
         self._t = loadtemplater(ui, spec, cache=templatekw.defaulttempl)
+        self._parts = templatepartsmap(spec, self._t,
+                                       ['docheader', 'docfooter'])
         self._counter = itertools.count()
         self._cache = {}  # for templatekw/funcs to store reusable data
+        self._renderitem('docheader', {})
+
     def context(self, **ctxs):
         '''insert context objects to be used to render template keywords'''
         ctxs = pycompat.byteskwargs(ctxs)
@@ -363,7 +367,11 @@  class templateformatter(baseformatter):
         item['index'] = next(self._counter)
         self._renderitem(self._tref, item)
 
-    def _renderitem(self, ref, item):
+    def _renderitem(self, part, item):
+        if part not in self._parts:
+            return
+        ref = self._parts[part]
+
         # TODO: add support for filectx. probably each template keyword or
         # function will have to declare dependent resources. e.g.
         # @templatekeyword(..., requires=('ctx',))
@@ -381,6 +389,10 @@  class templateformatter(baseformatter):
         g = self._t(ref, ui=self._ui, cache=self._cache, **props)
         self._out.write(templater.stringify(g))
 
+    def end(self):
+        baseformatter.end(self)
+        self._renderitem('docfooter', {})
+
 templatespec = collections.namedtuple(r'templatespec',
                                       r'ref tmpl mapfile')
 
@@ -434,6 +446,13 @@  def lookuptemplate(ui, topic, tmpl):
     # constant string?
     return templatespec('', tmpl, None)
 
+def templatepartsmap(spec, t, partnames):
+    """Create a mapping of {part: ref}"""
+    partsmap = {spec.ref: spec.ref}  # initial ref must exist in t
+    if spec.mapfile:
+        partsmap.update((p, p) for p in partnames if p in t)
+    return partsmap
+
 def loadtemplater(ui, spec, cache=None):
     """Create a templater from either a literal template or loading from
     a map file"""
diff --git a/tests/test-branches.t b/tests/test-branches.t
--- a/tests/test-branches.t
+++ b/tests/test-branches.t
@@ -530,6 +530,19 @@  template output:
   a: Adding b branch head 2
   default: Adding root node
 
+  $ cat <<'EOF' > "$TESTTMP/map-myjson"
+  > docheader = '\{\n'
+  > docfooter = '\n}\n'
+  > branches = '{ifeq(index, 0, "", ",\n")} {dict(branch, node|short)|json}'
+  > EOF
+  $ hg branches -T "$TESTTMP/map-myjson"
+  {
+   {"branch": "b", "node": "e23b5505d1ad"},
+   {"branch": "a branch *", "node": "10ff5895aa57"}, (glob)
+   {"branch": "a", "node": "d8cbc61dbaa6"},
+   {"branch": "default", "node": "19709c5a4e75"}
+  }
+
 Tests of revision branch name caching
 
 We rev branch cache is updated automatically. In these tests we use a trick to