# HG changeset patch # User Yuya Nishihara # Date 2017-04-22 12:46:14 # Node ID 13eebc189ff3f35d3eb9cf94e6406adb397361cd # Parent 12a0794fa2e397e251fd87c1fb821580e345fe9b 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. 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