Commit 93fb571e authored by Jim Fulton's avatar Jim Fulton

New features:

- When doing variable substitutions, you can omit the section name to
  refer to a variable in the same section (e.g. ${:foo}).

- When doing variable substitution, you can use the special option,
  ``_buildout_section_name_`` to get the section name.  This is most handy
  for getting the current section name (e.g. ${:_buildout_section_name_}).

- A new special option, ``<`` allows sections to be used as macros.
parent 4135c65e
...@@ -9,7 +9,9 @@ Change History ...@@ -9,7 +9,9 @@ Change History
- When doing variable substitution, you can use the special option, - When doing variable substitution, you can use the special option,
``_buildout_section_name_`` to get the section name. This is most handy ``_buildout_section_name_`` to get the section name. This is most handy
for getting the current section name (e.g. ${:_buildout_section_name_}. for getting the current section name (e.g. ${:_buildout_section_name_}).
- A new special option, ``<`` allows sections to be used as macros.
- Added annotate command for annotated sections. Displays sections - Added annotate command for annotated sections. Displays sections
key-value pairs along with the value origin. key-value pairs along with the value origin.
......
...@@ -1027,6 +1027,9 @@ class Options(UserDict.DictMixin): ...@@ -1027,6 +1027,9 @@ class Options(UserDict.DictMixin):
name = self.name name = self.name
__doing__ = 'Initializing section %s.', name __doing__ = 'Initializing section %s.', name
if '<' in self._raw:
self._raw = self._do_extend_raw(name, self._raw, [])
# force substitutions # force substitutions
for k, v in self._raw.items(): for k, v in self._raw.items():
if '${' in v: if '${' in v:
...@@ -1047,6 +1050,33 @@ class Options(UserDict.DictMixin): ...@@ -1047,6 +1050,33 @@ class Options(UserDict.DictMixin):
self.recipe = recipe_class(buildout, name, self) self.recipe = recipe_class(buildout, name, self)
buildout._parts.append(name) buildout._parts.append(name)
def _do_extend_raw(self, name, data, doing):
if name == 'buildout':
return data
if name in doing:
raise zc.buildout.UserError("Infinite extending loop %r" % name)
doing.append(name)
try:
to_do = data.pop('<', None)
if to_do is None:
return data
__doing__ = 'Loading input sections for %r', name
result = {}
for iname in to_do.split('\n'):
iname = iname.strip()
if not iname:
continue
raw = self.buildout._raw.get(iname)
if raw is None:
raise zc.buildout.UserError("No section named %r" % iname)
result.update(self._do_extend_raw(iname, raw, doing))
result.update(data)
return result
finally:
assert doing.pop() == name
def _dosub(self, option, v): def _dosub(self, option, v):
__doing__ = 'Getting option %s:%s.', self.name, option __doing__ = 'Getting option %s:%s.', self.name, option
seen = [(self.name, option)] seen = [(self.name, option)]
...@@ -1178,7 +1208,7 @@ class Options(UserDict.DictMixin): ...@@ -1178,7 +1208,7 @@ class Options(UserDict.DictMixin):
elif os.path.isfile(p): elif os.path.isfile(p):
os.remove(p) os.remove(p)
else: else:
self._buildout._logger.warn("Couldn't clean up %r.", p) self.buildout._logger.warn("Couldn't clean up %r.", p)
raise raise
finally: finally:
self._created = None self._created = None
......
...@@ -979,6 +979,55 @@ It will still be treated as a part: ...@@ -979,6 +979,55 @@ It will still be treated as a part:
parts = data-dir debug parts = data-dir debug
... ...
Extending sections (macros)
---------------------------
A section (other than the buildout section) can extend one or more
other sections using the ``<`` option. Options from the referenced
sections are copied to the refering section *before* variable
substitution. This, together with the ability to refer to variables
of the current section allows sections to be used as macros.
>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... develop = recipes
... parts = myfiles
... log-level = INFO
...
... [debug]
... recipe = recipes:debug
...
... [with_file1]
... <= debug
... file1 = ${:path}/file1
... color = red
...
... [with_file2]
... <= debug
... file2 = ${:path}/file2
... color = blue
...
... [myfiles]
... <= with_file1
... with_file2
... path = mydata
... """)
>>> print system(buildout),
Develop: '/sample-buildout/recipes'
Uninstalling debug.
Uninstalling data-dir.
Installing myfiles.
color blue
file1 mydata/file1
file2 mydata/file2
path mydata
recipe recipes:debug
In this example, the debug, with_file1 and with_file2 sections act as
macros. In particular, the variable substitutions are performed
relative to the myfiles section.
Adding and removing options Adding and removing options
--------------------------- ---------------------------
...@@ -1083,11 +1132,10 @@ Set up a buildout configuration for this extension. ...@@ -1083,11 +1132,10 @@ Set up a buildout configuration for this extension.
>>> os.chdir(sample_buildout) >>> os.chdir(sample_buildout)
>>> print system(os.path.join(sample_buildout, 'bin', 'buildout')), >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')),
Develop: '/sample-buildout/demo' Develop: '/sample-buildout/demo'
Uninstalling debug. Uninstalling myfiles.
Getting distribution for 'recipes'. Getting distribution for 'recipes'.
zip_safe flag not set; analyzing archive contents... zip_safe flag not set; analyzing archive contents...
Got recipes 0.0.0. Got recipes 0.0.0.
Uninstalling data-dir.
warning: install_lib: 'build/lib' does not exist -- no Python modules to install warning: install_lib: 'build/lib' does not exist -- no Python modules to install
Verify option values. Verify option values.
...@@ -1107,7 +1155,8 @@ Verify option values. ...@@ -1107,7 +1155,8 @@ Verify option values.
Annotated sections output shows which files are responsible for which Annotated sections output shows which files are responsible for which
operations. operations.
>>> print system(os.path.join('bin', 'buildout') + ' annotate'), # doctest: +ELLIPSIS >>> print system(os.path.join('bin', 'buildout') + ' annotate'),
... # doctest: +ELLIPSIS
<BLANKLINE> <BLANKLINE>
Annotated sections Annotated sections
================== ==================
......
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