Patchwork [5,of,9] templater: separate function to create templater from map file (API)

login
register
mail settings
Submitter Yuya Nishihara
Date April 15, 2016, 1:15 p.m.
Message ID <8831af8116bb1e105065.1460726144@mimosa>
Download mbox | patch
Permalink /patch/14644/
State Accepted
Headers show

Comments

Yuya Nishihara - April 15, 2016, 1:15 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1459693608 -32400
#      Sun Apr 03 23:26:48 2016 +0900
# Node ID 8831af8116bb1e10506529c39ace09bde10566fc
# Parent  a67a064b7ec0f57e10ce2a119d656adffadc04c1
templater: separate function to create templater from map file (API)

New frommapfile() function will make it clear when template aliases will be
loaded. They should be applied to command arguments and templates in hgrc,
but not to map files. Otherwise, our stock styles and web templates
(i.e map-file templates) could be modified unintentionally.

Future patches will add "aliases" argument to __init__(), but not to
frommapfile().

Patch

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -1478,6 +1478,7 @@  class changeset_templater(changeset_prin
     def __init__(self, ui, repo, matchfn, diffopts, tmpl, mapfile, buffered):
         changeset_printer.__init__(self, ui, repo, matchfn, diffopts, buffered)
         formatnode = ui.debugflag and (lambda x: x) or (lambda x: x[:12])
+        filters = {'formatnode': formatnode}
         defaulttempl = {
             'parent': '{rev}:{node|formatnode} ',
             'manifest': '{rev}:{node|formatnode}',
@@ -1486,10 +1487,14 @@  class changeset_templater(changeset_prin
             }
         # filecopy is preserved for compatibility reasons
         defaulttempl['filecopy'] = defaulttempl['file_copy']
-        self.t = templater.templater(mapfile, {'formatnode': formatnode},
-                                     cache=defaulttempl)
-        if tmpl:
-            self.t.cache['changeset'] = tmpl
+        assert not (tmpl and mapfile)
+        if mapfile:
+            self.t = templater.templater.frommapfile(mapfile, filters=filters,
+                                                     cache=defaulttempl)
+        else:
+            self.t = templater.templater(filters=filters, cache=defaulttempl)
+            if tmpl:
+                self.t.cache['changeset'] = tmpl
 
         self.cache = {}
 
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -2770,7 +2770,7 @@  def debuginstall(ui, **opts):
             # template found, check if it is working
             err = None
             try:
-                templater.templater(m)
+                templater.templater.frommapfile(m)
             except Exception as inst:
                 err = inst
                 p = None
@@ -3681,7 +3681,7 @@  def debugtemplate(ui, repo, tmpl, **opts
     mapfile = None
     if revs is None:
         k = 'debugtemplate'
-        t = templater.templater(mapfile)
+        t = templater.templater()
         t.cache[k] = tmpl
         ui.write(templater.stringify(t(k, **props)))
     else:
diff --git a/mercurial/filemerge.py b/mercurial/filemerge.py
--- a/mercurial/filemerge.py
+++ b/mercurial/filemerge.py
@@ -526,7 +526,7 @@  def _formatlabels(repo, fcd, fco, fca, l
 
     ui = repo.ui
     template = ui.config('ui', 'mergemarkertemplate', _defaultconflictmarker)
-    tmpl = templater.templater(None, cache={'conflictmarker': template})
+    tmpl = templater.templater(cache={'conflictmarker': template})
 
     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
@@ -190,7 +190,10 @@  def lookuptemplate(ui, topic, tmpl):
 
 def gettemplater(ui, topic, spec):
     tmpl, mapfile = lookuptemplate(ui, topic, spec)
-    t = templater.templater(mapfile, {})
+    assert not (tmpl and mapfile)
+    if mapfile:
+        return templater.templater.frommapfile(mapfile)
+    t = templater.templater()
     if tmpl:
         t.cache[topic] = tmpl
     return t
diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py
--- a/mercurial/hgweb/hgweb_mod.py
+++ b/mercurial/hgweb/hgweb_mod.py
@@ -188,20 +188,22 @@  class requestcontext(object):
 
         # create the templater
 
-        tmpl = templater.templater(mapfile,
-                                   filters={'websub': websubfilter},
-                                   defaults={'url': req.url,
-                                             'logourl': logourl,
-                                             'logoimg': logoimg,
-                                             'staticurl': staticurl,
-                                             'urlbase': urlbase,
-                                             'repo': self.reponame,
-                                             'encoding': encoding.encoding,
-                                             'motd': motd,
-                                             'sessionvars': sessionvars,
-                                             'pathdef': makebreadcrumb(req.url),
-                                             'style': style,
-                                            })
+        defaults = {
+            'url': req.url,
+            'logourl': logourl,
+            'logoimg': logoimg,
+            'staticurl': staticurl,
+            'urlbase': urlbase,
+            'repo': self.reponame,
+            'encoding': encoding.encoding,
+            'motd': motd,
+            'sessionvars': sessionvars,
+            'pathdef': makebreadcrumb(req.url),
+            'style': style,
+        }
+        tmpl = templater.templater.frommapfile(mapfile,
+                                               filters={'websub': websubfilter},
+                                               defaults=defaults)
         return tmpl
 
 
diff --git a/mercurial/hgweb/hgwebdir_mod.py b/mercurial/hgweb/hgwebdir_mod.py
--- a/mercurial/hgweb/hgwebdir_mod.py
+++ b/mercurial/hgweb/hgwebdir_mod.py
@@ -491,16 +491,17 @@  class hgwebdir(object):
         if not staticurl.endswith('/'):
             staticurl += '/'
 
-        tmpl = templater.templater(mapfile,
-                                   defaults={"encoding": encoding.encoding,
-                                             "motd": motd,
-                                             "url": url,
-                                             "logourl": logourl,
-                                             "logoimg": logoimg,
-                                             "staticurl": staticurl,
-                                             "sessionvars": sessionvars,
-                                             "style": style,
-                                             })
+        defaults = {
+            "encoding": encoding.encoding,
+            "motd": motd,
+            "url": url,
+            "logourl": logourl,
+            "logoimg": logoimg,
+            "staticurl": staticurl,
+            "sessionvars": sessionvars,
+            "style": style,
+        }
+        tmpl = templater.templater.frommapfile(mapfile, defaults=defaults)
         return tmpl
 
     def updatereqenv(self, env):
diff --git a/mercurial/templater.py b/mercurial/templater.py
--- a/mercurial/templater.py
+++ b/mercurial/templater.py
@@ -1016,10 +1016,9 @@  class TemplateNotFound(error.Abort):
 
 class templater(object):
 
-    def __init__(self, mapfile, filters=None, defaults=None, cache=None,
+    def __init__(self, filters=None, defaults=None, cache=None,
                  minchunk=1024, maxchunk=65536):
         '''set up template engine.
-        mapfile is name of file to read map definitions from.
         filters is dict of functions. each transforms a value into another.
         defaults is dict of default map definitions.'''
         if filters is None:
@@ -1036,11 +1035,15 @@  class templater(object):
         self.minchunk, self.maxchunk = minchunk, maxchunk
         self.ecache = {}
 
-        if not mapfile:
-            return
+    @classmethod
+    def frommapfile(cls, mapfile, filters=None, defaults=None, cache=None,
+                    minchunk=1024, maxchunk=65536):
+        """Create templater from the specified map file"""
+        t = cls(filters, defaults, cache, minchunk, maxchunk)
         cache, tmap = _readmapfile(mapfile)
-        self.cache.update(cache)
-        self.map = tmap
+        t.cache.update(cache)
+        t.map = tmap
+        return t
 
     def __contains__(self, key):
         return key in self.cache or key in self.map