# HG changeset patch # User Jun Wu # Date 1490589217 25200 # Node ID d83e51654c8af95c371608dffcc0d498d686d58a # Parent 0be96ac9199ad8c7d9280d1b9afd57d349613fe2 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. diff -r 0be96ac9199a -r d83e51654c8a mercurial/commands.py --- a/mercurial/commands.py Sun Mar 26 21:27:02 2017 -0700 +++ b/mercurial/commands.py Sun Mar 26 21:33:37 2017 -0700 @@ -1807,6 +1807,8 @@ for t, f in rcutil.rccomponents(): if t == 'path': ui.debug('read config from: %s\n' % f) + elif t == 'items': + pass else: raise error.ProgrammingError('unknown rctype: %s' % t) untrusted = bool(opts.get('untrusted')) diff -r 0be96ac9199a -r d83e51654c8a mercurial/rcutil.py --- a/mercurial/rcutil.py Sun Mar 26 21:27:02 2017 -0700 +++ b/mercurial/rcutil.py Sun Mar 26 21:33:37 2017 -0700 @@ -76,15 +76,22 @@ and is the config file path. if type is 'items', obj is a list of (section, 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: continue _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 -r 0be96ac9199a -r d83e51654c8a mercurial/ui.py --- a/mercurial/ui.py Sun Mar 26 21:27:02 2017 -0700 +++ b/mercurial/ui.py Sun Mar 26 21:33:37 2017 -0700 @@ -211,10 +211,20 @@ def load(cls): """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) return u diff -r 0be96ac9199a -r d83e51654c8a tests/test-config-env.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-config-env.py Sun Mar 26 21:33:37 2017 -0700 @@ -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 -r 0be96ac9199a -r d83e51654c8a tests/test-config-env.py.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-config-env.py.out Sun Mar 26 21:33:37 2017 -0700 @@ -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 -r 0be96ac9199a -r d83e51654c8a tests/test-config.t --- a/tests/test-config.t Sun Mar 26 21:27:02 2017 -0700 +++ b/tests/test-config.t Sun Mar 26 21:33:37 2017 -0700 @@ -164,3 +164,17 @@ $ HGEDITOR=false hg config --edit 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