Commit 6b30db6a authored by jim's avatar jim

On two of my machines, I got spurious test failures when a test failed

to see that a file removed by a subprocess was actually removed.
Added logic to wait for the file to disappear. :/

Whitespace cleanup. (Although there are a few required trailing white
spaces in buildout.txt.


git-svn-id: http://svn.zope.org/repos/main/zc.buildout/trunk@98178 62d5b8a3-27da-0310-9561-8e5933582275
parent cd7dbb46
...@@ -8,7 +8,7 @@ example, if we are creating an application named "Foo", then "the Foo ...@@ -8,7 +8,7 @@ example, if we are creating an application named "Foo", then "the Foo
buildout" is the collection of configuration and application-specific buildout" is the collection of configuration and application-specific
software that allows an instance of the application to be created. We software that allows an instance of the application to be created. We
may refer to such an instance of the application informally as "a Foo may refer to such an instance of the application informally as "a Foo
buildout". buildout".
This document describes how to define buildouts using buildout This document describes how to define buildouts using buildout
configuration files and recipes. There are three ways to set up the configuration files and recipes. There are three ways to set up the
...@@ -39,7 +39,7 @@ We have a sample buildout that we created using the bootstrap command ...@@ -39,7 +39,7 @@ We have a sample buildout that we created using the bootstrap command
of an existing buildout (method 3 above). It has the absolute minimum of an existing buildout (method 3 above). It has the absolute minimum
information. We have bin, develop-eggs, eggs and parts directories, information. We have bin, develop-eggs, eggs and parts directories,
and a configuration file: and a configuration file:
>>> ls(sample_buildout) >>> ls(sample_buildout)
d bin d bin
- buildout.cfg - buildout.cfg
...@@ -89,7 +89,7 @@ parts: ...@@ -89,7 +89,7 @@ parts:
A part is simply something to be created by a buildout. It can be A part is simply something to be created by a buildout. It can be
almost anything, such as a Python package, a program, a directory, or almost anything, such as a Python package, a program, a directory, or
even a configuration file. even a configuration file.
Recipes Recipes
------- -------
...@@ -97,7 +97,7 @@ Recipes ...@@ -97,7 +97,7 @@ Recipes
A part is created by a recipe. Recipes are always installed as Python A part is created by a recipe. Recipes are always installed as Python
eggs. They can be downloaded from a package server, such as the eggs. They can be downloaded from a package server, such as the
Python Package Index, or they can be developed as part of a project Python Package Index, or they can be developed as part of a project
using a "develop" egg. using a "develop" egg.
A develop egg is a special kind of egg that gets installed as an "egg A develop egg is a special kind of egg that gets installed as an "egg
link" that contains the name of a source directory. Develop eggs link" that contains the name of a source directory. Develop eggs
...@@ -113,7 +113,7 @@ directory for our local recipes: ...@@ -113,7 +113,7 @@ directory for our local recipes:
and then we'll create a source file for our mkdir recipe: and then we'll create a source file for our mkdir recipe:
>>> write(sample_buildout, 'recipes', 'mkdir.py', >>> write(sample_buildout, 'recipes', 'mkdir.py',
... """ ... """
... import logging, os, zc.buildout ... import logging, os, zc.buildout
... ...
...@@ -130,7 +130,7 @@ and then we'll create a source file for our mkdir recipe: ...@@ -130,7 +130,7 @@ and then we'll create a source file for our mkdir recipe:
... 'Cannot create %s. %s is not a directory.', ... 'Cannot create %s. %s is not a directory.',
... options['path'], os.path.dirname(options['path'])) ... options['path'], os.path.dirname(options['path']))
... raise zc.buildout.UserError('Invalid Path') ... raise zc.buildout.UserError('Invalid Path')
... ...
... ...
... def install(self): ... def install(self):
... path = self.options['path'] ... path = self.options['path']
...@@ -185,7 +185,7 @@ buildout directory. The buildout object passed in is a mapping from ...@@ -185,7 +185,7 @@ buildout directory. The buildout object passed in is a mapping from
section name to a mapping of options for that section. The buildout section name to a mapping of options for that section. The buildout
directory is available as the directory option of the buildout directory is available as the directory option of the buildout
section. We normalize the path and save it back into the options section. We normalize the path and save it back into the options
directory. directory.
The install method is responsible for creating the part. In this 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 path case, we need the path of the directory to create. We'll use a path
...@@ -214,7 +214,7 @@ provided via a setup.py script: ...@@ -214,7 +214,7 @@ provided via a setup.py script:
>>> write(sample_buildout, 'recipes', 'setup.py', >>> write(sample_buildout, 'recipes', 'setup.py',
... """ ... """
... from setuptools import setup ... from setuptools import setup
... ...
... setup( ... setup(
... name = "recipes", ... name = "recipes",
... entry_points = {'zc.buildout': ['mkdir = mkdir:Mkdir']}, ... entry_points = {'zc.buildout': ['mkdir = mkdir:Mkdir']},
...@@ -270,7 +270,7 @@ use the part name to decide what to do. ...@@ -270,7 +270,7 @@ use the part name to decide what to do.
[data-dir] [data-dir]
recipe = recipes:mkdir recipe = recipes:mkdir
path = mystuff path = mystuff
When we name a part, we also create a section of the same When we name a part, we also create a section of the same
...@@ -317,7 +317,7 @@ about the part we installed: ...@@ -317,7 +317,7 @@ about the part we installed:
Note that the directory we installed is included in .installed.cfg. Note that the directory we installed is included in .installed.cfg.
In addition, the path option includes the actual destination In addition, the path option includes the actual destination
directory. directory.
If we change the name of the directory in the configuration file, If we change the name of the directory in the configuration file,
we'll see that the directory gets removed and recreated: we'll see that the directory gets removed and recreated:
...@@ -401,7 +401,7 @@ If an error occurs during installation, it is up to the recipe to ...@@ -401,7 +401,7 @@ If an error occurs during installation, it is up to the recipe to
clean up any system side effects, such as files created. Let's update clean up any system side effects, such as files created. Let's update
the mkdir recipe to support multiple paths: the mkdir recipe to support multiple paths:
>>> write(sample_buildout, 'recipes', 'mkdir.py', >>> write(sample_buildout, 'recipes', 'mkdir.py',
... """ ... """
... import logging, os, zc.buildout ... import logging, os, zc.buildout
... ...
...@@ -413,7 +413,7 @@ the mkdir recipe to support multiple paths: ...@@ -413,7 +413,7 @@ the mkdir recipe to support multiple paths:
... # Normalize paths and check that their parent ... # Normalize paths and check that their parent
... # directories exist: ... # directories exist:
... paths = [] ... paths = []
... for path in options['path'].split(): ... for path in options['path'].split():
... path = os.path.join(buildout['buildout']['directory'], path) ... path = os.path.join(buildout['buildout']['directory'], path)
... if not os.path.isdir(os.path.dirname(path)): ... if not os.path.isdir(os.path.dirname(path)):
... logging.getLogger(self.name).error( ... logging.getLogger(self.name).error(
...@@ -425,7 +425,7 @@ the mkdir recipe to support multiple paths: ...@@ -425,7 +425,7 @@ the mkdir recipe to support multiple paths:
... ...
... def install(self): ... def install(self):
... paths = self.options['path'].split() ... paths = self.options['path'].split()
... for path in paths: ... for path in paths:
... logging.getLogger(self.name).info( ... logging.getLogger(self.name).info(
... 'Creating directory %s', os.path.basename(path)) ... 'Creating directory %s', os.path.basename(path))
... os.mkdir(path) ... os.mkdir(path)
...@@ -502,7 +502,7 @@ Now they fail because foo exists, because it was left behind. ...@@ -502,7 +502,7 @@ Now they fail because foo exists, because it was left behind.
Let's fix the recipe: Let's fix the recipe:
>>> write(sample_buildout, 'recipes', 'mkdir.py', >>> write(sample_buildout, 'recipes', 'mkdir.py',
... """ ... """
... import logging, os, zc.buildout ... import logging, os, zc.buildout
... ...
...@@ -514,7 +514,7 @@ Let's fix the recipe: ...@@ -514,7 +514,7 @@ Let's fix the recipe:
... # Normalize paths and check that their parent ... # Normalize paths and check that their parent
... # directories exist: ... # directories exist:
... paths = [] ... paths = []
... for path in options['path'].split(): ... for path in options['path'].split():
... path = os.path.join(buildout['buildout']['directory'], path) ... path = os.path.join(buildout['buildout']['directory'], path)
... if not os.path.isdir(os.path.dirname(path)): ... if not os.path.isdir(os.path.dirname(path)):
... logging.getLogger(self.name).error( ... logging.getLogger(self.name).error(
...@@ -528,7 +528,7 @@ Let's fix the recipe: ...@@ -528,7 +528,7 @@ Let's fix the recipe:
... paths = self.options['path'].split() ... paths = self.options['path'].split()
... created = [] ... created = []
... try: ... try:
... for path in paths: ... for path in paths:
... logging.getLogger(self.name).info( ... logging.getLogger(self.name).info(
... 'Creating directory %s', os.path.basename(path)) ... 'Creating directory %s', os.path.basename(path))
... os.mkdir(path) ... os.mkdir(path)
...@@ -573,6 +573,10 @@ When we rerun the buildout: ...@@ -573,6 +573,10 @@ When we rerun the buildout:
... ...
OSError: [Errno 17] File exists: '/sample-buildout/bin' OSError: [Errno 17] File exists: '/sample-buildout/bin'
.. Wait for the file to really disappear. My linux is weird.
>>> wait_until("foo goes away", lambda : not os.path.exists('foo'))
we get the same error, but we don't get the directory left behind: we get the same error, but we don't get the directory left behind:
>>> os.path.exists('foo') >>> os.path.exists('foo')
...@@ -588,7 +592,7 @@ automatically. The method returns the files registered and can be ...@@ -588,7 +592,7 @@ automatically. The method returns the files registered and can be
used to return the files created. Let's use this API to simplify the used to return the files created. Let's use this API to simplify the
recipe: recipe:
>>> write(sample_buildout, 'recipes', 'mkdir.py', >>> write(sample_buildout, 'recipes', 'mkdir.py',
... """ ... """
... import logging, os, zc.buildout ... import logging, os, zc.buildout
... ...
...@@ -600,7 +604,7 @@ recipe: ...@@ -600,7 +604,7 @@ recipe:
... # Normalize paths and check that their parent ... # Normalize paths and check that their parent
... # directories exist: ... # directories exist:
... paths = [] ... paths = []
... for path in options['path'].split(): ... for path in options['path'].split():
... path = os.path.join(buildout['buildout']['directory'], path) ... path = os.path.join(buildout['buildout']['directory'], path)
... if not os.path.isdir(os.path.dirname(path)): ... if not os.path.isdir(os.path.dirname(path)):
... logging.getLogger(self.name).error( ... logging.getLogger(self.name).error(
...@@ -612,7 +616,7 @@ recipe: ...@@ -612,7 +616,7 @@ recipe:
... ...
... def install(self): ... def install(self):
... paths = self.options['path'].split() ... paths = self.options['path'].split()
... for path in paths: ... for path in paths:
... logging.getLogger(self.name).info( ... logging.getLogger(self.name).info(
... 'Creating directory %s', os.path.basename(path)) ... 'Creating directory %s', os.path.basename(path))
... os.mkdir(path) ... os.mkdir(path)
...@@ -710,7 +714,7 @@ Buildout configuration files support variable substitution. ...@@ -710,7 +714,7 @@ Buildout configuration files support variable substitution.
To illustrate this, we'll create an debug recipe to To illustrate this, we'll create an debug recipe to
allow us to see interactions with the buildout: allow us to see interactions with the buildout:
>>> write(sample_buildout, 'recipes', 'debug.py', >>> write(sample_buildout, 'recipes', 'debug.py',
... """ ... """
... class Debug: ... class Debug:
... ...
...@@ -777,7 +781,7 @@ substituted are qualified option names, consisting of a section name ...@@ -777,7 +781,7 @@ substituted are qualified option names, consisting of a section name
and option name joined by a colon. and option name joined by a colon.
Now, if we run the buildout, we'll see the options with the values Now, if we run the buildout, we'll see the options with the values
substituted. substituted.
>>> print system(buildout), >>> print system(buildout),
Develop: '/sample-buildout/recipes' Develop: '/sample-buildout/recipes'
...@@ -1069,9 +1073,9 @@ To see how this works, we use an example: ...@@ -1069,9 +1073,9 @@ To see how this works, we use an example:
The example is pretty trivial, but the pattern it illustrates is The example is pretty trivial, but the pattern it illustrates is
pretty common. In a more practical example, the base buildout might pretty common. In a more practical example, the base buildout might
represent a product and the extending buildout might be a represent a product and the extending buildout might be a
customization. customization.
Here is a more elaborate example. Here is a more elaborate example.
>>> other = tmpdir('other') >>> other = tmpdir('other')
...@@ -1171,7 +1175,7 @@ we'll set up a web server with some configuration files. ...@@ -1171,7 +1175,7 @@ we'll set up a web server with some configuration files.
... """ ... """
... [buildout] ... [buildout]
... extends = r1.cfg ... extends = r1.cfg
... ...
... [debug] ... [debug]
... op2 = r2 2 ... op2 = r2 2
... op3 = r2 3 ... op3 = r2 3
...@@ -1179,7 +1183,7 @@ we'll set up a web server with some configuration files. ...@@ -1179,7 +1183,7 @@ we'll set up a web server with some configuration files.
>>> server_url = start_server(server_data) >>> server_url = start_server(server_data)
>>> write('client.cfg', >>> write('client.cfg',
... """ ... """
... [buildout] ... [buildout]
... develop = recipes ... develop = recipes
...@@ -1208,10 +1212,10 @@ URL reference. Relative references are interpreted relative to the ...@@ -1208,10 +1212,10 @@ URL reference. Relative references are interpreted relative to the
base URL when they appear in configuration files loaded via URL. base URL when they appear in configuration files loaded via URL.
We can also specify a URL as the configuration file to be used by a We can also specify a URL as the configuration file to be used by a
buildout. buildout.
>>> os.remove('client.cfg') >>> os.remove('client.cfg')
>>> write(server_data, 'remote.cfg', >>> write(server_data, 'remote.cfg',
... """ ... """
... [buildout] ... [buildout]
... develop = recipes ... develop = recipes
...@@ -1344,7 +1348,7 @@ able to be instantiated at uninstallation time. ...@@ -1344,7 +1348,7 @@ able to be instantiated at uninstallation time.
Here's a recipe that simulates installation of a system service, along Here's a recipe that simulates installation of a system service, along
with an uninstall recipe that simulates removing the service. with an uninstall recipe that simulates removing the service.
>>> write(sample_buildout, 'recipes', 'service.py', >>> write(sample_buildout, 'recipes', 'service.py',
... """ ... """
... class Service: ... class Service:
... ...
...@@ -1354,7 +1358,7 @@ with an uninstall recipe that simulates removing the service. ...@@ -1354,7 +1358,7 @@ with an uninstall recipe that simulates removing the service.
... self.options = options ... self.options = options
... ...
... def install(self): ... def install(self):
... print "chkconfig --add %s" % self.options['script'] ... print "chkconfig --add %s" % self.options['script']
... return () ... return ()
... ...
... def update(self): ... def update(self):
...@@ -1446,7 +1450,7 @@ Now we remove the service part, and add another part. ...@@ -1446,7 +1450,7 @@ Now we remove the service part, and add another part.
... [buildout] ... [buildout]
... develop = recipes ... develop = recipes
... parts = debug ... parts = debug
... ...
... [debug] ... [debug]
... recipe = recipes:debug ... recipe = recipes:debug
... """) ... """)
...@@ -1469,14 +1473,14 @@ recipe before they are deleted. ...@@ -1469,14 +1473,14 @@ recipe before they are deleted.
For example, here's an uninstallation recipe that simulates backing up For example, here's an uninstallation recipe that simulates backing up
a directory before it is deleted. It is designed to work with the a directory before it is deleted. It is designed to work with the
mkdir recipe introduced earlier. mkdir recipe introduced earlier.
>>> write(sample_buildout, 'recipes', 'backup.py', >>> write(sample_buildout, 'recipes', 'backup.py',
... """ ... """
... import os ... import os
... def backup_directory(name, options): ... def backup_directory(name, options):
... path = options['path'] ... path = options['path']
... size = len(os.listdir(path)) ... size = len(os.listdir(path))
... print "backing up directory %s of size %s" % (path, size) ... print "backing up directory %s of size %s" % (path, size)
... """) ... """)
It must be registered with the zc.buildout.uninstall entry It must be registered with the zc.buildout.uninstall entry
...@@ -1507,7 +1511,7 @@ Now we can use it with a mkdir part. ...@@ -1507,7 +1511,7 @@ Now we can use it with a mkdir part.
... [buildout] ... [buildout]
... develop = recipes ... develop = recipes
... parts = dir debug ... parts = dir debug
... ...
... [dir] ... [dir]
... recipe = recipes:mkdir ... recipe = recipes:mkdir
... path = my_directory ... path = my_directory
...@@ -1534,7 +1538,7 @@ Now we remove the part from the configuration file. ...@@ -1534,7 +1538,7 @@ Now we remove the part from the configuration file.
... [buildout] ... [buildout]
... develop = recipes ... develop = recipes
... parts = debug ... parts = debug
... ...
... [debug] ... [debug]
... recipe = recipes:debug ... recipe = recipes:debug
... """) ... """)
...@@ -1583,7 +1587,7 @@ The following options are supported: ...@@ -1583,7 +1587,7 @@ The following options are supported:
-c filename -c filename
The -c option can be used to specify a configuration file, rather than The -c option can be used to specify a configuration file, rather than
buildout.cfg in the current directory. buildout.cfg in the current directory.
-t socket_timeout -t socket_timeout
...@@ -1602,11 +1606,11 @@ The following options are supported: ...@@ -1602,11 +1606,11 @@ The following options are supported:
Don't read user-default configuration. Don't read user-default configuration.
-o -o
Run in off-line mode. This is equivalent to the assignment Run in off-line mode. This is equivalent to the assignment
buildout:offline=true. buildout:offline=true.
-O -O
Run in non-off-line mode. This is equivalent to the assignment Run in non-off-line mode. This is equivalent to the assignment
buildout:offline=false. This is the default buildout mode. The buildout:offline=false. This is the default buildout mode. The
-O option would normally be used to override a true offline -O option would normally be used to override a true offline
setting in a configuration file. setting in a configuration file.
...@@ -1618,10 +1622,10 @@ The following options are supported: ...@@ -1618,10 +1622,10 @@ The following options are supported:
available that satisfy its requirements. available that satisfy its requirements.
-N -N
Run in non-newest mode. This is equivalent to the assignment Run in non-newest mode. This is equivalent to the assignment
buildout:newest=false. With this setting, buildout will not seek buildout:newest=false. With this setting, buildout will not seek
new distributions if installed distributions satisfy it's new distributions if installed distributions satisfy it's
requirements. requirements.
Assignments are of the form:: Assignments are of the form::
...@@ -1646,7 +1650,7 @@ Here's an example: ...@@ -1646,7 +1650,7 @@ Here's an example:
Note that we used the installed buildout option to specify an Note that we used the installed buildout option to specify an
alternate file to store information about installed parts. alternate file to store information about installed parts.
>>> print system(buildout+' -c other.cfg debug:op1=foo -v'), >>> print system(buildout+' -c other.cfg debug:op1=foo -v'),
Develop: '/sample-buildout/recipes' Develop: '/sample-buildout/recipes'
Installing debug. Installing debug.
...@@ -1654,12 +1658,12 @@ alternate file to store information about installed parts. ...@@ -1654,12 +1658,12 @@ alternate file to store information about installed parts.
op1 foo op1 foo
recipe recipes:debug recipe recipes:debug
Here we used the -c option to specify an alternate configuration file, Here we used the -c option to specify an alternate configuration file,
and the -v option to increase the level of logging from the default, and the -v option to increase the level of logging from the default,
WARNING. WARNING.
Options can also be combined in the usual Unix way, as in: Options can also be combined in the usual Unix way, as in:
>>> print system(buildout+' -vcother.cfg debug:op1=foo'), >>> print system(buildout+' -vcother.cfg debug:op1=foo'),
Develop: '/sample-buildout/recipes' Develop: '/sample-buildout/recipes'
Updating debug. Updating debug.
...@@ -1712,7 +1716,7 @@ the buildout in the usual way: ...@@ -1712,7 +1716,7 @@ the buildout in the usual way:
d2: Creating directory d2 d2: Creating directory d2
Installing d3. Installing d3.
d3: Creating directory d3 d3: Creating directory d3
>>> ls(sample_buildout) >>> ls(sample_buildout)
- .installed.cfg - .installed.cfg
- b1.cfg - b1.cfg
...@@ -1791,7 +1795,7 @@ and run the buildout specifying just d3 and d4: ...@@ -1791,7 +1795,7 @@ and run the buildout specifying just d3 and d4:
d3: Creating directory data3 d3: Creating directory data3
Installing d4. Installing d4.
d4: Creating directory data2-extra d4: Creating directory data2-extra
>>> ls(sample_buildout) >>> ls(sample_buildout)
- .installed.cfg - .installed.cfg
- b1.cfg - b1.cfg
...@@ -1808,7 +1812,7 @@ and run the buildout specifying just d3 and d4: ...@@ -1808,7 +1812,7 @@ and run the buildout specifying just d3 and d4:
d eggs d eggs
d parts d parts
d recipes d recipes
Only the d3 and d4 recipes ran. d3 was removed and data3 and data2-extra Only the d3 and d4 recipes ran. d3 was removed and data3 and data2-extra
were created. were created.
...@@ -1899,7 +1903,7 @@ provide alternate locations, and even names for these directories. ...@@ -1899,7 +1903,7 @@ provide alternate locations, and even names for these directories.
... """ ... """
... [buildout] ... [buildout]
... develop = recipes ... develop = recipes
... parts = ... parts =
... develop-eggs-directory = %(developbasket)s ... develop-eggs-directory = %(developbasket)s
... eggs-directory = %(basket)s ... eggs-directory = %(basket)s
... bin-directory = %(scripts)s ... bin-directory = %(scripts)s
...@@ -1928,7 +1932,7 @@ provide alternate locations, and even names for these directories. ...@@ -1928,7 +1932,7 @@ provide alternate locations, and even names for these directories.
d scripts d scripts
d work d work
>>> ls(alt, 'developbasket') >>> ls(alt, 'developbasket')
- recipes.egg-link - recipes.egg-link
You can also specify an alternate buildout directory: You can also specify an alternate buildout directory:
...@@ -1941,12 +1945,12 @@ You can also specify an alternate buildout directory: ...@@ -1941,12 +1945,12 @@ You can also specify an alternate buildout directory:
... [buildout] ... [buildout]
... directory = %(alt)s ... directory = %(alt)s
... develop = %(recipes)s ... develop = %(recipes)s
... parts = ... parts =
... """ % dict( ... """ % dict(
... alt=alt, ... alt=alt,
... recipes=os.path.join(sample_buildout, 'recipes'), ... recipes=os.path.join(sample_buildout, 'recipes'),
... )) ... ))
>>> print system(buildout), >>> print system(buildout),
Creating directory '/sample-alt/bin'. Creating directory '/sample-alt/bin'.
Creating directory '/sample-alt/parts'. Creating directory '/sample-alt/parts'.
...@@ -1961,7 +1965,7 @@ You can also specify an alternate buildout directory: ...@@ -1961,7 +1965,7 @@ You can also specify an alternate buildout directory:
d eggs d eggs
d parts d parts
>>> ls(alt, 'develop-eggs') >>> ls(alt, 'develop-eggs')
- recipes.egg-link - recipes.egg-link
Logging control Logging control
...@@ -1969,10 +1973,10 @@ Logging control ...@@ -1969,10 +1973,10 @@ Logging control
Three buildout options are used to control logging: Three buildout options are used to control logging:
log-level log-level
specifies the log level specifies the log level
verbosity verbosity
adjusts the log level adjusts the log level
log-format log-format
...@@ -1990,7 +1994,7 @@ of changing the format: ...@@ -1990,7 +1994,7 @@ of changing the format:
... verbosity = 5 ... verbosity = 5
... log-format = %(levelname)s %(message)s ... log-format = %(levelname)s %(message)s
... """) ... """)
Here, we've changed the format to include the log-level name, rather Here, we've changed the format to include the log-level name, rather
than the logger name. than the logger name.
...@@ -2010,7 +2014,7 @@ and that users can override in their configuration files. To see ...@@ -2010,7 +2014,7 @@ and that users can override in their configuration files. To see
these, we'll run a minimal buildout configuration with a debug logging these, we'll run a minimal buildout configuration with a debug logging
level. One of the features of debug logging is that the configuration level. One of the features of debug logging is that the configuration
database is shown. database is shown.
>>> write(sample_buildout, 'buildout.cfg', >>> write(sample_buildout, 'buildout.cfg',
... """ ... """
... [buildout] ... [buildout]
...@@ -2040,7 +2044,7 @@ database is shown. ...@@ -2040,7 +2044,7 @@ database is shown.
python = buildout python = buildout
verbosity = 20 verbosity = 20
<BLANKLINE> <BLANKLINE>
All of these options can be overridden by configuration files or by All of these options can be overridden by configuration files or by
command-line assignments. We've discussed most of these options command-line assignments. We've discussed most of these options
already, but let's review them and touch on some we haven't discussed: already, but let's review them and touch on some we haven't discussed:
...@@ -2108,7 +2112,7 @@ Creating new buildouts and bootstrapping ...@@ -2108,7 +2112,7 @@ Creating new buildouts and 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. local buildout scripts.
>>> sample_bootstrapped = tmpdir('sample-bootstrapped') >>> sample_bootstrapped = tmpdir('sample-bootstrapped')
...@@ -2237,7 +2241,7 @@ requirements of the buildout will always be used. ...@@ -2237,7 +2241,7 @@ requirements of the buildout will always be used.
You can also specify more locations to search for distributions using You can also specify more locations to search for distributions using
the `find-links` option. All locations specified will be searched for the `find-links` option. All locations specified will be searched for
distributions along with the package index as described before. distributions along with the package index as described before.
Locations can be urls:: Locations can be urls::
...@@ -2257,11 +2261,11 @@ Finally, they can also be direct paths to distributions:: ...@@ -2257,11 +2261,11 @@ Finally, they can also be direct paths to distributions::
... ...
find-links = /some/path/someegg-1.0.0-py2.3.egg find-links = /some/path/someegg-1.0.0-py2.3.egg
Any number of locations can be specified in the `find-links` option:: Any number of locations can be specified in the `find-links` option::
[buildout] [buildout]
... ...
find-links = find-links =
http://download.zope.org/distribution/ http://download.zope.org/distribution/
/some/otherpath /some/otherpath
/some/path/someegg-1.0.0-py2.3.egg /some/path/someegg-1.0.0-py2.3.egg
...@@ -2288,7 +2292,7 @@ information on installed parts. This option is initialized to ...@@ -2288,7 +2292,7 @@ information on installed parts. This option is initialized to
".installed.cfg", but it can be overridden in the configuration file ".installed.cfg", but it can be overridden in the configuration file
or on the command line: or on the command line:
>>> write('buildout.cfg', >>> write('buildout.cfg',
... """ ... """
... [buildout] ... [buildout]
... develop = recipes ... develop = recipes
...@@ -2341,7 +2345,7 @@ buildout installed option: ...@@ -2341,7 +2345,7 @@ buildout installed option:
Note that there will be no installation database if there are no Note that there will be no installation database if there are no
parts: parts:
>>> write('buildout.cfg', >>> write('buildout.cfg',
... """ ... """
... [buildout] ... [buildout]
... parts = ... parts =
...@@ -2379,7 +2383,7 @@ previous section: ...@@ -2379,7 +2383,7 @@ previous section:
>>> mkdir(sample_bootstrapped, 'demo') >>> mkdir(sample_bootstrapped, 'demo')
>>> write(sample_bootstrapped, 'demo', 'demo.py', >>> write(sample_bootstrapped, 'demo', 'demo.py',
... """ ... """
... def ext(buildout): ... def ext(buildout):
... print 'ext', list(buildout) ... print 'ext', list(buildout)
...@@ -2388,7 +2392,7 @@ previous section: ...@@ -2388,7 +2392,7 @@ previous section:
>>> write(sample_bootstrapped, 'demo', 'setup.py', >>> write(sample_bootstrapped, 'demo', 'setup.py',
... """ ... """
... from setuptools import setup ... from setuptools import setup
... ...
... setup( ... setup(
... name = "demo", ... name = "demo",
... entry_points = {'zc.buildout.extension': ['ext = demo:ext']}, ... entry_points = {'zc.buildout.extension': ['ext = demo:ext']},
...@@ -2426,7 +2430,7 @@ the network, we wouldn't need to do anything special. ...@@ -2426,7 +2430,7 @@ the network, we wouldn't need to do anything special.
... extensions = demo ... extensions = demo
... parts = ... parts =
... """) ... """)
We see that our extension is loaded and executed: We see that our extension is loaded and executed:
>>> print system(os.path.join(sample_bootstrapped, 'bin', 'buildout')), >>> print system(os.path.join(sample_bootstrapped, 'bin', 'buildout')),
...@@ -2437,22 +2441,22 @@ Allow hosts ...@@ -2437,22 +2441,22 @@ Allow hosts
----------- -----------
On some environments the links visited by `zc.buildout` can be forbidden On some environments the links visited by `zc.buildout` can be forbidden
by paranoiac firewalls. These URL might be on the chain of links by paranoiac firewalls. These URL might be on the chain of links
visited by `zc.buildout` wheter they are defined in the `find-links` option, visited by `zc.buildout` wheter they are defined in the `find-links` option,
wheter they are defined by various eggs in their `url`, `download_url`, wheter they are defined by various eggs in their `url`, `download_url`,
`dependency_links` metadata. `dependency_links` metadata.
It is even harder to track that package_index works like a spider and It is even harder to track that package_index works like a spider and
might visit links and go to other location. might visit links and go to other location.
The `allow-hosts` option provides a way to prevent this, and The `allow-hosts` option provides a way to prevent this, and
works exactly like the one provided in `easy_install`. works exactly like the one provided in `easy_install`.
You can provide a list of allowed host, together with wildcards:: You can provide a list of allowed host, together with wildcards::
[buildout] [buildout]
... ...
allow-hosts = allow-hosts =
*.python.org *.python.org
example.com example.com
......
...@@ -176,13 +176,26 @@ def find_python(version): ...@@ -176,13 +176,26 @@ def find_python(version):
o.close() o.close()
if os.path.exists(e): if os.path.exists(e):
return e return e
raise ValueError( raise ValueError(
"Couldn't figure out the executable for Python %(version)s.\n" "Couldn't figure out the executable for Python %(version)s.\n"
"Set the environment variable PYTHON%(version)s to the location\n" "Set the environment variable PYTHON%(version)s to the location\n"
"of the Python %(version)s executable before running the tests." "of the Python %(version)s executable before running the tests."
% {'version': version}) % {'version': version})
def wait_until(label, func, *args, **kw):
if 'timeout' in kw:
kw = dict(kw)
timeout = kw.pop('timeout')
else:
timeout = 30
deadline = time.time()+timeout
while time.time() < deadline:
if func(*args, **kw):
return
time.sleep('.01')
raise ValueError('Timed out waiting for: '+label)
def buildoutSetUp(test): def buildoutSetUp(test):
test.globs['__tear_downs'] = __tear_downs = [] test.globs['__tear_downs'] = __tear_downs = []
...@@ -214,7 +227,7 @@ def buildoutSetUp(test): ...@@ -214,7 +227,7 @@ def buildoutSetUp(test):
tmp = tempfile.mkdtemp('buildouttests') tmp = tempfile.mkdtemp('buildouttests')
register_teardown(lambda: rmtree(tmp)) register_teardown(lambda: rmtree(tmp))
zc.buildout.easy_install.default_index_url = 'file://'+tmp zc.buildout.easy_install.default_index_url = 'file://'+tmp
os.environ['buildout-testing-index-url'] = ( os.environ['buildout-testing-index-url'] = (
zc.buildout.easy_install.default_index_url) zc.buildout.easy_install.default_index_url)
...@@ -243,8 +256,8 @@ def buildoutSetUp(test): ...@@ -243,8 +256,8 @@ def buildoutSetUp(test):
] ]
).bootstrap([]) ).bootstrap([])
# Create the develop-eggs dir, which didn't get created the usual # Create the develop-eggs dir, which didn't get created the usual
# way due to thr trick above: # way due to thr trick above:
os.mkdir('develop-eggs') os.mkdir('develop-eggs')
...@@ -272,14 +285,15 @@ def buildoutSetUp(test): ...@@ -272,14 +285,15 @@ def buildoutSetUp(test):
bdist_egg = bdist_egg, bdist_egg = bdist_egg,
start_server = start_server, start_server = start_server,
buildout = os.path.join(sample, 'bin', 'buildout'), buildout = os.path.join(sample, 'bin', 'buildout'),
wait_until = wait_until,
)) ))
zc.buildout.easy_install.prefer_final(prefer_final) zc.buildout.easy_install.prefer_final(prefer_final)
def buildoutTearDown(test): def buildoutTearDown(test):
for f in test.globs['__tear_downs']: for f in test.globs['__tear_downs']:
f() f()
class Server(BaseHTTPServer.HTTPServer): class Server(BaseHTTPServer.HTTPServer):
def __init__(self, tree, *args): def __init__(self, tree, *args):
...@@ -307,12 +321,12 @@ class Handler(BaseHTTPServer.BaseHTTPRequestHandler): ...@@ -307,12 +321,12 @@ class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_GET(self): def do_GET(self):
if '__stop__' in self.path: if '__stop__' in self.path:
raise SystemExit raise SystemExit
if self.path == '/enable_server_logging': if self.path == '/enable_server_logging':
self.__server.__log = True self.__server.__log = True
self.send_response(200) self.send_response(200)
return return
if self.path == '/disable_server_logging': if self.path == '/disable_server_logging':
self.__server.__log = False self.__server.__log = False
self.send_response(200) self.send_response(200)
...@@ -361,7 +375,7 @@ class Handler(BaseHTTPServer.BaseHTTPRequestHandler): ...@@ -361,7 +375,7 @@ class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
self.end_headers() self.end_headers()
self.wfile.write(out) self.wfile.write(out)
def log_request(self, code): def log_request(self, code):
if self.__server.__log: if self.__server.__log:
print '%s %s %s' % (self.command, code, self.path) print '%s %s %s' % (self.command, code, self.path)
...@@ -462,7 +476,7 @@ def _normalize_path(match): ...@@ -462,7 +476,7 @@ def _normalize_path(match):
if path.startswith('\\'): if path.startswith('\\'):
path = path[1:] path = path[1:]
return '/' + path.replace(os.path.sep, '/') return '/' + path.replace(os.path.sep, '/')
normalize_path = ( normalize_path = (
re.compile( re.compile(
r'''[^'" \t\n\r]+\%(sep)s_[Tt][Ee][Ss][Tt]_\%(sep)s([^"' \t\n\r]+)''' r'''[^'" \t\n\r]+\%(sep)s_[Tt][Ee][Ss][Tt]_\%(sep)s([^"' \t\n\r]+)'''
......
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