Commit 7ab3e42d authored by jim's avatar jim

Refactored the way recipes are run and how they should be written.

If a recipe uses any data from other sections, the recipe needs to
update it's data when the recipe is constructed.

Need more discussion of this in the docs.


git-svn-id: http://svn.zope.org/repos/main/zc.buildout/trunk@68634 62d5b8a3-27da-0310-9561-8e5933582275
parent d5cc8268
......@@ -16,6 +16,7 @@
$Id$
"""
import os
import zc.buildout.egglinker
import zc.buildout.easy_install
......@@ -25,26 +26,27 @@ class Egg:
self.buildout = buildout
self.name = name
self.options = options
def install(self):
distribution = self.options.get('distribution', self.name)
links = self.options.get(
'find-links',
self.buildout['buildout'].get('find-links'),
)
links = options.get('find-links',
buildout['buildout'].get('find-links'))
if links:
links = links.split()
buildout_directory = buildout['buildout']['directory']
links = [os.path.join(buildout_directory, link)
for link in links.split()]
options['find-links'] = '\n'.join(links)
else:
links = ()
self.links = links
buildout = self.buildout
options['_b'] = buildout['buildout']['bin-directory']
options['_e'] = buildout['buildout']['eggs-directory']
def install(self):
options = self.options
distribution = options.get('distribution', self.name)
zc.buildout.easy_install.install(
distribution,
buildout.eggs,
[buildout.buildout_path(link) for link in links],
)
distribution, options['_e'], self.links)
scripts = self.options.get('scripts')
scripts = options.get('scripts')
if scripts or scripts is None:
if scripts is not None:
scripts = scripts.split()
......@@ -53,6 +55,6 @@ class Egg:
for s in scripts
])
return zc.buildout.egglinker.scripts(
[distribution], buildout.bin, [buildout.eggs],
scripts=scripts)
[distribution],
options['_b'], [options['_e']], scripts=scripts)
This diff is collapsed.
......@@ -92,9 +92,13 @@ and then we'll create a source file for our mkdir recipe:
... self.buildout = buildout
... self.name = name
... self.options = options
... options['path'] = os.path.join(
... buildout['buildout']['directory'],
... options['path'],
... )
...
... def install(self):
... path = self.buildout.buildout_path(self.options['path'])
... path = self.options['path']
... if not os.path.isdir(path):
... print 'Creating directory', os.path.basename(path)
... os.mkdir(path)
......@@ -104,14 +108,21 @@ and then we'll create a source file for our mkdir recipe:
The recipe defines a constructor that takes a buildout object, a part
name, and an options dictionary. It saves them in instance attributes.
If the path is relative, we'll interpret it as relative to the
buildout directory. The buildout object passed in is a mapping from
section name to a mapping of options for that section. The buildout
directory is available as the directory option of the buildout
section. We normalize the path and save it back into the options
directory.
**IMPORTANT**: Any time we use data from another section, it is important
to reflect that data in the recipe options, as this data is used to
decide if a part configuration has changed and a part needs to be
reinstalled.
The install method is responsible for creating the part. In this
case, we need the path of the directory to create. We'll use a
buildout option from our options dictionary. If the path is relative,
we'll interpret it relative to the buildout directory. The buildout
buildout_path method gives us a path relative to the buildout. It
uses os.path.join, so if we pass it an absolute path, we'll get the
absolute path back. (If no arguments are passed to base_path, then the
buildout directory is returned.)
path option from our options dictionary.
We made the method chatty so that we can observe what it's doing.
......@@ -134,14 +145,13 @@ installed as an egg. We need to define a setup script for this:
... )
... """)
Here we've defined a package containing just our module. We've also
defined an entry point. Entry points provide a way for an egg to
define the services it provides. Here we've said that we define a
zc.buildout entry point named default. Recipe classes must be exposed
as entry points in the zc.buildout group. we give entry points names
within the group. The name "default" is somewhat special because it
allows a recipe to be referenced using a package name without naming
an entry point.
Here we've defined a package with an entry_point. Entry points provide
a way for an egg to define the services it provides. Here we've said
that we define a zc.buildout entry point named default. Recipe
classes must be exposed as entry points in the zc.buildout group. we
give entry points names within the group. The name "default" is
somewhat special because it allows a recipe to be referenced using a
package name without naming an entry point.
We also need a README.txt for our recipes to avoid a warning:
......@@ -219,12 +229,14 @@ installed:
parts = data_dir
<BLANKLINE>
[data_dir]
__buildout_installed__ = mystuff
__buildout_signature__ = recipes-O3ypTgKOkHMqMwKvMfvHnA==
path = mystuff
__buildout_installed__ = /tmp/sample-buildout/mystuff
__buildout_signature__ = recipes-c7vHV6ekIDUPy/7fjAaYjg==
path = /tmp/sample-buildout/mystuff
recipe = recipes:mkdir
Note that the directory we installed is included in .installed.cfg.
In addition, the path option includes the actual destination
directory.
If we change the name of the directory in the configuration file,
we'll see that the directory gets removed and recreated:
......@@ -639,27 +651,27 @@ configuration and run the buildout in the usual way:
<BLANKLINE>
[debug]
__buildout_installed__ =
__buildout_signature__ = recipes-IX/o5hMSw90MtZVxRpjz0Q==
__buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
op1 = 1
op7 = 7
recipe = recipes:debug
<BLANKLINE>
[d1]
__buildout_installed__ = d1
__buildout_signature__ = recipes-IX/o5hMSw90MtZVxRpjz0Q==
path = d1
__buildout_installed__ = /tmp/sample-buildout/d1
__buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
path = /tmp/sample-buildout/d1
recipe = recipes:mkdir
<BLANKLINE>
[d2]
__buildout_installed__ = d2
__buildout_signature__ = recipes-IX/o5hMSw90MtZVxRpjz0Q==
path = d2
__buildout_installed__ = /tmp/sample-buildout/d2
__buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
path = /tmp/sample-buildout/d2
recipe = recipes:mkdir
<BLANKLINE>
[d3]
__buildout_installed__ = d3
__buildout_signature__ = recipes-IX/o5hMSw90MtZVxRpjz0Q==
path = d3
__buildout_installed__ = /tmp/sample-buildout/d3
__buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
path = /tmp/sample-buildout/d3
recipe = recipes:mkdir
Now we'll update our configuration file:
......@@ -721,33 +733,33 @@ The .installed.cfg is only updated for the recipes that ran:
<BLANKLINE>
[debug]
__buildout_installed__ =
__buildout_signature__ = recipes-IX/o5hMSw90MtZVxRpjz0Q==
__buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
op1 = 1
op7 = 7
recipe = recipes:debug
<BLANKLINE>
[d2]
__buildout_installed__ = d2
__buildout_signature__ = recipes-IX/o5hMSw90MtZVxRpjz0Q==
path = d2
__buildout_installed__ = /tmp/sample-buildout/d2
__buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
path = /tmp/sample-buildout/d2
recipe = recipes:mkdir
<BLANKLINE>
[d3]
__buildout_installed__ = data3
__buildout_signature__ = recipes-IX/o5hMSw90MtZVxRpjz0Q==
path = data3
__buildout_installed__ = /tmp/sample-buildout/data3
__buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
path = /tmp/sample-buildout/data3
recipe = recipes:mkdir
<BLANKLINE>
[d4]
__buildout_installed__ = data4
__buildout_signature__ = recipes-IX/o5hMSw90MtZVxRpjz0Q==
path = data4
__buildout_installed__ = /tmp/sample-buildout/data4
__buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
path = /tmp/sample-buildout/data4
recipe = recipes:mkdir
<BLANKLINE>
[d1]
__buildout_installed__ = d1
__buildout_signature__ = recipes-IX/o5hMSw90MtZVxRpjz0Q==
path = d1
__buildout_installed__ = /tmp/sample-buildout/d1
__buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
path = /tmp/sample-buildout/d1
recipe = recipes:mkdir
Note that the installed data for debug, d1, and d2 haven't changed,
......
......@@ -53,7 +53,7 @@ def system(command, input=''):
return o.read()
def buildoutSetUp(test):
sample = tempfile.mkdtemp('buildout-tests')
sample = tempfile.mkdtemp('sample-buildout')
for name in ('bin', 'eggs', 'parts'):
os.mkdir(os.path.join(sample, name))
......@@ -118,7 +118,7 @@ def runsetup(d):
os.chdir(here)
def create_sample_eggs(test):
sample = tempfile.mkdtemp('eggtest')
sample = tempfile.mkdtemp('sample-eggs')
test.globs['_sample_eggs_container'] = sample
test.globs['sample_eggs'] = os.path.join(sample, 'dist')
write(sample, 'README.txt', '')
......
......@@ -94,6 +94,8 @@ def test_suite():
checker=renormalizing.RENormalizing([
(re.compile('__buildout_signature__ = recipes-\S+'),
'__buildout_signature__ = recipes-SSSSSSSSSSS'),
(re.compile('\S+sample-(\w+)%s(\S+)' % os.path.sep),
r'/sample-\1/\2'),
])
),
doctest.DocFileSuite(
......
......@@ -25,6 +25,11 @@ class TestRunner:
self.buildout = buildout
self.name = name
self.options = options
options['script'] = os.path.join(buildout['buildout']['bin-directory'],
options.get('script', self.name),
)
options['_e'] = buildout['buildout']['eggs-directory']
def install(self):
distributions = [
......@@ -34,13 +39,12 @@ class TestRunner:
]
path = zc.buildout.egglinker.path(
distributions+['zope.testing'],
[self.buildout.eggs],
[self.options['_e']],
)
locations = [zc.buildout.egglinker.location(distribution,
[self.buildout.eggs])
[self.options['_e']])
for distribution in distributions]
script = self.options.get('script', self.name)
script = self.buildout.buildout_path('bin', script)
script = self.options['script']
open(script, 'w').write(tests_template % dict(
PYTHON=sys.executable,
PATH="',\n '".join(path),
......
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