Commit 04cf959d authored by Jim Fulton's avatar Jim Fulton

Added support for repeatable buildouts by allowing egg versions to

be specified in a versions section.

Changed the log format for picked versions.
parent ae984452
......@@ -17,12 +17,15 @@ priorities include:
Change History
**************
1.0.0b21 (2007-03-??)
1.0.0b21 (2007-03-06)
=====================
Feature Changes
---------------
- Added support for repeatable buildouts by allowing egg versions to
be specified in a versions section.
- The easy_install module install and build functions now accept a
versions argument that supplied to mapping from project name to
version numbers. This can be used to fix version numbers for
......
......@@ -142,6 +142,10 @@ class Buildout(UserDict.DictMixin):
options['newest'] = newest
self.newest = newest == 'true'
versions = options.get('versions')
if versions:
zc.buildout.easy_install.default_versions(dict(self[versions]))
def _buildout_path(self, *names):
return os.path.join(self._buildout_dir, *names)
......
......@@ -1598,10 +1598,9 @@ database is shown.
>>> print system(buildout+' -v'),
zc.buildout.easy_install: Installing ['zc.buildout', 'setuptools']
zc.buildout.easy_install: We have a develop egg for zc.buildout
zc.buildout.easy_install: Picked version for zc.buildout = 1.0.0
zc.buildout.easy_install: We have the best distribution that satisfies
setuptools
zc.buildout.easy_install: Picked version for setuptools = 0.6
zc.buildout.easy_install.picked: setuptools = 0.6
<BLANKLINE>
Configuration data:
[buildout]
......
......@@ -31,6 +31,7 @@ import zc.buildout
default_index_url = os.environ.get('buildout-testing-index-url')
logger = logging.getLogger('zc.buildout.easy_install')
picked = logging.getLogger('zc.buildout.easy_install.picked')
url_match = re.compile('[a-z0-9+.-]+://').match
......@@ -348,10 +349,11 @@ class Installer:
# Check whether we picked a version and, if we did, report it:
if not (
len(requirement.specs) == 1 and requirement.specs[0][0] == '=='
dist.precedence == pkg_resources.DEVELOP_DIST
or
(len(requirement.specs) == 1 and requirement.specs[0][0] == '==')
):
logger.debug('Picked version for %s = %s',
dist.project_name, dist.version)
picked.debug('%s = %s', dist.project_name, dist.version)
return dist
......
......@@ -247,15 +247,15 @@ reporting that a version was picked automatically:
zc.buildout.easy_install DEBUG
We have the best distribution that satisfies
demo
zc.buildout.easy_install DEBUG
Picked version for demo = 0.3
zc.buildout.easy_install.picked DEBUG
demo = 0.3
zc.buildout.easy_install DEBUG
Getting required demoneeded
zc.buildout.easy_install DEBUG
We have the best distribution that satisfies
demoneeded
zc.buildout.easy_install DEBUG
Picked version for demoneeded = 1.1
zc.buildout.easy_install.picked DEBUG
demoneeded = 1.1
>>> handler.uninstall()
>>> logging.getLogger('zc.buildout.easy_install').propagate = True
......
Repeatable buildouts: controlling eggs used
===========================================
One of the goals of zc.buildout is to provide enough control to make
buildouts repeatable. It should be possible to check the buildout
configuration files for a project into a version control system and
later use the checked in files to get the same buildout, subject to
changes in the environment outside the buildout.
An advantage of using Python eggs is that depenencies of eggs used are
automatically determined and used. The automatic inclusion of
depenent distributions is at odds with the goal of repeatable
buildouts.
To support repeatable buildouts, a versions section can be created
with options for each distribution name whos version is to be fixed.
The section can then be specified via the buildout versions option.
To see how this works, we'll create two versions of a recipe egg:
>>> mkdir('recipe')
>>> write('recipe', 'recipe.py',
... '''
... class Recipe:
... def __init__(*a): pass
... def install(self):
... print 'recipe v1'
... return ()
... update = install
... ''')
>>> write('recipe', 'setup.py',
... '''
... from setuptools import setup
... setup(name='spam', version='1', py_modules=['recipe'],
... entry_points={'zc.buildout': ['default = recipe:Recipe']},
... )
... ''')
>>> write('recipe', 'README', '')
>>> print system(buildout+' setup recipe bdist_egg'), # doctest: +ELLIPSIS
buildout: Running setup script recipe/setup.py
...
>>> rmdir('recipe', 'build')
>>> write('recipe', 'recipe.py',
... '''
... class Recipe:
... def __init__(*a): pass
... def install(self):
... print 'recipe v2'
... return ()
... update = install
... ''')
>>> write('recipe', 'setup.py',
... '''
... from setuptools import setup
... setup(name='spam', version='2', py_modules=['recipe'],
... entry_points={'zc.buildout': ['default = recipe:Recipe']},
... )
... ''')
>>> print system(buildout+' setup recipe bdist_egg'), # doctest: +ELLIPSIS
buildout: Running setup script recipe/setup.py
...
and we'll configure a buildout to use it:
>>> write('buildout.cfg',
... '''
... [buildout]
... parts = foo
... find-links = %s
...
... [foo]
... recipe = spam
... ''' % join('recipe', 'dist'))
If we run the buildout, it will use version 2:
>>> print system(buildout),
zc.buildout.easy_install: Getting new distribution for spam
zc.buildout.easy_install: Got spam 2
buildout: Installing foo
recipe v2
We can specify a versions section that lists our recipe and name it in
the buildout section:
>>> write('buildout.cfg',
... '''
... [buildout]
... parts = foo
... find-links = %s
... versions = release-1
...
... [release-1]
... spam = 1
... eggs = 2.2
...
... [foo]
... recipe = spam
... ''' % join('recipe', 'dist'))
Here we created a release-1 section listing the version 1 for the spam
distribution. We told the buildout to use it by specifying release-1
as in the versions option.
Now, if we run the buildout, we'll use version 1 of the spam recipe:
>>> print system(buildout),
zc.buildout.easy_install: Getting new distribution for spam==1
zc.buildout.easy_install: Got spam 1
buildout: Uninstalling foo
buildout: Installing foo
recipe v1
Running the buildout in verbose mode will help us get information
about versions used. If we run the buildout in verbose mode without
specifying a versions section:
>>> print system(buildout+' buildout:versions= -v'), # doctest: +ELLIPSIS
zc.buildout.easy_install: Installing ['zc.buildout', 'setuptools']
zc.buildout.easy_install: We have a develop egg for zc.buildout
zc.buildout.easy_install: We have the best distribution that satisfies
setuptools
zc.buildout.easy_install.picked: setuptools = 0.6
zc.buildout.easy_install: Installing ['spam']
zc.buildout.easy_install: We have the best distribution that satisfies
spam
zc.buildout.easy_install.picked: spam = 2
...
buildout: Uninstalling foo
buildout: Installing foo
recipe v2
We'll get output that includes lines that tell us what versions
buildout chose a for us, like::
zc.buildout.easy_install.picked: spam = 2
This allows us to discover versions that are picked dynamically, so
that we can fix them in a versions section.
If we run the buildout with the versions section:
>>> print system(buildout+' -v'), # doctest: +ELLIPSIS
zc.buildout.easy_install: Installing ['zc.buildout', 'setuptools']
zc.buildout.easy_install: We have a develop egg for zc.buildout
zc.buildout.easy_install: We have the best distribution that satisfies
setuptools
zc.buildout.easy_install.picked: setuptools = 0.6
zc.buildout.easy_install: Installing ['spam']
zc.buildout.easy_install: We have the best distribution that satisfies
spam==1
...
buildout: Uninstalling foo
buildout: Installing foo
recipe v1
We won't get output for the spam distribution, which we didn't pick,
but we will get output for setuptools, which we didn't specify
versions for.
......@@ -1420,7 +1420,7 @@ def test_suite():
import zc.buildout.testselectingpython
suite = unittest.TestSuite((
doctest.DocFileSuite(
'buildout.txt', 'runsetup.txt',
'buildout.txt', 'runsetup.txt', 'repeatable.txt',
setUp=zc.buildout.testing.buildoutSetUp,
tearDown=zc.buildout.testing.buildoutTearDown,
checker=renormalizing.RENormalizing([
......@@ -1436,8 +1436,8 @@ def test_suite():
'zc.buildout.egg'),
(re.compile('creating \S*setup.cfg'), 'creating setup.cfg'),
(re.compile('hello\%ssetup' % os.path.sep), 'hello/setup'),
(re.compile('Picked version for (\S+) = \S+'),
'Picked version for \\1 = V.V'),
(re.compile('zc.buildout.easy_install.picked: (\S+) = \S+'),
'picked \\1 = V.V'),
])
),
......
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