Patchwork [3,of,4] templater: move repo, ui and cache to per-engine resources

login
register
mail settings
Submitter Yuya Nishihara
Date Dec. 21, 2017, 3:08 p.m.
Message ID <c06827f22f361f8e1ff3.1513868926@mimosa>
Download mbox | patch
Permalink /patch/26381/
State Accepted
Headers show

Comments

Yuya Nishihara - Dec. 21, 2017, 3:08 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1513861530 -32400
#      Thu Dec 21 22:05:30 2017 +0900
# Node ID c06827f22f361f8e1ff3431c18ed0734708149ed
# Parent  420618063c2cf0ab50e06e075b2feb49eef77767
templater: move repo, ui and cache to per-engine resources

Patch

diff --git a/hgext/show.py b/hgext/show.py
--- a/hgext/show.py
+++ b/hgext/show.py
@@ -252,7 +252,9 @@  def showstack(ui, repo, displayer):
     # our simplicity and the customizations required.
     # TODO use proper graph symbols from graphmod
 
-    shortesttmpl = formatter.maketemplater(ui, '{shortest(node, %d)}' % nodelen)
+    tres = formatter.templateresources(ui, repo)
+    shortesttmpl = formatter.maketemplater(ui, '{shortest(node, %d)}' % nodelen,
+                                           resources=tres)
     def shortest(ctx):
         return shortesttmpl.render({'ctx': ctx, 'node': ctx.hex()})
 
@@ -438,7 +440,10 @@  def longestshortest(repo, revs, minlen=4
     If we fail to do this, a value of e.g. ``10023`` could mean either
     revision 10023 or node ``10023abc...``.
     """
-    tmpl = formatter.maketemplater(repo.ui, '{shortest(node, %d)}' % minlen)
+    tres = formatter.templateresources(repo.ui, repo)
+    tmpl = formatter.maketemplater(repo.ui, '{shortest(node, %d)}' % minlen,
+                                   resources=tres)
+
     lens = [minlen]
     for rev in revs:
         ctx = repo[rev]
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -1843,10 +1843,11 @@  class changeset_templater(changeset_prin
         diffopts = diffopts or {}
 
         changeset_printer.__init__(self, ui, repo, matchfn, diffopts, buffered)
-        self.t = formatter.loadtemplater(ui, tmplspec,
+        tres = formatter.templateresources(ui, repo)
+        self.t = formatter.loadtemplater(ui, tmplspec, resources=tres,
                                          cache=templatekw.defaulttempl)
         self._counter = itertools.count()
-        self.cache = {}
+        self.cache = tres['cache']  # shared with _graphnodeformatter()
 
         self._tref = tmplspec.ref
         self._parts = {'header': '', 'footer': '',
@@ -1887,11 +1888,8 @@  class changeset_templater(changeset_prin
         props = props.copy()
         props.update(templatekw.keywords)
         props['ctx'] = ctx
-        props['repo'] = self.repo
-        props['ui'] = self.repo.ui
         props['index'] = index = next(self._counter)
         props['revcache'] = {'copies': copies}
-        props['cache'] = self.cache
         props = pycompat.strkwargs(props)
 
         # write separator, which wouldn't work well with the header part below
@@ -2657,16 +2655,14 @@  def _graphnodeformatter(ui, displayer):
         return templatekw.showgraphnode  # fast path for "{graphnode}"
 
     spec = templater.unquotestring(spec)
-    templ = formatter.maketemplater(ui, spec)
-    cache = {}
+    tres = formatter.templateresources(ui)
     if isinstance(displayer, changeset_templater):
-        cache = displayer.cache  # reuse cache of slow templates
+        tres['cache'] = displayer.cache  # reuse cache of slow templates
+    templ = formatter.maketemplater(ui, spec, resources=tres)
     props = templatekw.keywords.copy()
-    props['cache'] = cache
     def formatnode(repo, ctx):
         props['ctx'] = ctx
         props['repo'] = repo
-        props['ui'] = repo.ui
         props['revcache'] = {}
         return templ.render(props)
     return formatnode
diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -2365,8 +2365,8 @@  def debugtemplate(ui, repo, tmpl, **opts
             ui.note(("* expanded:\n"), templater.prettyformat(newtree), '\n')
 
     if revs is None:
-        t = formatter.maketemplater(ui, tmpl)
-        props['ui'] = ui
+        tres = formatter.templateresources(ui, repo)
+        t = formatter.maketemplater(ui, tmpl, resources=tres)
         ui.write(t.render(props))
     else:
         displayer = cmdutil.makelogtemplater(ui, repo, tmpl)
diff --git a/mercurial/filemerge.py b/mercurial/filemerge.py
--- a/mercurial/filemerge.py
+++ b/mercurial/filemerge.py
@@ -569,7 +569,8 @@  def _formatlabels(repo, fcd, fco, fca, l
     ui = repo.ui
     template = ui.config('ui', 'mergemarkertemplate')
     template = templater.unquotestring(template)
-    tmpl = formatter.maketemplater(ui, template)
+    tres = formatter.templateresources(ui, repo)
+    tmpl = formatter.maketemplater(ui, template, resources=tres)
 
     pad = max(len(l) for l in labels)
 
diff --git a/mercurial/formatter.py b/mercurial/formatter.py
--- a/mercurial/formatter.py
+++ b/mercurial/formatter.py
@@ -363,11 +363,11 @@  class templateformatter(baseformatter):
         self._out = out
         spec = lookuptemplate(ui, topic, opts.get('template', ''))
         self._tref = spec.ref
-        self._t = loadtemplater(ui, spec, cache=templatekw.defaulttempl)
+        self._t = loadtemplater(ui, spec, resources=templateresources(ui),
+                                cache=templatekw.defaulttempl)
         self._parts = templatepartsmap(spec, self._t,
                                        ['docheader', 'docfooter', 'separator'])
         self._counter = itertools.count()
-        self._cache = {}  # for templatekw/funcs to store reusable data
         self._renderitem('docheader', {})
 
     def _showitem(self):
@@ -395,7 +395,7 @@  class templateformatter(baseformatter):
             props['repo'] = props['ctx'].repo()
             props['revcache'] = {}
         props = pycompat.strkwargs(props)
-        g = self._t(ref, ui=self._ui, cache=self._cache, **props)
+        g = self._t(ref, **props)
         self._out.write(templater.stringify(g))
 
     def end(self):
@@ -486,6 +486,15 @@  def maketemplater(ui, tmpl, resources=No
         t.cache[''] = tmpl
     return t
 
+def templateresources(ui, repo=None):
+    """Create a dict of template resources designed for the default templatekw
+    and function"""
+    return {
+        'cache': {},  # for templatekw/funcs to store reusable data
+        'repo': repo,
+        'ui': ui,
+    }
+
 def formatter(ui, out, topic, opts):
     template = opts.get("template", "")
     if template == "json":
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
@@ -204,6 +204,10 @@  never cause crash:
   $ hg log -r 'wdir()' -T '{manifest}\n'
   
 
+Internal resources shouldn't be exposed (issue5699):
+
+  $ hg log -r. -T '{cache}{repo}{templ}{ui}'
+
 Quoting for ui.logtemplate
 
   $ hg tip --config "ui.logtemplate={rev}\n"