# HG changeset patch # User Matt Mackall # Date 1384807029 18000 # Node ID 3d8bfe2ecf6d33e06996ca5fb7c3622b9b150589 # Parent 64b4f0cd73369185656a36ab8823f1ac082d1d23 templater: only recursively evaluate string literals as templates (issue4103) diff -r 64b4f0cd7336 -r 3d8bfe2ecf6d hgext/color.py --- a/hgext/color.py Mon Nov 18 14:02:26 2013 -0500 +++ b/hgext/color.py Mon Nov 18 15:37:09 2013 -0500 @@ -386,9 +386,7 @@ # i18n: "label" is a keyword raise error.ParseError(_("label expects two arguments")) - thing = templater.stringify(args[1][0](context, mapping, args[1][1])) - thing = templater.runtemplate(context, mapping, - templater.compiletemplate(thing, context)) + thing = templater._evalifliteral(args[1], context, mapping) # apparently, repo could be a string that is the favicon? repo = mapping.get('repo', '') diff -r 64b4f0cd7336 -r 3d8bfe2ecf6d mercurial/templater.py --- a/mercurial/templater.py Mon Nov 18 14:02:26 2013 -0500 +++ b/mercurial/templater.py Mon Nov 18 15:37:09 2013 -0500 @@ -258,6 +258,13 @@ key = args[1][0](context, mapping, args[1][1]) yield dictarg.get(key) +def _evalifliteral(arg, context, mapping): + t = stringify(arg[0](context, mapping, arg[1])) + if arg[0] == runstring: + yield runtemplate(context, mapping, compiletemplate(t, context)) + else: + yield t + def if_(context, mapping, args): if not (2 <= len(args) <= 3): # i18n: "if" is a keyword @@ -265,11 +272,9 @@ test = stringify(args[0][0](context, mapping, args[0][1])) if test: - t = stringify(args[1][0](context, mapping, args[1][1])) - yield runtemplate(context, mapping, compiletemplate(t, context)) + yield _evalifliteral(args[1], context, mapping) elif len(args) == 3: - t = stringify(args[2][0](context, mapping, args[2][1])) - yield runtemplate(context, mapping, compiletemplate(t, context)) + yield _evalifliteral(args[2], context, mapping) def ifeq(context, mapping, args): if not (3 <= len(args) <= 4): @@ -279,11 +284,9 @@ test = stringify(args[0][0](context, mapping, args[0][1])) match = stringify(args[1][0](context, mapping, args[1][1])) if test == match: - t = stringify(args[2][0](context, mapping, args[2][1])) - yield runtemplate(context, mapping, compiletemplate(t, context)) + yield _evalifliteral(args[2], context, mapping) elif len(args) == 4: - t = stringify(args[3][0](context, mapping, args[3][1])) - yield runtemplate(context, mapping, compiletemplate(t, context)) + yield _evalifliteral(args[3], context, mapping) def join(context, mapping, args): if not (1 <= len(args) <= 2): @@ -313,8 +316,7 @@ raise error.ParseError(_("label expects two arguments")) # ignore args[0] (the label string) since this is supposed to be a a no-op - t = stringify(args[1][0](context, mapping, args[1][1])) - yield runtemplate(context, mapping, compiletemplate(t, context)) + yield _evalifliteral(args[1], context, mapping) def rstdoc(context, mapping, args): if len(args) != 2: diff -r 64b4f0cd7336 -r 3d8bfe2ecf6d tests/test-command-template.t --- a/tests/test-command-template.t Mon Nov 18 14:02:26 2013 -0500 +++ b/tests/test-command-template.t Mon Nov 18 15:37:09 2013 -0500 @@ -1594,3 +1594,15 @@ <>\n<[> <>\n<]> <>\n< + +Test recursive evaluation: + + $ hg init r + $ cd r + $ echo a > a + $ hg ci -Am '{rev}' + adding a + $ hg log -r 0 --template '{if(rev, desc)}\n' + {rev} + $ hg log -r 0 --template '{if(rev, "{author} {rev}")}\n' + test 0