[PATCH] templater: add 'env()' to fetch environment variables

Matt Harbison mharbison72 at gmail.com
Mon Jan 16 22:28:17 EST 2017


On Mon, 16 Jan 2017 07:25:24 -0500, Yuya Nishihara <yuya at tcha.org> wrote:

> On Sun, 15 Jan 2017 15:30:56 -0500, Matt Harbison wrote:
>> # HG changeset patch
>> # User Matt Harbison <matt_harbison at yahoo.com>
>> # Date 1484508143 18000
>> #      Sun Jan 15 14:22:23 2017 -0500
>> # Node ID 2ba757de67ce1347d088a4d9f947efe5d407ffdd
>> # Parent  4c0a5a256ae806fab18d56b3c44a8d1c98a40ce0
>> templater: add 'env()' to fetch environment variables
>>
>> Template files ignore custom items in [templates] and [templatealias]
>> (presumably by design).  We have a couple repositories that host  
>> multiple
>> products, and use tags consisting of product, OS, and version.  The  
>> {latesttag}
>> template supports a filtering pattern, but I didn't see any other way  
>> to get the
>> customized pattern per product/OS into the file, without duplicating  
>> the file
>> for each combination.  (Yes, there is %include, but letting the build  
>> system
>> supply this missing piece means the template file doesn't need  
>> maintenance as
>> products come and go.)
>>
>> diff --git a/mercurial/templater.py b/mercurial/templater.py
>> --- a/mercurial/templater.py
>> +++ b/mercurial/templater.py
>> @@ -14,6 +14,7 @@
>>  from .i18n import _
>>  from . import (
>>      config,
>> +    encoding,
>>      error,
>>      minirst,
>>      parser,
>> @@ -505,6 +506,20 @@
>>
>>      return ''.join(chunks)
>>
>> + at templatefunc('env([var])')
>> +def env(context, mapping, args):
>> +    """A dictionary of environment variables, or the value of the  
>> single named
>> +    variable."""
>> +    if len(args) > 1:
>> +        # i18n: "env" is a keyword
>> +        raise error.ParseError(_("env expects at most one argument"))
>> +
>> +    if len(args) == 0:
>> +        return encoding.environ
>> +
>> +    raw = evalstring(context, mapping, args[0])
>> +    return pycompat.osgetenv(raw)
>
> This can be a simple {env} (or {environ}) keyword and you can use get()
> function, e.g. {get(env, 'pattern')}. showextras() is a good example of
> building template dict.

I've got to be missing something simple.  I added this code:

@templatekeyword('environ')
def showenviron(**args):
     """A dictionary of environment variables."""

     env = encoding.environ
     env = util.sortdict((k, env[k]) for k in sorted(env))
     makemap = lambda k: {'key': k, 'value': env[k]}
     c = [makemap(k) for k in env]
     f = _showlist('environ', c, **args)
     return _hybrid(f, env, makemap,
                    lambda x: '%s=%s' % (x['key'], x['value']))


And these forms work:

$ pattern=foo ../hg log -r . -T "{get(environ, 'PATTERN')}"
foo
$ pattern=foo ../hg log -r . -T "{environ % '{key} -> {value}\n'}"
!:: -> ::\
ALLUSERSPROFILE -> C:\ProgramData
...

But this doesn't.  It spews a wall of text that looks like templater  
internals:

$ pattern=foo ../hg log -r . -T "{environ}"
filestermwidthnamespacesrevcachetroublesobsoleteactivebookmarkdatep1nodebookmarks...

The {extras} template that I copy/pasted from lists key=value lines.  I  
also looked at 'namespaces', but couldn't figure out what triggered this.


More information about the Mercurial-devel mailing list