[PATCH 4 of 4] templater: add debugtemplate command

Yuya Nishihara yuya at tcha.org
Fri Mar 11 11:40:51 EST 2016


# HG changeset patch
# User Yuya Nishihara <yuya at tcha.org>
# Date 1455379572 -32400
#      Sun Feb 14 01:06:12 2016 +0900
# Node ID df989e8a3647b71f910a956d6a15b0dc6e184366
# Parent  1fe2aaec05ba870b130398847091350e278589ba
templater: add debugtemplate command

This is useful for debugging template parsing. Several tests are ported to
this command.

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -68,6 +68,7 @@ from . import (
     sshserver,
     streamclone,
     templatekw,
+    templater,
     treediscovery,
     ui as uimod,
     util,
@@ -2757,7 +2758,6 @@ def debuginstall(ui, **opts):
     fm.condwrite(err, 'extensionserror', " %s\n", err)
 
     # templates
-    from . import templater
     p = templater.templatepaths()
     fm.write('templatedirs', 'checking templates (%s)...\n', ' '.join(p))
     fm.condwrite(not p, '', _(" no template directories found\n"))
@@ -3592,6 +3592,54 @@ def debugsuccessorssets(ui, repo, *revs)
                     ui.write(node2str(node))
             ui.write('\n')
 
+ at command('debugtemplate',
+    [('r', 'rev', [], _('apply template on changesets'), _('REV')),
+     ('D', 'define', [], _('define template keyword'), _('KEY=VALUE'))],
+    _('[-r REV]... [-D KEY=VALUE]... TEMPLATE'),
+    optionalrepo=True)
+def debugtemplate(ui, repo, tmpl, **opts):
+    """parse and apply a template
+
+    If -r/--rev is given, the template is processed as a log template and
+    applied to the given changesets. Otherwise, it is processed as a generic
+    template.
+
+    Use --verbose to print the parsed tree.
+    """
+    revs = None
+    if opts['rev']:
+        if repo is None:
+            raise error.RepoError(_('there is no Mercurial repository here '
+                                    '(.hg not found)'))
+        revs = scmutil.revrange(repo, opts['rev'])
+
+    props = {}
+    for d in opts['define']:
+        try:
+            k, v = (e.strip() for e in d.split('=', 1))
+            if not k:
+                raise ValueError
+            props[k] = v
+        except ValueError:
+            raise error.Abort(_('malformed keyword definition: %s') % d)
+
+    if ui.verbose:
+        tree = templater.parse(tmpl)
+        ui.note(templater.prettyformat(tree), '\n')
+
+    mapfile = None
+    if revs is None:
+        k = 'debugtemplate'
+        t = templater.templater(mapfile)
+        t.cache[k] = tmpl
+        ui.write(templater.stringify(t(k, **props)))
+    else:
+        displayer = cmdutil.changeset_templater(ui, repo, None, opts, tmpl,
+                                                mapfile, buffered=False)
+        for r in revs:
+            displayer.show(repo[r], **props)
+        displayer.close()
+
 @command('debugwalk', walkopts, _('[OPTION]... [FILE]...'), inferrepo=True)
 def debugwalk(ui, repo, *pats, **opts):
     """show how files match on given patterns"""
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
@@ -2861,27 +2861,55 @@ Test invalid date:
 
 Test integer literal:
 
-  $ hg log -Ra -r0 -T '{(0)}\n'
+  $ hg debugtemplate -v '{(0)}\n'
+  (template
+    (group
+      ('integer', '0'))
+    ('string', '\n'))
   0
-  $ hg log -Ra -r0 -T '{(123)}\n'
+  $ hg debugtemplate -v '{(123)}\n'
+  (template
+    (group
+      ('integer', '123'))
+    ('string', '\n'))
   123
-  $ hg log -Ra -r0 -T '{(-4)}\n'
+  $ hg debugtemplate -v '{(-4)}\n'
+  (template
+    (group
+      ('integer', '-4'))
+    ('string', '\n'))
   -4
-  $ hg log -Ra -r0 -T '{(-)}\n'
+  $ hg debugtemplate '{(-)}\n'
   hg: parse error at 2: integer literal without digits
   [255]
-  $ hg log -Ra -r0 -T '{(-a)}\n'
+  $ hg debugtemplate '{(-a)}\n'
   hg: parse error at 2: integer literal without digits
   [255]
 
 top-level integer literal is interpreted as symbol (i.e. variable name):
 
-  $ hg log -Ra -r0 -T '{1}\n'
-  
-  $ hg log -Ra -r0 -T '{if("t", "{1}")}\n'
-  
-  $ hg log -Ra -r0 -T '{1|stringify}\n'
-  
+  $ hg debugtemplate -D 1=one -v '{1}\n'
+  (template
+    ('integer', '1')
+    ('string', '\n'))
+  one
+  $ hg debugtemplate -D 1=one -v '{if("t", "{1}")}\n'
+  (template
+    (func
+      ('symbol', 'if')
+      (list
+        ('string', 't')
+        (template
+          ('integer', '1'))))
+    ('string', '\n'))
+  one
+  $ hg debugtemplate -D 1=one -v '{1|stringify}\n'
+  (template
+    (|
+      ('integer', '1')
+      ('symbol', 'stringify'))
+    ('string', '\n'))
+  one
 
 unless explicit symbol is expected:
 
@@ -2894,13 +2922,29 @@ unless explicit symbol is expected:
 
 Test string literal:
 
-  $ hg log -Ra -r0 -T '{"string with no template fragment"}\n'
+  $ hg debugtemplate -Ra -r0 -v '{"string with no template fragment"}\n'
+  (template
+    ('string', 'string with no template fragment')
+    ('string', '\n'))
   string with no template fragment
-  $ hg log -Ra -r0 -T '{"template: {rev}"}\n'
+  $ hg debugtemplate -Ra -r0 -v '{"template: {rev}"}\n'
+  (template
+    (template
+      ('string', 'template: ')
+      ('symbol', 'rev'))
+    ('string', '\n'))
   template: 0
-  $ hg log -Ra -r0 -T '{r"rawstring: {rev}"}\n'
+  $ hg debugtemplate -Ra -r0 -v '{r"rawstring: {rev}"}\n'
+  (template
+    ('string', 'rawstring: {rev}')
+    ('string', '\n'))
   rawstring: {rev}
-  $ hg log -Ra -r0 -T '{files % r"rawstring: {file}"}\n'
+  $ hg debugtemplate -Ra -r0 -v '{files % r"rawstring: {file}"}\n'
+  (template
+    (%
+      ('symbol', 'files')
+      ('string', 'rawstring: {file}'))
+    ('string', '\n'))
   rawstring: {file}
 
 Test string escaping:
diff --git a/tests/test-completion.t b/tests/test-completion.t
--- a/tests/test-completion.t
+++ b/tests/test-completion.t
@@ -108,6 +108,7 @@ Show debug commands if there are no othe
   debugsetparents
   debugsub
   debugsuccessorssets
+  debugtemplate
   debugwalk
   debugwireargs
 
@@ -272,6 +273,7 @@ Show all commands + options
   debugsetparents: 
   debugsub: rev
   debugsuccessorssets: 
+  debugtemplate: rev, define
   debugwalk: include, exclude
   debugwireargs: three, four, five, ssh, remotecmd, insecure
   files: rev, print0, include, exclude, template, subrepos
diff --git a/tests/test-help.t b/tests/test-help.t
--- a/tests/test-help.t
+++ b/tests/test-help.t
@@ -861,6 +861,8 @@ Test list of internal help commands
    debugsub      (no help text available)
    debugsuccessorssets
                  show set of successors for revision
+   debugtemplate
+                 parse and apply a template
    debugwalk     show how files match on given patterns
    debugwireargs
                  (no help text available)


More information about the Mercurial-devel mailing list