Commit 6f6b3ad4 authored by Jim Fulton's avatar Jim Fulton

Added an API for use by similar recipes.

Added support for offline mode.

Used new API for test server management
parent 94378e23
...@@ -35,6 +35,14 @@ unzip ...@@ -35,6 +35,14 @@ unzip
only effective when an egg is installed. If a zipped egg already only effective when an egg is installed. If a zipped egg already
exists in the eggs directory, it will not be unzipped. exists in the eggs directory, it will not be unzipped.
scripts
Control which scripts are generated. The value should be a list of
zero or more tokens. Each tokem is either a name, or a name,
followed by an '=' and a new name. Only the named scripts are
generated. If no tokens are given, then script generation is
disabled. If the option isn't given at all, then all scripts
defined by the named eggs will be generated.
We have a link server that has a number of eggs: We have a link server that has a number of eggs:
...@@ -199,3 +207,23 @@ You can also control the name used for scripts: ...@@ -199,3 +207,23 @@ You can also control the name used for scripts:
- buildout - buildout
- foo - foo
Offline mode
------------
If the buildout offline option is set to "true", then no attempt will
be made to contact an index server:
>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = demo
... offline = true
...
... [demo]
... recipe = zc.recipe.egg
... index = eek!
... scripts = demo=foo
... """ % dict(server=link_server))
>>> print system(buildout),
Egg Recipe API for other Recipes
================================
It is common for recipes to accept a collection of egg specifications
and generate scripts based on the resulting working sets. The egg
recipe provides an API that other recipes can use.
A recipe can reuse the egg recipe, supporting the eggs, find-links,
index, python, and unzip options. This is done by creating an egg
recipe instance in a recipes's contructor. In the recipe's install
script, the egg-recipe instance's working_set method to collect the
requested eggs and working set.
To illustrate, we create a sample recipe that is a very thin layer
around the egg recipe:
>>> mkdir(sample_buildout, 'sample')
>>> write(sample_buildout, 'sample', 'sample.py',
... """
... import logging, os
... import zc.recipe.egg
...
... class Sample:
...
... def __init__(self, buildout, name, options):
... self.egg = zc.recipe.egg.Egg(buildout, name, options)
... self.name = name
... self.options = options
...
... def install(self):
... extras = self.options['extras'].split()
... requirements, ws = self.egg.working_set(extras)
... print 'Part:', self.name
... print 'Egg requirements:'
... for r in requirements:
... print r
... print 'Working set:'
... for d in ws:
... print d
... """)
Here we instantiated the egg recipe in the constructor, saving it in
an attribute. This also initialized the options dictionary.
In our install method, we called the working_set method on the
instance we saved. The working_set method takes an optional sequence
of extra requirements to be included in the working set.
>>> write(sample_buildout, 'sample', 'setup.py',
... """
... from setuptools import setup
...
... setup(
... name = "sample",
... entry_points = {'zc.buildout': ['default = sample:Sample']},
... )
... """)
>>> write(sample_buildout, 'sample', 'README.txt', " ")
>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... develop = sample
... parts = sample-part
...
... [sample-part]
... recipe = sample
... eggs = demo<0.3
... find-links = %(server)s
... index = %(server)sindex
... extras = other
... """ % dict(server=link_server))
>>> import os
>>> os.chdir(sample_buildout)
>>> buildout = os.path.join(sample_buildout, 'bin', 'buildout')
>>> print system(buildout),
Part: sample-part
Egg requirements:
demo<0.3
Working set:
demo 0.2
other 1.0
demoneeded 1.1
We can see that the options were augmented with additionl data
computed by the egg recipe by looking at .installed.cfg:
>>> cat(sample_buildout, '.installed.cfg')
[buildout]
parts = sample-part
<BLANKLINE>
[sample-part]
__buildout_installed__ =
__buildout_signature__ = sample-6aWMvV2EJ9Ijq+bR8ugArQ==
_b = /tmp/tmpb7kP9bsample-buildout/bin
_d = /tmp/tmpb7kP9bsample-buildout/develop-eggs
_e = /tmp/tmpb7kP9bsample-buildout/eggs
eggs = demo<0.3
executable = /usr/local/bin/python2.3
extras = other
find-links = http://localhost:27071/
index = http://localhost:27071/index
recipe = sample
...@@ -48,7 +48,7 @@ class Egg: ...@@ -48,7 +48,7 @@ class Egg:
python = options.get('python', buildout['buildout']['python']) python = options.get('python', buildout['buildout']['python'])
options['executable'] = buildout[python]['executable'] options['executable'] = buildout[python]['executable']
def working_set(self): def working_set(self, extra=()):
"""Separate method to just get the working set """Separate method to just get the working set
This is intended for reuse by similar recipes. This is intended for reuse by similar recipes.
...@@ -59,7 +59,15 @@ class Egg: ...@@ -59,7 +59,15 @@ class Egg:
r.strip() r.strip()
for r in options.get('eggs', self.name).split('\n') for r in options.get('eggs', self.name).split('\n')
if r.strip()] if r.strip()]
orig_distributions = distributions[:]
distributions.extend(extra)
if self.buildout['buildout'].get('offline') == 'true':
ws = zc.buildout.easy_install.working_set(
distributions, options['executable'],
[options['_d'], options['_e']]
)
else:
ws = zc.buildout.easy_install.install( ws = zc.buildout.easy_install.install(
distributions, options['_e'], distributions, options['_e'],
links = self.links, links = self.links,
...@@ -69,7 +77,7 @@ class Egg: ...@@ -69,7 +77,7 @@ class Egg:
path=[options['_d']] path=[options['_d']]
) )
return distributions, ws return orig_distributions, ws
def install(self): def install(self):
distributions, ws = self.working_set() distributions, ws = self.working_set()
......
...@@ -29,16 +29,9 @@ def setUp(test): ...@@ -29,16 +29,9 @@ def setUp(test):
'develop-eggs', 'zc.recipe.egg.egg-link'), 'develop-eggs', 'zc.recipe.egg.egg-link'),
'w').write(dirname(__file__, 4)) 'w').write(dirname(__file__, 4))
zc.buildout.testing.create_sample_eggs(test) zc.buildout.testing.create_sample_eggs(test)
test.globs['link_server'] = ( zc.buildout.testing.setUpServer(test, zc.buildout.testing.make_tree(test))
'http://localhost:%s/'
% zc.buildout.testing.start_server(zc.buildout.testing.make_tree(test))
)
def tearDown(test):
zc.buildout.testing.buildoutTearDown(test)
zc.buildout.testing.stop_server(test.globs['link_server'])
def setUpPython(test): def setUpPython(test):
zc.buildout.testing.buildoutSetUp(test, clear_home=False) zc.buildout.testing.buildoutSetUp(test, clear_home=False)
...@@ -47,17 +40,14 @@ def setUpPython(test): ...@@ -47,17 +40,14 @@ def setUpPython(test):
'w').write(dirname(__file__, 4)) 'w').write(dirname(__file__, 4))
zc.buildout.testing.multi_python(test) zc.buildout.testing.multi_python(test)
test.globs['link_server'] = ( zc.buildout.testing.setUpServer(test, zc.buildout.testing.make_tree(test))
'http://localhost:%s/'
% zc.buildout.testing.start_server(zc.buildout.testing.make_tree(test))
)
def test_suite(): def test_suite():
return unittest.TestSuite(( return unittest.TestSuite((
#doctest.DocTestSuite(), #doctest.DocTestSuite(),
doctest.DocFileSuite( doctest.DocFileSuite(
'README.txt', 'README.txt',
setUp=setUp, tearDown=tearDown, setUp=setUp, tearDown=zc.buildout.testing.buildoutTearDown,
checker=renormalizing.RENormalizing([ checker=renormalizing.RENormalizing([
(re.compile('(\S+[/%(sep)s]| )' (re.compile('(\S+[/%(sep)s]| )'
'(\\w+-)[^ \t\n%(sep)s/]+.egg' '(\\w+-)[^ \t\n%(sep)s/]+.egg'
...@@ -67,9 +57,31 @@ def test_suite(): ...@@ -67,9 +57,31 @@ def test_suite():
(re.compile('-py\d[.]\d.egg'), '-py2.4.egg'), (re.compile('-py\d[.]\d.egg'), '-py2.4.egg'),
]) ])
), ),
doctest.DocFileSuite(
'api.txt',
setUp=setUp, tearDown=zc.buildout.testing.buildoutTearDown,
checker=renormalizing.RENormalizing([
(re.compile('_b = \S+sample-buildout.bin'),
'_b = sample-buildout/bin'),
(re.compile('__buildout_signature__ = \S+'),
'__buildout_signature__ = sample-6aWMvV2EJ9Ijq+bR8ugArQ=='),
(re.compile('_d = \S+sample-buildout.develop-eggs'),
'_d = sample-buildout/develop-eggs'),
(re.compile('_e = \S+sample-buildout.eggs'),
'_e = sample-buildout/eggs'),
(re.compile('executable = \S+python\S+'),
'executable = python'),
(re.compile('index = \S+python\S+'),
'executable = python'),
(re.compile('find-links = http://localhost:\d+/'),
'find-links = http://localhost:8080/'),
(re.compile('index = http://localhost:\d+/index'),
'index = http://localhost:8080/index'),
])
),
doctest.DocFileSuite( doctest.DocFileSuite(
'selecting-python.txt', 'selecting-python.txt',
setUp=setUpPython, tearDown=tearDown, setUp=setUpPython, tearDown=zc.buildout.testing.buildoutTearDown,
checker=renormalizing.RENormalizing([ checker=renormalizing.RENormalizing([
(re.compile('\S+sample-(\w+)%s(\S+)' % os.path.sep), (re.compile('\S+sample-(\w+)%s(\S+)' % os.path.sep),
r'/sample-\1/\2'), r'/sample-\1/\2'),
......
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