Commit d5a754d9 authored by Jim Fulton's avatar Jim Fulton

- Now create a minimal setup.py if it doesn't exist and issue a

  warning that it is being created.

- Fixed bug in saving installed configuration data.  %'s and extra
  spaces weren't quoted.
parent 7281489a
...@@ -60,6 +60,9 @@ class Buildout(dict): ...@@ -60,6 +60,9 @@ class Buildout(dict):
def __init__(self, config_file, cloptions): def __init__(self, config_file, cloptions):
config_file = os.path.abspath(config_file) config_file = os.path.abspath(config_file)
self._config_file = config_file self._config_file = config_file
if not os.path.exists(config_file):
print 'Warning: creating', config_file
open(config_file, 'w').write('[buildout]\nparts = \n')
super(Buildout, self).__init__() super(Buildout, self).__init__()
...@@ -376,10 +379,15 @@ class Buildout(dict): ...@@ -376,10 +379,15 @@ class Buildout(dict):
def _read_installed_part_options(self): def _read_installed_part_options(self):
old = self._installed_path() old = self._installed_path()
if os.path.isfile(old): if os.path.isfile(old):
parser = ConfigParser.SafeConfigParser() parser = ConfigParser.SafeConfigParser(_spacey_defaults)
parser.read(old) parser.read(old)
return dict([ return dict([
(section, Options(self, section, parser.items(section))) (section,
Options(self, section,
[item for item in parser.items(section)
if item[0] not in _spacey_defaults]
)
)
for section in parser.sections()]) for section in parser.sections()])
else: else:
return {'buildout': Options(self, 'buildout', {'parts': ''})} return {'buildout': Options(self, 'buildout', {'parts': ''})}
...@@ -453,13 +461,44 @@ class Buildout(dict): ...@@ -453,13 +461,44 @@ class Buildout(dict):
for section in sections: for section in sections:
_save_options(section, self[section], sys.stdout) _save_options(section, self[section], sys.stdout)
print print
_spacey_nl = re.compile('^[ \t\r\f\v]+'
'|''[ \t\r\f\v]*\n[ \t\r\f\v\n]*'
'|'
'[ \t\r\f\v]+$'
)
def _quote_spacey_nl(match):
match = match.group(0).split('\n', 1)
result = '\n\t'.join(
[(s
.replace(' ', '%(__buildout_space__)s')
.replace('\r', '%(__buildout_space_r__)s')
.replace('\f', '%(__buildout_space_f__)s')
.replace('\v', '%(__buildout_space_v__)s')
.replace('\n', '%(__buildout_space_n__)s')
)
for s in match]
)
return result
_spacey_defaults = dict(
__buildout_space__ = ' ',
__buildout_space_r__ = '\r',
__buildout_space_f__ = '\f',
__buildout_space_v__ = '\v',
__buildout_space_n__ = '\n',
)
def _save_options(section, options, f): def _save_options(section, options, f):
print >>f, '[%s]' % section print >>f, '[%s]' % section
items = options.items() items = options.items()
items.sort() items.sort()
for option, value in items: for option, value in items:
print >>f, option, '=', str(value).replace('\n', '\n\t') value = value.replace('%', '%%')
value = _spacey_nl.sub(_quote_spacey_nl, value)
print >>f, option, '=', value
def _open(base, filename, seen): def _open(base, filename, seen):
......
...@@ -1066,7 +1066,7 @@ database is shown. ...@@ -1066,7 +1066,7 @@ database is shown.
eggs-directory = /tmp/sample-buildout/eggs eggs-directory = /tmp/sample-buildout/eggs
executable = /usr/local/bin/python2.3 executable = /usr/local/bin/python2.3
installed = /tmp/sample-buildout/.installed.cfg installed = /tmp/sample-buildout/.installed.cfg
log-format = %(name)s: %(message)s log-format = %%(name)s: %%(message)s
log-level = WARNING log-level = WARNING
parts = parts =
parts-directory = /tmp/sample-buildout/parts parts-directory = /tmp/sample-buildout/parts
...@@ -1141,18 +1141,16 @@ Bootstrapping ...@@ -1141,18 +1141,16 @@ Bootstrapping
If zc.buildout is installed, you can use it to create a new buildout If zc.buildout is installed, you can use it to create a new buildout
with it's own local copies of zc.buildout and setuptools and with with it's own local copies of zc.buildout and setuptools and with
local buildout scripts. There must be an existing setup.cfg: local buildout scripts.
>>> sample_bootstrapped = mkdtemp('sample-bootstrapped') >>> sample_bootstrapped = mkdtemp('sample-bootstrapped')
>>> write(sample_bootstrapped, 'setup.cfg',
... '''
... [buildout]
... parts = foo this will not be read :)
... ''')
>>> print system(buildout >>> print system(buildout
... +' -c'+os.path.join(sample_bootstrapped, 'setup.cfg') ... +' -c'+os.path.join(sample_bootstrapped, 'setup.cfg')
... +' bootstrap'), ... +' bootstrap'),
Warning: creating /sample-bootstrapped/setup.cfg
Note that a basic setup.cfg was created for us.
>>> ls(sample_bootstrapped) >>> ls(sample_bootstrapped)
d bin d bin
...@@ -1173,7 +1171,7 @@ local buildout scripts. There must be an existing setup.cfg: ...@@ -1173,7 +1171,7 @@ local buildout scripts. There must be an existing setup.cfg:
Note that, in this example, we were using a development egg for the Note that, in this example, we were using a development egg for the
buildout, and the ac.buildout egg ended up as an egg link. buildout, and the zc.buildout egg ended up as an egg link.
Also not that the buildout script was installed but not run. To run Also not that the buildout script was installed but not run. To run
the buildout, we'd have to run the installed buildout script. the buildout, we'd have to run the installed buildout script.
...@@ -61,6 +61,71 @@ It is an error to create a variable-reference cycle: ...@@ -61,6 +61,71 @@ It is an error to create a variable-reference cycle:
[('buildout', 'y'), ('buildout', 'z'), ('buildout', 'x')], [('buildout', 'y'), ('buildout', 'z'), ('buildout', 'x')],
('buildout', 'y')) ('buildout', 'y'))
""" """
def test_comparing_saved_options_with_funny_characters():
"""
If an option has newlines, extra/odd spaces or a %, we need to make
sure the comparison with the saved value works correctly.
>>> mkdir(sample_buildout, 'recipes')
>>> write(sample_buildout, 'recipes', 'debug.py',
... '''
... class Debug:
... def __init__(self, buildout, name, options):
... options['debug'] = \"\"\" <zodb>
...
... <filestorage>
... path foo
... </filestorage>
...
... </zodb>
... \"\"\"
... options['debug2'] = ' x '
... options['debug3'] = '42'
... options['format'] = '%3d'
...
... def install(self):
... open('t', 'w').write('t')
... return 't'
... ''')
>>> write(sample_buildout, 'recipes', 'setup.py',
... '''
... from setuptools import setup
... setup(
... name = "recipes",
... entry_points = {'zc.buildout': ['default = debug:Debug']},
... )
... ''')
>>> write(sample_buildout, 'recipes', 'README.txt', " ")
>>> write(sample_buildout, 'buildout.cfg',
... '''
... [buildout]
... develop = recipes
... parts = debug
...
... [debug]
... recipe = recipes
... ''')
>>> os.chdir(sample_buildout)
>>> buildout = os.path.join(sample_buildout, 'bin', 'buildout')
>>> print system(buildout+' -v'), # doctest: +ELLIPSIS
buildout: Running ...setup.py -q develop ...
buildout: Installing debug
If we run the buildout again, we shoudn't get a message about
uninstalling anything because the configuration hasn't changed.
>>> print system(buildout+' -v'),
buildout: Running setup.py -q develop ...
buildout: Installing debug
"""
def linkerSetUp(test): def linkerSetUp(test):
zc.buildout.testing.buildoutSetUp(test, clear_home=False) zc.buildout.testing.buildoutSetUp(test, clear_home=False)
...@@ -136,6 +201,7 @@ def test_suite(): ...@@ -136,6 +201,7 @@ def test_suite():
(re.compile('executable = \S+python\S*'), (re.compile('executable = \S+python\S*'),
'executable = python'), 'executable = python'),
(re.compile('setuptools-\S+[.]egg'), 'setuptools.egg'), (re.compile('setuptools-\S+[.]egg'), 'setuptools.egg'),
(re.compile('creating \S*setup.cfg'), 'creating setup.cfg'),
]) ])
), ),
...@@ -154,7 +220,13 @@ def test_suite(): ...@@ -154,7 +220,13 @@ def test_suite():
), ),
doctest.DocTestSuite( doctest.DocTestSuite(
setUp=zc.buildout.testing.buildoutSetUp, setUp=zc.buildout.testing.buildoutSetUp,
tearDown=zc.buildout.testing.buildoutTearDown), tearDown=zc.buildout.testing.buildoutTearDown,
checker=PythonNormalizing([
(re.compile("buildout: Running \S*setup.py"),
'buildout: Running setup.py'),
]),
)
)) ))
if __name__ == '__main__': if __name__ == '__main__':
......
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