Patchwork [2,of,4] templater: switch 'revcache' based on new mapping items

login
register
mail settings
Submitter Yuya Nishihara
Date March 22, 2018, 3:02 p.m.
Message ID <9cb74d4a9abe21e1c990.1521730962@mimosa>
Download mbox | patch
Permalink /patch/29789/
State Accepted
Headers show

Comments

Yuya Nishihara - March 22, 2018, 3:02 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1521118367 -32400
#      Thu Mar 15 21:52:47 2018 +0900
# Node ID 9cb74d4a9abe21e1c9902dc17a145be6ab289173
# Parent  5614b5980fa6a42b7d85761389e30deab997bc3f
templater: switch 'revcache' based on new mapping items

It was pretty easy to leave a stale 'revcache' when switching 'ctx'.
Let's make it be automatically replaced.

Patch

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -909,7 +909,7 @@  def rendertemplate(ctx, tmpl, props=None
     tres = formatter.templateresources(repo.ui, repo)
     t = formatter.maketemplater(repo.ui, tmpl, defaults=templatekw.keywords,
                                 resources=tres)
-    mapping = {'ctx': ctx, 'revcache': {}}
+    mapping = {'ctx': ctx}
     if props:
         mapping.update(props)
     return t.renderdefault(mapping)
diff --git a/mercurial/formatter.py b/mercurial/formatter.py
--- a/mercurial/formatter.py
+++ b/mercurial/formatter.py
@@ -394,14 +394,7 @@  class templateformatter(baseformatter):
         if part not in self._parts:
             return
         ref = self._parts[part]
-
-        props = {}
-        # explicitly-defined fields precede templatekw
-        props.update(item)
-        if 'ctx' in item or 'fctx' in item:
-            # but template resources must be always available
-            props['revcache'] = {}
-        self._out.write(self._t.render(ref, props))
+        self._out.write(self._t.render(ref, item))
 
     def end(self):
         baseformatter.end(self)
@@ -518,7 +511,10 @@  class templateresources(templater.resour
         return get(self, context, mapping, key)
 
     def populatemap(self, context, origmapping, newmapping):
-        return {}
+        mapping = {}
+        if self._hasctx(newmapping):
+            mapping['revcache'] = {}  # per-ctx cache
+        return mapping
 
     def _getsome(self, context, mapping, key):
         v = mapping.get(key)
@@ -526,6 +522,9 @@  class templateresources(templater.resour
             return v
         return self._resmap.get(key)
 
+    def _hasctx(self, mapping):
+        return 'ctx' in mapping or 'fctx' in mapping
+
     def _getctx(self, context, mapping, key):
         ctx = mapping.get('ctx')
         if ctx is not None:
@@ -545,7 +544,7 @@  class templateresources(templater.resour
         'ctx': _getctx,
         'fctx': _getsome,
         'repo': _getrepo,
-        'revcache': _getsome,  # per-ctx cache; set later
+        'revcache': _getsome,
         'ui': _getsome,
     }
     _knownkeys = set(_gettermap.keys())
diff --git a/mercurial/hgweb/webutil.py b/mercurial/hgweb/webutil.py
--- a/mercurial/hgweb/webutil.py
+++ b/mercurial/hgweb/webutil.py
@@ -392,7 +392,6 @@  def commonentry(repo, ctx):
         # filectx, but I'm not pretty sure if that would always work because
         # fctx.parents() != fctx.changectx.parents() for example.
         'ctx': ctx,
-        'revcache': {},
         'rev': ctx.rev(),
         'node': hex(node),
         'author': ctx.user(),
diff --git a/mercurial/logcmdutil.py b/mercurial/logcmdutil.py
--- a/mercurial/logcmdutil.py
+++ b/mercurial/logcmdutil.py
@@ -288,7 +288,7 @@  class changesetprinter(object):
         t = formatter.maketemplater(self.repo.ui, '{join(obsfate, "\n")}',
                                     defaults=templatekw.keywords,
                                     resources=tres)
-        obsfate = t.renderdefault({'ctx': ctx, 'revcache': {}}).splitlines()
+        obsfate = t.renderdefault({'ctx': ctx}).splitlines()
 
         if obsfate:
             for obsfateline in obsfate:
@@ -856,7 +856,7 @@  def _graphnodeformatter(ui, displayer):
     templ = formatter.maketemplater(ui, spec, defaults=templatekw.keywords,
                                     resources=tres)
     def formatnode(repo, ctx):
-        props = {'ctx': ctx, 'repo': repo, 'revcache': {}}
+        props = {'ctx': ctx, 'repo': repo}
         return templ.renderdefault(props)
     return formatnode
 
diff --git a/mercurial/templatekw.py b/mercurial/templatekw.py
--- a/mercurial/templatekw.py
+++ b/mercurial/templatekw.py
@@ -583,7 +583,7 @@  def showpredecessors(context, mapping):
     predecessors = map(hex, predecessors)
 
     return _hybrid(None, predecessors,
-                   lambda x: {'ctx': repo[x], 'revcache': {}},
+                   lambda x: {'ctx': repo[x]},
                    lambda x: scmutil.formatchangeid(repo[x]))
 
 @templatekeyword('reporoot', requires={'repo'})
@@ -607,7 +607,7 @@  def showsuccessorssets(context, mapping)
 
     data = []
     for ss in ssets:
-        h = _hybrid(None, ss, lambda x: {'ctx': repo[x], 'revcache': {}},
+        h = _hybrid(None, ss, lambda x: {'ctx': repo[x]},
                     lambda x: scmutil.formatchangeid(repo[x]))
         data.append(h)
 
@@ -647,7 +647,7 @@  def showsuccsandmarkers(context, mapping
 
         successors = [hex(n) for n in successors]
         successors = _hybrid(None, successors,
-                             lambda x: {'ctx': repo[x], 'revcache': {}},
+                             lambda x: {'ctx': repo[x]},
                              lambda x: scmutil.formatchangeid(repo[x]))
 
         # Format markers
@@ -710,7 +710,7 @@  def showparents(context, mapping):
                 ('phase', p.phasestr())]
                for p in pctxs]
     f = _showcompatlist(context, mapping, 'parent', parents)
-    return _hybrid(f, prevs, lambda x: {'ctx': repo[x], 'revcache': {}},
+    return _hybrid(f, prevs, lambda x: {'ctx': repo[x]},
                    lambda x: scmutil.formatchangeid(repo[x]), keytype=int)
 
 @templatekeyword('phase', requires={'ctx'})
@@ -737,7 +737,7 @@  def showrevslist(context, mapping, name,
     repo = context.resource(mapping, 'repo')
     f = _showcompatlist(context, mapping, name, ['%d' % r for r in revs])
     return _hybrid(f, revs,
-                   lambda x: {name: x, 'ctx': repo[x], 'revcache': {}},
+                   lambda x: {name: x, 'ctx': repo[x]},
                    pycompat.identity, keytype=int)
 
 @templatekeyword('subrepos', requires={'ctx'})