# HG changeset patch # User rdamazio@google.com # Date 1550111648 28800 # Node ID 6704696141b85f4a5b6b13171548085cae4dafe5 # Parent 5f9d057ba28c10f3b7ccadff05e060c33352337b templates: adding a config() function for template customization This allows templates to be written such that users can customize them easily, or that they can be customized based on other configuration of the system. For enterprise deployments, we often have complex template aliases, and right now the only way individual users can customize those is by replacing the whole template alias (which means they won't get company-wide updates to it anymore, plus most users don't want to have to get a complex template right). With this change, they can just set a config option which feeds into our templates for common changes (e.g. whether to limit commit descriptions to the width of their terminal or not). To work around the issue of having to register the config options, I declared a dedicated section [templateconfig] for these options to be dynamically declared. They can still reference any other config option that's registered elsewhere. I only did string, bool and int at this time - list and date would add other complications with parsing the default so I'll leave that as an exercise to the reader :) Differential Revision: https://phab.mercurial-scm.org/D5959 diff -r 5f9d057ba28c -r 6704696141b8 mercurial/configitems.py --- a/mercurial/configitems.py Thu Jan 31 20:11:16 2019 +0300 +++ b/mercurial/configitems.py Wed Feb 13 18:34:08 2019 -0800 @@ -1081,6 +1081,10 @@ default=None, generic=True, ) +coreconfigitem('templateconfig', '.*', + default=dynamicdefault, + generic=True, +) coreconfigitem('trusted', 'groups', default=list, ) diff -r 5f9d057ba28c -r 6704696141b8 mercurial/templatefuncs.py --- a/mercurial/templatefuncs.py Thu Jan 31 20:11:16 2019 +0300 +++ b/mercurial/templatefuncs.py Wed Feb 13 18:34:08 2019 -0800 @@ -295,6 +295,39 @@ hint = _("get() expects a dict as first argument") raise error.ParseError(bytes(err), hint=hint) +@templatefunc('config(section, name[, default])', requires={'ui'}) +def config(context, mapping, args): + """Returns the requested hgrc config option as a string.""" + fn = context.resource(mapping, 'ui').config + return _config(context, mapping, args, fn, evalstring) + +@templatefunc('configbool(section, name[, default])', requires={'ui'}) +def configbool(context, mapping, args): + """Returns the requested hgrc config option as a boolean.""" + fn = context.resource(mapping, 'ui').configbool + return _config(context, mapping, args, fn, evalboolean) + +@templatefunc('configint(section, name[, default])', requires={'ui'}) +def configint(context, mapping, args): + """Returns the requested hgrc config option as an integer.""" + fn = context.resource(mapping, 'ui').configint + return _config(context, mapping, args, fn, evalinteger) + +def _config(context, mapping, args, configfn, defaultfn): + if not (2 <= len(args) <= 3): + raise error.ParseError(_("config expects two or three arguments")) + + # The config option can come from any section, though we specifically + # reserve the [templateconfig] section for dynamically defining options + # for this function without also requiring an extension. + section = evalstringliteral(context, mapping, args[0]) + name = evalstringliteral(context, mapping, args[1]) + if len(args) == 3: + default = defaultfn(context, mapping, args[2]) + return configfn(section, name, default) + else: + return configfn(section, name) + @templatefunc('if(expr, then[, else])') def if_(context, mapping, args): """Conditionally execute based on the result of diff -r 5f9d057ba28c -r 6704696141b8 tests/test-template-functions.t --- a/tests/test-template-functions.t Thu Jan 31 20:11:16 2019 +0300 +++ b/tests/test-template-functions.t Wed Feb 13 18:34:08 2019 -0800 @@ -1549,4 +1549,31 @@ $ HGENCODING=utf-8 hg debugtemplate "{pad('`cat utf-8`', 2, '-')}\n" \xc3\xa9- (esc) +read config options: + + $ hg log -T "{config('templateconfig', 'knob', 'foo')}\n" + foo + $ hg log -T "{config('templateconfig', 'knob', 'foo')}\n" \ + > --config templateconfig.knob=bar + bar + $ hg log -T "{configbool('templateconfig', 'knob', True)}\n" + True + $ hg log -T "{configbool('templateconfig', 'knob', True)}\n" \ + > --config templateconfig.knob=0 + False + $ hg log -T "{configint('templateconfig', 'knob', 123)}\n" + 123 + $ hg log -T "{configint('templateconfig', 'knob', 123)}\n" \ + > --config templateconfig.knob=456 + 456 + $ hg log -T "{config('templateconfig', 'knob')}\n" + devel-warn: config item requires an explicit default value: 'templateconfig.knob' at: * (glob) + + $ hg log -T "{configbool('ui', 'interactive')}\n" + False + $ hg log -T "{configbool('ui', 'interactive')}\n" --config ui.interactive=1 + True + $ hg log -T "{config('templateconfig', 'knob', if(true, 'foo', 'bar'))}\n" + foo + $ cd ..