[PATCH 07 of 10 V5] rcutil: let environ override system configs (BC)

Matt Harbison mharbison72 at gmail.com
Fri Apr 7 03:14:50 UTC 2017


On Mon, 27 Mar 2017 02:02:06 -0400, Jun Wu <quark at fb.com> wrote:

> # HG changeset patch
> # User Jun Wu <quark at fb.com>
> # Date 1490589217 25200
> #      Sun Mar 26 21:33:37 2017 -0700
> # Node ID 38572bb2cffd815526a727bc6f3aacdca2902f4f
> # Parent  9b0aa30bf151b6c0e999b017fd328e29440bd447
> # Available At https://bitbucket.org/quark-zju/hg-draft
> #              hg pull https://bitbucket.org/quark-zju/hg-draft -r  
> 38572bb2cffd
> rcutil: let environ override system configs (BC)
>
> This is BC because system configs won't be able to override $EDITOR,  
> $PAGER.
> The new behavior is arguably more rational.

I'm not sure if this is a broader concern than just the test suite with  
env-based config, but I bisected a new Windows failure back to this change.

--- c:/Users/Matt/Projects/hg/tests/test-check-code.t
+++ c:/Users/Matt/Projects/hg/tests/test-check-code.t.err
@@ -9,34 +9,7 @@

    $ hg locate -X contrib/python-zstandard -X hgext/fsmonitor/pywatchman |
    > sed 's-\\-/-g' | xargs "$check_code" --warnings --per-file=0 || false
-  Skipping i18n/polib.py it has no-che?k-code (glob)
-  mercurial/demandimport.py:312:
-   >     if os.environ.get('HGDEMANDIMPORT') != 'disable':
-   use encoding.environ instead (py3)
-  mercurial/encoding.py:54:
-   >     environ = os.environ
-   use encoding.environ instead (py3)
-  mercurial/encoding.py:56:
-   >     environ = os.environb
-   use encoding.environ instead (py3)
-  mercurial/encoding.py:61:
-   >                    for k, v in os.environ.items())
-   use encoding.environ instead (py3)
-  mercurial/encoding.py:221:
-   >                    for k, v in os.environ.items())
-   use encoding.environ instead (py3)
-  Skipping mercurial/httpclient/__init__.py it has no-che?k-code (glob)
-  Skipping mercurial/httpclient/_readers.py it has no-che?k-code (glob)
-  mercurial/policy.py:46:
-   >     if 'HGMODULEPOLICY' in os.environ:
-   use encoding.environ instead (py3)
-  mercurial/policy.py:47:
-   >         policy = os.environ['HGMODULEPOLICY'].encode('utf-8')
-   use encoding.environ instead (py3)
-  mercurial/policy.py:49:
-   >     policy = os.environ.get('HGMODULEPOLICY', policy)
-   use encoding.environ instead (py3)
-  Skipping mercurial/statprof.py it has no-che?k-code (glob)
+  /usr/bin/env: python: Bad file number
    [1]

  @commands in debugcommands.py should be in alphabetical order.


> diff --git a/mercurial/commands.py b/mercurial/commands.py
> --- a/mercurial/commands.py
> +++ b/mercurial/commands.py
> @@ -1807,4 +1807,6 @@ def config(ui, repo, *values, **opts):
>          if t == 'path':
>              ui.debug('read config from: %s\n' % f)
> +        elif t == 'items':
> +            pass
>          else:
>              raise error.ProgrammingError('unknown rctype: %s' % t)
> diff --git a/mercurial/rcutil.py b/mercurial/rcutil.py
> --- a/mercurial/rcutil.py
> +++ b/mercurial/rcutil.py
> @@ -77,8 +77,12 @@ def rccomponents():
>      name, value, source) that should fill the config directly.
>      '''
> +    envrc = ('items', envrcitems())
> +
>      global _rccomponents
>      if _rccomponents is None:
>          if 'HGRCPATH' in encoding.environ:
> -            _rccomponents = []
> +            # assume HGRCPATH is all about user configs so environments  
> can be
> +            # overridden.
> +            _rccomponents = [envrc]
>              for p in  
> encoding.environ['HGRCPATH'].split(pycompat.ospathsep):
>                  if not p:
> @@ -86,5 +90,8 @@ def rccomponents():
>                  _rccomponents.extend(('path', p) for p in  
> _expandrcpath(p))
>          else:
> -            paths = defaultrcpath() + systemrcpath() + userrcpath()
> +            paths = defaultrcpath() + systemrcpath()
>              _rccomponents = [('path', os.path.normpath(p)) for p in  
> paths]
> +            _rccomponents.append(envrc)
> +            paths = userrcpath()
> +            _rccomponents.extend(('path', os.path.normpath(p)) for p in  
> paths)
>      return _rccomponents
> diff --git a/mercurial/ui.py b/mercurial/ui.py
> --- a/mercurial/ui.py
> +++ b/mercurial/ui.py
> @@ -212,8 +212,18 @@ class ui(object):
>          """Create a ui and load global and user configs"""
>          u = cls()
> -        # we always trust global config files
> +        # we always trust global config files and environment variables
>          for t, f in rcutil.rccomponents():
>              if t == 'path':
>                  u.readconfig(f, trust=True)
> +            elif t == 'items':
> +                sections = set()
> +                for section, name, value, source in f:
> +                    # do not set u._ocfg
> +                    # XXX clean this up once immutable config object is  
> a thing
> +                    u._tcfg.set(section, name, value, source)
> +                    u._ucfg.set(section, name, value, source)
> +                    sections.add(section)
> +                for section in sections:
> +                    u.fixconfig(section=section)
>              else:
>                  raise error.ProgrammingError('unknown rctype: %s' % t)
> diff --git a/tests/test-config-env.py b/tests/test-config-env.py
> new file mode 100644
> --- /dev/null
> +++ b/tests/test-config-env.py
> @@ -0,0 +1,48 @@
> +# Test the config layer generated by environment variables
> +
> +from __future__ import absolute_import, print_function
> +
> +import os
> +
> +from mercurial import (
> +    encoding,
> +    rcutil,
> +    ui as uimod,
> +)
> +
> +testtmp = encoding.environ['TESTTMP']
> +
> +# prepare hgrc files
> +def join(name):
> +    return os.path.join(testtmp, name)
> +
> +with open(join('sysrc'), 'w') as f:
> +    f.write('[ui]\neditor=e0\n[pager]\npager=p0\n')
> +
> +with open(join('userrc'), 'w') as f:
> +    f.write('[ui]\neditor=e1')
> +
> +# replace rcpath functions so they point to the files above
> +def systemrcpath():
> +    return [join('sysrc')]
> +
> +def userrcpath():
> +    return [join('userrc')]
> +
> +rcutil.systemrcpath = systemrcpath
> +rcutil.userrcpath = userrcpath
> +os.path.isdir = lambda x: False # hack: do not load default.d/*.rc
> +
> +# utility to print configs
> +def printconfigs(env):
> +    encoding.environ = env
> +    rcutil._rccomponents = None # reset cache
> +    ui = uimod.ui.load()
> +    for section, name, value in ui.walkconfig():
> +        source = ui.configsource(section, name)
> +        print('%s.%s=%s # %s' % (section, name, value, source))
> +    print('')
> +
> +# environment variable overrides
> +printconfigs({})
> +printconfigs({'EDITOR': 'e2', 'PAGER': 'p2'})
> diff --git a/tests/test-config-env.py.out b/tests/test-config-env.py.out
> new file mode 100644
> --- /dev/null
> +++ b/tests/test-config-env.py.out
> @@ -0,0 +1,6 @@
> +pager.pager=p0 # $TESTTMP/sysrc:4
> +ui.editor=e1 # $TESTTMP/userrc:2
> +
> +pager.pager=p2 # $PAGER
> +ui.editor=e1 # $TESTTMP/userrc:2
> +
> diff --git a/tests/test-config.t b/tests/test-config.t
> --- a/tests/test-config.t
> +++ b/tests/test-config.t
> @@ -165,2 +165,16 @@ edit failure
>    abort: edit failed: false exited with status 1
>    [255]
> +
> +config affected by environment variables
> +
> +  $ EDITOR=e1 VISUAL=e2 hg config --debug | grep 'ui\.editor'
> +  $VISUAL: ui.editor=e2
> +
> +  $ VISUAL=e2 hg config --debug --config ui.editor=e3 | grep  
> 'ui\.editor'
> +  --config: ui.editor=e3
> +
> +  $ PAGER=p1 hg config --debug | grep 'pager\.pager'
> +  $PAGER: pager.pager=p1
> +
> +  $ PAGER=p1 hg config --debug --config pager.pager=p2 | grep  
> 'pager\.pager'
> +  --config: pager.pager=p2
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


More information about the Mercurial-devel mailing list