Commit 7f93ff04 authored by Godefroid Chapelle's avatar Godefroid Chapelle

Problem: some increments of default_cfg do not work

Solution: merge default_cfg in the first config without extends
parent 8376678b
...@@ -110,6 +110,8 @@ class SectionKey(object): ...@@ -110,6 +110,8 @@ class SectionKey(object):
self.value = sectionkey.value self.value = sectionkey.value
if sectionkey.history[-1].operation not in ['ADD', 'REMOVE']: if sectionkey.history[-1].operation not in ['ADD', 'REMOVE']:
self.addToHistory("OVERRIDE", sectionkey.value, sectionkey.source) self.addToHistory("OVERRIDE", sectionkey.value, sectionkey.source)
else:
self.history = copy.deepcopy(sectionkey.history)
def setDirectory(self, value): def setDirectory(self, value):
self.value = value self.value = value
...@@ -304,13 +306,19 @@ _buildout_default_options = _annotate_section({ ...@@ -304,13 +306,19 @@ _buildout_default_options = _annotate_section({
}, 'DEFAULT_VALUE') }, 'DEFAULT_VALUE')
def _get_user_config():
buildout_home = os.path.join(os.path.expanduser('~'), '.buildout')
buildout_home = os.environ.get('BUILDOUT_HOME', buildout_home)
return os.path.join(buildout_home, 'default.cfg')
@commands @commands
class Buildout(DictMixin): class Buildout(DictMixin):
COMMANDS = set() COMMANDS = set()
def __init__(self, config_file, cloptions, def __init__(self, config_file, cloptions,
user_defaults=True, use_user_defaults=True,
command=None, args=()): command=None, args=()):
__doing__ = 'Initializing.' __doing__ = 'Initializing.'
...@@ -352,26 +360,26 @@ class Buildout(DictMixin): ...@@ -352,26 +360,26 @@ class Buildout(DictMixin):
override = copy.deepcopy(cloptions.get('buildout', {})) override = copy.deepcopy(cloptions.get('buildout', {}))
# load user defaults, which override defaults # load user defaults, which override defaults
if user_defaults: user_config = _get_user_config()
if os.environ.get('BUILDOUT_HOME'): if use_user_defaults and os.path.exists(user_config):
buildout_home = os.environ['BUILDOUT_HOME'] data_buildout_copy = copy.deepcopy(data['buildout'])
else: user_defaults, _ = _open(
buildout_home = os.path.join( os.path.dirname(user_config),
os.path.expanduser('~'), '.buildout') user_config, [], data_buildout_copy,
user_config = os.path.join(buildout_home, 'default.cfg') override, set(), {}
if os.path.exists(user_config): )
data_buildout_copy = copy.deepcopy(data['buildout']) for_dl_option = _update(data, user_defaults)
_update(data, _open(os.path.dirname(user_config), user_config, else:
[], data_buildout_copy, override, user_defaults = {}
set())) for_dl_option = copy.deepcopy(data)
# load configuration files # load configuration files
if config_file: if config_file:
data_buildout_copy = copy.deepcopy(data['buildout']) data_buildout_copy = copy.deepcopy(for_dl_option['buildout'])
cfg_data = _open( cfg_data, _ = _open(
os.path.dirname(config_file), os.path.dirname(config_file),
config_file, [], data_buildout_copy, config_file, [], data_buildout_copy,
override, set() override, set(), user_defaults
) )
data = _update(data, cfg_data) data = _update(data, cfg_data)
...@@ -1774,7 +1782,10 @@ def _default_globals(): ...@@ -1774,7 +1782,10 @@ def _default_globals():
return globals_defs return globals_defs
def _open(base, filename, seen, dl_options, override, downloaded):
def _open(
base, filename, seen, dl_options, override, downloaded, user_defaults
):
"""Open a configuration file and return the result as a dictionary, """Open a configuration file and return the result as a dictionary,
Recursively open other files based on buildout options found. Recursively open other files based on buildout options found.
...@@ -1842,16 +1853,19 @@ def _open(base, filename, seen, dl_options, override, downloaded): ...@@ -1842,16 +1853,19 @@ def _open(base, filename, seen, dl_options, override, downloaded):
if extends: if extends:
extends = extends.split() extends = extends.split()
eresult = _open(base, extends.pop(0), seen, dl_options, override, eresult, user_defaults = _open(base, extends.pop(0), seen, dl_options, override,
downloaded) downloaded, user_defaults)
for fname in extends: for fname in extends:
next_extend = _open(base, fname, seen, dl_options, override, next_extend, user_defaults = _open(base, fname, seen, dl_options, override,
downloaded) downloaded, user_defaults)
eresult = _update(eresult, next_extend) eresult = _update(eresult, next_extend)
result = _update(eresult, result) result = _update(eresult, result)
else:
if user_defaults:
result = _update(user_defaults, result)
user_defaults = {}
seen.pop() seen.pop()
return result return result, user_defaults
ignore_directories = '.svn', 'CVS', '__pycache__', '.git' ignore_directories = '.svn', 'CVS', '__pycache__', '.git'
...@@ -2116,7 +2130,7 @@ def main(args=None): ...@@ -2116,7 +2130,7 @@ def main(args=None):
config_file = 'buildout.cfg' config_file = 'buildout.cfg'
verbosity = 0 verbosity = 0
options = [] options = []
user_defaults = True use_user_defaults = True
debug = False debug = False
while args: while args:
if args[0][0] == '-': if args[0][0] == '-':
...@@ -2128,7 +2142,7 @@ def main(args=None): ...@@ -2128,7 +2142,7 @@ def main(args=None):
elif op[0] == 'q': elif op[0] == 'q':
verbosity -= 10 verbosity -= 10
elif op[0] == 'U': elif op[0] == 'U':
user_defaults = False use_user_defaults = False
elif op[0] == 'o': elif op[0] == 'o':
options.append(('buildout', 'offline', 'true')) options.append(('buildout', 'offline', 'true'))
elif op[0] == 'O': elif op[0] == 'O':
...@@ -2199,7 +2213,7 @@ def main(args=None): ...@@ -2199,7 +2213,7 @@ def main(args=None):
try: try:
try: try:
buildout = Buildout(config_file, options, buildout = Buildout(config_file, options,
user_defaults, command, args) use_user_defaults, command, args)
getattr(buildout, command)(args) getattr(buildout, command)(args)
except SystemExit: except SystemExit:
logging.shutdown() logging.shutdown()
......
...@@ -20,7 +20,7 @@ from zc.buildout.tests import easy_install_SetUp ...@@ -20,7 +20,7 @@ from zc.buildout.tests import easy_install_SetUp
from zc.buildout.tests import normalize_bang from zc.buildout.tests import normalize_bang
def increment_default_cfg(): def default_cfg():
r""" r"""
>>> home = tmpdir('home') >>> home = tmpdir('home')
>>> mkdir(home, '.buildout') >>> mkdir(home, '.buildout')
...@@ -55,7 +55,7 @@ def increment_default_cfg(): ...@@ -55,7 +55,7 @@ def increment_default_cfg():
""" """
def increment_default_cfg_extensions(): def default_cfg_extensions():
r""" r"""
Add two extensions as develop eggs Add two extensions as develop eggs
...@@ -146,79 +146,137 @@ def increment_default_cfg_extensions(): ...@@ -146,79 +146,137 @@ def increment_default_cfg_extensions():
... ...
versions= versions versions= versions
DEFAULT_VALUE DEFAULT_VALUE
>>> print_(system(buildout, env=env), end='')
demo ext ['buildout', 'versions']
demo2 ext ['buildout', 'versions']
Develop: '/sample-buildout/demo'
Develop: '/sample-buildout/demo2'
demo unload ['buildout', 'versions']
demo2 unload ['buildout', 'versions']
""" """
def default_cfg_extensions_with_extends_increment_in_base(): def with_extends_increment_in_base():
r""" r"""
Add two extensions as develop eggs >>> home = tmpdir('home')
>>> mkdir(home, '.buildout')
>>> mkdir('demo') >>> default_cfg = join(home, '.buildout', 'default.cfg')
>>> write('demo', 'demo.py', ''' >>> write(default_cfg, '''
... import sys ... [buildout]
... def ext(buildout): ... extensions = demo
... sys.stdout.write('demo %s %s\\n' % ('ext', sorted(buildout)))
... def unload(buildout):
... sys.stdout.write('demo %s %s\\n' % ('unload', sorted(buildout)))
... ''') ... ''')
>>> write('demo', 'setup.py', ''' >>> write('base.cfg', '''
... from setuptools import setup ... [buildout]
... ... extensions += demo2
... setup(
... name = "demo",
... entry_points = {
... 'zc.buildout.extension': ['ext = demo:ext'],
... 'zc.buildout.unloadextension': ['ext = demo:unload'],
... },
... )
... ''') ... ''')
>>> mkdir('demo2') >>> write('buildout.cfg', '''
>>> write('demo2', 'demo2.py', ''' ... [buildout]
... import sys ... extends = base.cfg
... def ext(buildout): ... parts =
... sys.stdout.write('demo2 %s %s\\n' % ('ext', sorted(buildout)))
... def unload(buildout):
... sys.stdout.write('demo2 %s %s\\n' % ('unload', sorted(buildout)))
... ''') ... ''')
>>> write('demo2', 'setup.py', ''' >>> env = dict(HOME=home, USERPROFILE=home)
... from setuptools import setup >>> print_(system(buildout+' annotate buildout', env=env), end='')
... # doctest: +ELLIPSIS
<BLANKLINE>
Annotated sections
==================
<BLANKLINE>
[buildout]
... ...
... setup( extensions= demo
... name = "demo2", demo2
... entry_points = { /home/.buildout/default.cfg
... 'zc.buildout.extension': ['ext = demo2:ext'], += base.cfg
... 'zc.buildout.unloadextension': ['ext = demo2:unload'], ...
... }, versions= versions
... ) DEFAULT_VALUE
"""
def with_extends_increment_in_base2():
r"""
>>> home = tmpdir('home')
>>> mkdir(home, '.buildout')
>>> default_cfg = join(home, '.buildout', 'default.cfg')
>>> write(default_cfg, '''
... [buildout]
... extensions = demo
... ''') ... ''')
>>> write('buildout.cfg', ''' >>> write('base.cfg', '''
... [buildout] ... [buildout]
... develop = demo demo2 ... ''')
>>> write('base2.cfg', '''
... [buildout]
... extensions += demo2
... ''')
>>> write('buildout.cfg', '''
... [buildout]
... extends = base.cfg
... base2.cfg
... parts = ... parts =
... ''') ... ''')
>>> env = dict(HOME=home, USERPROFILE=home)
>>> print_(system(buildout+' annotate buildout', env=env), end='')
... # doctest: +ELLIPSIS
<BLANKLINE>
Annotated sections
==================
<BLANKLINE>
[buildout]
...
extensions= demo
demo2
/home/.buildout/default.cfg
+= base2.cfg
...
versions= versions
DEFAULT_VALUE
"""
Run buildout once without extensions to actually develop the eggs.
(Develop happens after loading extensions.)
>>> print_(system(buildout), end='') def with_extends_increment_in_base2_and_base3():
Develop: '/sample-buildout/demo' r"""
Develop: '/sample-buildout/demo2' >>> home = tmpdir('home')
>>> ls("develop-eggs") >>> mkdir(home, '.buildout')
- demo.egg-link >>> default_cfg = join(home, '.buildout', 'default.cfg')
- demo2.egg-link >>> write(default_cfg, '''
- zc.recipe.egg.egg-link ... [buildout]
... extensions = demo
... ''')
>>> write('base.cfg', '''
... [buildout]
... ''')
>>> write('base2.cfg', '''
... [buildout]
... extensions += demo2
... ''')
>>> write('base3.cfg', '''
... [buildout]
... extensions += demo3
... ''')
>>> write('buildout.cfg', '''
... [buildout]
... extends = base.cfg
... base2.cfg
... base3.cfg
... parts =
... ''')
>>> env = dict(HOME=home, USERPROFILE=home)
>>> print_(system(buildout+' annotate buildout', env=env), end='')
... # doctest: +ELLIPSIS
<BLANKLINE>
Annotated sections
==================
<BLANKLINE>
[buildout]
...
extensions= demo
demo2
demo3
/home/.buildout/default.cfg
+= base2.cfg
+= base3.cfg
...
versions= versions
DEFAULT_VALUE
"""
extensions in .buildout/default.cfg
incremented in base.cfg
buildout.cfg extends base.cfg
def with_extends_increment_in_buildout():
r"""
>>> home = tmpdir('home') >>> home = tmpdir('home')
>>> mkdir(home, '.buildout') >>> mkdir(home, '.buildout')
>>> default_cfg = join(home, '.buildout', 'default.cfg') >>> default_cfg = join(home, '.buildout', 'default.cfg')
...@@ -228,12 +286,52 @@ def default_cfg_extensions_with_extends_increment_in_base(): ...@@ -228,12 +286,52 @@ def default_cfg_extensions_with_extends_increment_in_base():
... ''') ... ''')
>>> write('base.cfg', ''' >>> write('base.cfg', '''
... [buildout] ... [buildout]
... develop = demo demo2 ... ''')
>>> write('buildout.cfg', '''
... [buildout]
... extends = base.cfg
... extensions += demo2 ... extensions += demo2
... parts =
... ''')
>>> env = dict(HOME=home, USERPROFILE=home)
>>> print_(system(buildout+' annotate buildout', env=env), end='')
... # doctest: +ELLIPSIS
<BLANKLINE>
Annotated sections
==================
<BLANKLINE>
[buildout]
...
extensions= demo
demo2
/home/.buildout/default.cfg
+= buildout.cfg
...
versions= versions
DEFAULT_VALUE
"""
def with_extends_increment_in_buildout_with_base_and_root():
r"""
>>> home = tmpdir('home')
>>> mkdir(home, '.buildout')
>>> default_cfg = join(home, '.buildout', 'default.cfg')
>>> write(default_cfg, '''
... [buildout]
... extensions = demo
... ''')
>>> write('root.cfg', '''
... [buildout]
... ''')
>>> write('base.cfg', '''
... [buildout]
... extends = root.cfg
... ''') ... ''')
>>> write('buildout.cfg', ''' >>> write('buildout.cfg', '''
... [buildout] ... [buildout]
... extends = base.cfg ... extends = base.cfg
... extensions += demo2
... parts = ... parts =
... ''') ... ''')
>>> env = dict(HOME=home, USERPROFILE=home) >>> env = dict(HOME=home, USERPROFILE=home)
...@@ -248,71 +346,64 @@ def default_cfg_extensions_with_extends_increment_in_base(): ...@@ -248,71 +346,64 @@ def default_cfg_extensions_with_extends_increment_in_base():
extensions= demo extensions= demo
demo2 demo2
/home/.buildout/default.cfg /home/.buildout/default.cfg
+= base.cfg += buildout.cfg
... ...
versions= versions versions= versions
DEFAULT_VALUE DEFAULT_VALUE
>>> print_(system(buildout, env=env), end='')
demo ext ['buildout', 'versions']
demo2 ext ['buildout', 'versions']
Develop: '/sample-buildout/demo'
Develop: '/sample-buildout/demo2'
demo unload ['buildout', 'versions']
demo2 unload ['buildout', 'versions']
""" """
def test_suite(): def test_suite():
return doctest.DocTestSuite( return doctest.DocTestSuite(
setUp=easy_install_SetUp, setUp=easy_install_SetUp,
tearDown=zc.buildout.testing.buildoutTearDown, tearDown=zc.buildout.testing.buildoutTearDown,
checker=renormalizing.RENormalizing([ checker=renormalizing.RENormalizing([
zc.buildout.testing.normalize_path, zc.buildout.testing.normalize_path,
zc.buildout.testing.normalize_endings, zc.buildout.testing.normalize_endings,
zc.buildout.testing.normalize_script, zc.buildout.testing.normalize_script,
zc.buildout.testing.normalize_egg_py, zc.buildout.testing.normalize_egg_py,
zc.buildout.testing.normalize___pycache__, zc.buildout.testing.normalize___pycache__,
zc.buildout.testing.not_found, zc.buildout.testing.not_found,
zc.buildout.testing.normalize_exception_type_for_python_2_and_3, zc.buildout.testing.normalize_exception_type_for_python_2_and_3,
zc.buildout.testing.adding_find_link, zc.buildout.testing.adding_find_link,
zc.buildout.testing.python27_warning, zc.buildout.testing.python27_warning,
zc.buildout.testing.python27_warning_2, zc.buildout.testing.python27_warning_2,
normalize_bang, normalize_bang,
(re.compile(r'^(\w+\.)*(Missing\w+: )'), '\2'), (re.compile(r'^(\w+\.)*(Missing\w+: )'), '\2'),
(re.compile(r"buildout: Running \S*setup.py"), (re.compile(r"buildout: Running \S*setup.py"),
'buildout: Running setup.py'), 'buildout: Running setup.py'),
(re.compile(r'pip-\S+-'), (re.compile(r'pip-\S+-'),
'pip.egg'), 'pip.egg'),
(re.compile(r'setuptools-\S+-'), (re.compile(r'setuptools-\S+-'),
'setuptools.egg'), 'setuptools.egg'),
(re.compile(r'zc.buildout-\S+-'), (re.compile(r'zc.buildout-\S+-'),
'zc.buildout.egg'), 'zc.buildout.egg'),
(re.compile(r'pip = \S+'), 'pip = 20.0.0'), (re.compile(r'pip = \S+'), 'pip = 20.0.0'),
(re.compile(r'setuptools = \S+'), 'setuptools = 0.7.99'), (re.compile(r'setuptools = \S+'), 'setuptools = 0.7.99'),
(re.compile(r'File "\S+one.py"'), (re.compile(r'File "\S+one.py"'),
'File "one.py"'), 'File "one.py"'),
(re.compile(r'We have a develop egg: (\S+) (\S+)'), (re.compile(r'We have a develop egg: (\S+) (\S+)'),
r'We have a develop egg: \1 V'), r'We have a develop egg: \1 V'),
(re.compile(r'Picked: setuptools = \S+'), (re.compile(r'Picked: setuptools = \S+'),
'Picked: setuptools = V'), 'Picked: setuptools = V'),
(re.compile('[-d] pip'), '- pip'), (re.compile('[-d] pip'), '- pip'),
(re.compile('[-d] setuptools'), '- setuptools'), (re.compile('[-d] setuptools'), '- setuptools'),
(re.compile(r'\\[\\]?'), '/'), (re.compile(r'\\[\\]?'), '/'),
(re.compile( (re.compile(
'-q develop -mxN -d "/sample-buildout/develop-eggs'), '-q develop -mxN -d "/sample-buildout/develop-eggs'),
'-q develop -mxN -d /sample-buildout/develop-eggs' '-q develop -mxN -d /sample-buildout/develop-eggs'
), ),
(re.compile(r'^[*]...'), '...'), (re.compile(r'^[*]...'), '...'),
# for # for
# bug_92891 # bug_92891
# bootstrap_crashes_with_egg_recipe_in_buildout_section # bootstrap_crashes_with_egg_recipe_in_buildout_section
(re.compile(r"Unused options for buildout: 'eggs' 'scripts'\."), (re.compile(r"Unused options for buildout: 'eggs' 'scripts'\."),
"Unused options for buildout: 'scripts' 'eggs'."), "Unused options for buildout: 'scripts' 'eggs'."),
# Python 3.4 changed the wording of NameErrors # Python 3.4 changed the wording of NameErrors
(re.compile('NameError: global name'), 'NameError: name'), (re.compile('NameError: global name'), 'NameError: name'),
# fix for test_distutils_scripts_using_import_are_properly_parsed # fix for test_distutils_scripts_using_import_are_properly_parsed
# and test_distutils_scripts_using_from_are_properly_parsed # and test_distutils_scripts_using_from_are_properly_parsed
# win32 apparently adds a " around sys.executable # win32 apparently adds a " around sys.executable
(re.compile('#!"python"'), '#!python'), (re.compile('#!"python"'), '#!python'),
]), ]),
) )
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment