[Checkins] SVN: zc.buildout/trunk/ Fixed some bugs in variable
substitutions.
Jim Fulton
jim at zope.com
Thu Aug 17 19:23:20 EDT 2006
Log message for revision 69629:
Fixed some bugs in variable substitutions.
The characters "-", "." and " ", weren't allowed in section or
option names.
Substitutions with invalid names were ignored, which caused
missleading failures downstream.
Changed:
U zc.buildout/trunk/README.txt
U zc.buildout/trunk/src/zc/buildout/buildout.py
U zc.buildout/trunk/src/zc/buildout/buildout.txt
U zc.buildout/trunk/src/zc/buildout/tests.py
-=-
Modified: zc.buildout/trunk/README.txt
===================================================================
--- zc.buildout/trunk/README.txt 2006-08-17 21:07:01 UTC (rev 69628)
+++ zc.buildout/trunk/README.txt 2006-08-17 23:23:19 UTC (rev 69629)
@@ -192,6 +192,14 @@
1.0.0b3
-------
+- Fixed some bugs in variable substitutions.
+
+ The characters "-", "." and " ", weren't allowed in section or
+ option names.
+
+ Substitutions with invalid names were ignored, which caused
+ missleading failures downstream.
+
- Improved error handling. No longer show tracebacks for user errors.
- Now require a recipe option (and therefore a section) for every part.
Modified: zc.buildout/trunk/src/zc/buildout/buildout.py
===================================================================
--- zc.buildout/trunk/src/zc/buildout/buildout.py 2006-08-17 21:07:01 UTC (rev 69628)
+++ zc.buildout/trunk/src/zc/buildout/buildout.py 2006-08-17 23:23:19 UTC (rev 69629)
@@ -158,12 +158,32 @@
seen.pop()
return value
- _template_split = re.compile('([$]{\w+:\w+})').split
+ _template_split = re.compile('([$]{[^}]*})').split
+ _simple = re.compile('[-a-zA-Z0-9 ._]+$').match
+ _valid = re.compile('[-a-zA-Z0-9 ._]+:[-a-zA-Z0-9 ._]+$').match
def _dosubs_esc(self, value, data, converted, seen):
value = self._template_split(value)
subs = []
- for s in value[1::2]:
- s = tuple(s[2:-1].split(':'))
+ for ref in value[1::2]:
+ s = tuple(ref[2:-1].split(':'))
+ if not self._valid(ref):
+ if len(s) < 2:
+ raise UserError("The substitution, %s,\n"
+ "doesn't contain a colon."
+ % ref)
+ if len(s) > 2:
+ raise UserError("The substitution, %s,\n"
+ "has too many colons."
+ % ref)
+ if not self._simple(s[0]):
+ raise UserError("The section name in substitution, %s,\n"
+ "has invalid characters."
+ % ref)
+ if not self._simple(s[1]):
+ raise UserError("The option name in substitution, %s,\n"
+ "has invalid characters."
+ % ref)
+
v = converted.get(s)
if v is None:
options = data.get(s[0])
@@ -414,6 +434,7 @@
old = self._installed_path()
if os.path.isfile(old):
parser = ConfigParser.SafeConfigParser(_spacey_defaults)
+ parser.optionxform = lambda s: s
parser.read(old)
return dict([
(section,
@@ -556,6 +577,7 @@
result = {}
parser = ConfigParser.SafeConfigParser()
+ parser.optionxform = lambda s: s
parser.readfp(open(filename))
extends = extended_by = None
for section in parser.sections():
Modified: zc.buildout/trunk/src/zc/buildout/buildout.txt
===================================================================
--- zc.buildout/trunk/src/zc/buildout/buildout.txt 2006-08-17 21:07:01 UTC (rev 69628)
+++ zc.buildout/trunk/src/zc/buildout/buildout.txt 2006-08-17 23:23:19 UTC (rev 69629)
@@ -212,10 +212,10 @@
... """
... [buildout]
... develop = recipes
- ... parts = data_dir
+ ... parts = data-dir
... log-level = INFO
...
- ... [data_dir]
+ ... [data-dir]
... recipe = recipes:mkdir
... path = mystuff
... """)
@@ -235,7 +235,7 @@
::
- parts = data_dir
+ parts = data-dir
Here we've named a part to be "built". We can use any name we want
except that different part names must be unique and recipes will often
@@ -251,7 +251,7 @@
::
- [data_dir]
+ [data-dir]
recipe = recipes:mkdir
path = mystuff
@@ -269,8 +269,8 @@
>>> buildout = os.path.join(sample_buildout, 'bin', 'buildout')
>>> print system(buildout),
buildout: Running /tmp/sample-buildout/recipes/setup.py -q develop ...
- buildout: Installing data_dir
- data_dir: Creating directory mystuff
+ buildout: Installing data-dir
+ data-dir: Creating directory mystuff
We see that the recipe created the directory, as expected:
@@ -289,9 +289,9 @@
>>> cat(sample_buildout, '.installed.cfg')
[buildout]
- parts = data_dir
+ parts = data-dir
<BLANKLINE>
- [data_dir]
+ [data-dir]
__buildout_installed__ = /tmp/sample-buildout/mystuff
__buildout_signature__ = recipes-c7vHV6ekIDUPy/7fjAaYjg==
path = /tmp/sample-buildout/mystuff
@@ -308,19 +308,19 @@
... """
... [buildout]
... develop = recipes
- ... parts = data_dir
+ ... parts = data-dir
... log-level = INFO
...
- ... [data_dir]
+ ... [data-dir]
... recipe = recipes:mkdir
... path = mydata
... """)
>>> print system(buildout),
buildout: Running /tmp/sample-buildout/recipes/setup.py -q develop ...
- buildout: Uninstalling data_dir
- buildout: Installing data_dir
- data_dir: Creating directory mydata
+ buildout: Uninstalling data-dir
+ buildout: Installing data-dir
+ data-dir: Creating directory mydata
>>> ls(sample_buildout)
- .installed.cfg
@@ -332,6 +332,30 @@
d parts
d recipes
+Configuration file syntax
+-------------------------
+
+As mentioned earlier, buildout configuration files use the format
+defined by the Python ConfigParser module with extensions. The
+extensions are:
+
+- option names are case sensitive
+
+- option values can ue a substitution syntax, described below, to
+ refer to option values in specific sections.
+
+The ConfigParser syntax is very flexible. Section names can contain
+any characters other than newlines and right square braces ("]").
+Option names can contain any characters other than newlines, colons,
+and equal signs, can not start with a space, and don't include
+trailing spaces.
+
+It is likely that, in the future, some characters will be given
+special buildout-defined meanings. This is already true of the
+characters ":", "$", "%", "(", and ")". For now, it is a good idea to
+keep section and option names simple, sticking to alphanumeric
+characters, hyphens, and periods.
+
Variable substitutions
----------------------
@@ -386,16 +410,17 @@
... """
... [buildout]
... develop = recipes
- ... parts = data_dir debug
+ ... parts = data-dir debug
... log-level = INFO
...
... [debug]
... recipe = recipes:debug
- ... file1 = ${data_dir:path}/file
- ... file2 = %(file1)s.out
- ... file3 = %(base)s/file3
+ ... File 1 = ${data-dir:path}/file
+ ... File 2 = %(File 1)s.out
+ ... File 3 = %(base)s/file3
+ ... File 4 = ${debug:File 3}/log
...
- ... [data_dir]
+ ... [data-dir]
... recipe = recipes:mkdir
... path = mydata
...
@@ -418,14 +443,15 @@
>>> print system(buildout),
buildout: Running /tmp/sample-buildout/recipes/setup.py -q develop ...
- buildout: Uninstalling data_dir
- buildout: Installing data_dir
- data_dir: Creating directory mydata
+ buildout: Uninstalling data-dir
+ buildout: Installing data-dir
+ data-dir: Creating directory mydata
buildout: Installing debug
+ File 1 mydata/file
+ File 2 mydata/file.out
+ File 3 var/file3
+ File 4 var/file3/log
base var
- file1 mydata/file
- file2 mydata/file.out
- file3 var/file3
recipe recipes:debug
It might seem surprising that mydata was created again. This is
@@ -436,12 +462,13 @@
>>> print system(buildout),
buildout: Running /tmp/sample-buildout/recipes/setup.py -q develop ...
- buildout: Installing data_dir
+ buildout: Installing data-dir
buildout: Installing debug
+ File 1 mydata/file
+ File 2 mydata/file.out
+ File 3 var/file3
+ File 4 var/file3/log
base var
- file1 mydata/file
- file2 mydata/file.out
- file3 var/file3
recipe recipes:debug
We can see that mydata was not recreated.
@@ -449,6 +476,10 @@
Note that, in this case, we didn't specify a log level, so
we didn't get output about what the buildout was doing.
+Section and option names in variable substitutions are only allowed to
+contain alphanumeric characters, hyphens, periods and spaces. This
+restriction might be relaxed in future releases.
+
Multiple configuration files
----------------------------
Modified: zc.buildout/trunk/src/zc/buildout/tests.py
===================================================================
--- zc.buildout/trunk/src/zc/buildout/tests.py 2006-08-17 21:07:01 UTC (rev 69628)
+++ zc.buildout/trunk/src/zc/buildout/tests.py 2006-08-17 23:23:19 UTC (rev 69629)
@@ -59,6 +59,58 @@
We're evaluating buildout:y, buildout:z, buildout:x
and are referencing: buildout:y.
+It is an error to use funny characters in variable refereces:
+
+ >>> write(sample_buildout, 'buildout.cfg',
+ ... '''
+ ... [buildout]
+ ... develop = recipes
+ ... parts = data_dir debug
+ ... x = ${bui$ldout:y}
+ ... ''')
+
+ >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')),
+ Error: The section name in substitution, ${bui$ldout:y},
+ has invalid characters.
+
+ >>> write(sample_buildout, 'buildout.cfg',
+ ... '''
+ ... [buildout]
+ ... develop = recipes
+ ... parts = data_dir debug
+ ... x = ${buildout:y{z}
+ ... ''')
+
+ >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')),
+ Error: The option name in substitution, ${buildout:y{z},
+ has invalid characters.
+
+and too have too many or too few colons:
+
+ >>> write(sample_buildout, 'buildout.cfg',
+ ... '''
+ ... [buildout]
+ ... develop = recipes
+ ... parts = data_dir debug
+ ... x = ${parts}
+ ... ''')
+
+ >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')),
+ Error: The substitution, ${parts},
+ doesn't contain a colon.
+
+ >>> write(sample_buildout, 'buildout.cfg',
+ ... '''
+ ... [buildout]
+ ... develop = recipes
+ ... parts = data_dir debug
+ ... x = ${buildout:y:z}
+ ... ''')
+
+ >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')),
+ Error: The substitution, ${buildout:y:z},
+ has too many colons.
+
Al parts have to have a section:
>>> write(sample_buildout, 'buildout.cfg',
@@ -160,7 +212,6 @@
buildout: Installing debug
"""
-
def linkerSetUp(test):
zc.buildout.testing.buildoutSetUp(test, clear_home=False)
zc.buildout.testing.multi_python(test)
More information about the Checkins
mailing list