eggs/zc.buildout-1.5.2-py2.6.egg/zc/buildout/buildout.txt
changeset 307 c6bca38c1cbf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eggs/zc.buildout-1.5.2-py2.6.egg/zc/buildout/buildout.txt	Sat Jan 08 11:20:57 2011 +0530
@@ -0,0 +1,2831 @@
+Buildouts
+=========
+
+The word "buildout" refers to a description of a set of parts and the
+software to create and assemble them.  It is often used informally to
+refer to an installed system based on a buildout definition.  For
+example, if we are creating an application named "Foo", then "the Foo
+buildout" is the collection of configuration and application-specific
+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
+buildout".
+
+This document describes how to define buildouts using buildout
+configuration files and recipes.  There are three ways to set up the
+buildout software and create a buildout instance:
+
+1. Install the zc.buildout egg with easy_install and use the buildout
+   script installed in a Python scripts area.
+
+2. Use the buildout bootstrap script to create a buildout that
+   includes both the setuptools and zc.buildout eggs.  This allows you
+   to use the buildout software without modifying a Python install.
+   The buildout script is installed into your buildout local scripts
+   area.
+
+3. Use a buildout command from an already installed buildout to
+   bootstrap a new buildout.  (See the section on bootstraping later
+   in this document.)
+
+Often, a software project will be managed in a software repository,
+such as a subversion repository, that includes some software source
+directories, buildout configuration files, and a copy of the buildout
+bootstrap script.  To work on the project, one would check out the
+project from the repository and run the bootstrap script which
+installs setuptools and zc.buildout into the checkout as well as any
+parts defined.
+
+We have a sample buildout that we created using the bootstrap command
+of an existing buildout (method 3 above).  It has the absolute minimum
+information.  We have bin, develop-eggs, eggs and parts directories,
+and a configuration file:
+
+    >>> ls(sample_buildout)
+    d  bin
+    -  buildout.cfg
+    d  develop-eggs
+    d  eggs
+    d  parts
+
+The bin directory contains scripts.
+
+    >>> ls(sample_buildout, 'bin')
+    -  buildout
+
+    >>> ls(sample_buildout, 'eggs')
+    -  setuptools-0.6-py2.4.egg
+    -  zc.buildout-1.0-py2.4.egg
+
+The develop-eggs directory is initially empty:
+
+    >>> ls(sample_buildout, 'develop-eggs')
+
+The develop-eggs directory holds egg links for software being
+developed in the buildout.  We separate develop-eggs and other eggs to
+allow eggs directories to be shared across multiple buildouts.  For
+example, a common developer technique is to define a common eggs
+directory in their home that all non-develop eggs are stored in.  This
+allows larger buildouts to be set up much more quickly and saves disk
+space.
+
+The parts directory just contains some helpers for the buildout script
+itself.
+
+    >>> ls(sample_buildout, 'parts')
+    d  buildout
+
+The parts directory provides an area where recipes can install
+part data.  For example, if we built a custom Python, we would
+install it in the part directory.  Part data is stored in a
+sub-directory of the parts directory with the same name as the part.
+
+Buildouts are defined using configuration files.  These are in the
+format defined by the Python ConfigParser module, with extensions
+that we'll describe later.  By default, when a buildout is run, it
+looks for the file buildout.cfg in the directory where the buildout is
+run.
+
+The minimal configuration file has a buildout section that defines no
+parts:
+
+    >>> cat(sample_buildout, 'buildout.cfg')
+    [buildout]
+    parts =
+
+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
+even a configuration file.
+
+Recipes
+-------
+
+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
+Python Package Index, or they can be developed as part of a project
+using a "develop" 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
+don't have to be packaged for distribution to be used and can be
+modified in place, which is especially useful while they are being
+developed.
+
+Let's create a recipe as part of the sample project.  We'll create a
+recipe for creating directories.  First, we'll create a recipes source
+directory for our local recipes:
+
+    >>> mkdir(sample_buildout, 'recipes')
+
+and then we'll create a source file for our mkdir recipe:
+
+    >>> write(sample_buildout, 'recipes', 'mkdir.py',
+    ... """
+    ... import logging, os, zc.buildout
+    ...
+    ... class Mkdir:
+    ...
+    ...     def __init__(self, buildout, name, options):
+    ...         self.name, self.options = name, options
+    ...         options['path'] = os.path.join(
+    ...                               buildout['buildout']['directory'],
+    ...                               options['path'],
+    ...                               )
+    ...         if not os.path.isdir(os.path.dirname(options['path'])):
+    ...             logging.getLogger(self.name).error(
+    ...                 'Cannot create %s. %s is not a directory.',
+    ...                 options['path'], os.path.dirname(options['path']))
+    ...             raise zc.buildout.UserError('Invalid Path')
+    ...
+    ...
+    ...     def install(self):
+    ...         path = self.options['path']
+    ...         logging.getLogger(self.name).info(
+    ...             'Creating directory %s', os.path.basename(path))
+    ...         os.mkdir(path)
+    ...         return path
+    ...
+    ...     def update(self):
+    ...         pass
+    ... """)
+
+Currently, recipes must define 3 methods [#future_recipe_methods]_:
+
+- a constructor,
+
+- an install method, and
+
+- an update method.
+
+The constructor is responsible for updating a parts options to reflect
+data read from other sections.  The buildout system keeps track of
+whether a part specification has changed.  A part specification has
+changed if it's options, after adjusting for data read from other
+sections, has changed, or if the recipe has changed.  Only the options
+for the part are considered.  If data are read from other sections,
+then that information has to be reflected in the parts options.  In
+the Mkdir example, the given path is interpreted relative to the
+buildout directory, and data from the buildout directory is read.  The
+path option is updated to reflect this.  If the directory option was
+changed in the buildout sections, we would know to update parts
+created using the mkdir recipe using relative path names.
+
+When buildout is run, it saves configuration data for installed parts
+in a file named ".installed.cfg".  In subsequent runs, it compares
+part-configuration data stored in the .installed.cfg file and the
+part-configuration data loaded from the configuration files as
+modified by recipe constructors to decide if the configuration of a
+part has changed. If the configuration has changed, or if the recipe
+has changed, then the part is uninstalled and reinstalled.  The
+buildout only looks at the part's options, so any data used to
+configure the part needs to be reflected in the part's options.  It is
+the job of a recipe constructor to make sure that the options include
+all relevant data.
+
+Of course, parts are also uninstalled if they are no-longer used.
+
+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.
+
+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
+option from our options dictionary.  The install method logs what it's
+doing using the Python logging call.  We return the path that we
+installed.  If the part is uninstalled or reinstalled, then the path
+returned will be removed by the buildout machinery.  A recipe install
+method is expected to return a string, or an iterable of strings
+containing paths to be removed if a part is uninstalled.  For most
+recipes, this is all of the uninstall support needed. For more complex
+uninstallation scenarios use `Uninstall recipes`_.
+
+The update method is responsible for updating an already installed
+part.  An empty method is often provided, as in this example, if parts
+can't be updated.  An update method can return None, a string, or an
+iterable of strings.  If a string or iterable of strings is returned,
+then the saved list of paths to be uninstalled is updated with the new
+information by adding any new files returned by the update method.
+
+We need to provide packaging information so that our recipe can be
+installed as a develop egg. The minimum information we need to specify
+[#packaging_info]_ is a name.  For recipes, we also need to define the
+names of the recipe classes as entry points.  Packaging information is
+provided via a setup.py script:
+
+    >>> write(sample_buildout, 'recipes', 'setup.py',
+    ... """
+    ... from setuptools import setup
+    ...
+    ... setup(
+    ...     name = "recipes",
+    ...     entry_points = {'zc.buildout': ['mkdir = mkdir:Mkdir']},
+    ...     )
+    ... """)
+
+Our setup script defines 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 mkdir.  Recipe
+classes must be exposed as entry points in the zc.buildout group.  we
+give entry points names within the group.
+
+We also need a README.txt for our recipes to avoid an annoying warning
+from distutils, on which setuptools and zc.buildout are based:
+
+    >>> write(sample_buildout, 'recipes', 'README.txt', " ")
+
+Now let's update our buildout.cfg:
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... develop = recipes
+    ... parts = data-dir
+    ...
+    ... [data-dir]
+    ... recipe = recipes:mkdir
+    ... path = mystuff
+    ... """)
+
+Let's go through the changes one by one::
+
+    develop = recipes
+
+This tells the buildout to install a development egg for our recipes.
+Any number of paths can be listed.  The paths can be relative or
+absolute.  If relative, they are treated as relative to the buildout
+directory.  They can be directory or file paths.  If a file path is
+given, it should point to a Python setup script.  If a directory path
+is given, it should point to a directory containing a setup.py file.
+Development eggs are installed before building any parts, as they may
+provide locally-defined recipes needed by the parts.
+
+::
+
+    parts = data-dir
+
+Here we've named a part to be "built".  We can use any name we want
+except that different part names must be unique and recipes will often
+use the part name to decide what to do.
+
+::
+
+    [data-dir]
+    recipe = recipes:mkdir
+    path = mystuff
+
+
+When we name a part, we also create a section of the same
+name that contains part data.  In this section, we'll define
+the recipe to be used to install the part.  In this case, we also
+specify the path to be created.
+
+Let's run the buildout.  We do so by running the build script in the
+buildout:
+
+    >>> import os
+    >>> os.chdir(sample_buildout)
+    >>> buildout = os.path.join(sample_buildout, 'bin', 'buildout')
+    >>> print system(buildout),
+    Develop: '/sample-buildout/recipes'
+    Installing data-dir.
+    data-dir: Creating directory mystuff
+
+We see that the recipe created the directory, as expected:
+
+    >>> ls(sample_buildout)
+    -  .installed.cfg
+    d  bin
+    -  buildout.cfg
+    d  develop-eggs
+    d  eggs
+    d  mystuff
+    d  parts
+    d  recipes
+
+In addition, .installed.cfg has been created containing information
+about the part we installed:
+
+    >>> cat(sample_buildout, '.installed.cfg')
+    [buildout]
+    installed_develop_eggs = /sample-buildout/develop-eggs/recipes.egg-link
+    parts = data-dir
+    <BLANKLINE>
+    [data-dir]
+    __buildout_installed__ = /sample-buildout/mystuff
+    __buildout_signature__ = recipes-c7vHV6ekIDUPy/7fjAaYjg==
+    path = /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:
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... develop = recipes
+    ... parts = data-dir
+    ...
+    ... [data-dir]
+    ... recipe = recipes:mkdir
+    ... path = mydata
+    ... """)
+
+    >>> print system(buildout),
+    Develop: '/sample-buildout/recipes'
+    Uninstalling data-dir.
+    Installing data-dir.
+    data-dir: Creating directory mydata
+
+    >>> ls(sample_buildout)
+    -  .installed.cfg
+    d  bin
+    -  buildout.cfg
+    d  develop-eggs
+    d  eggs
+    d  mydata
+    d  parts
+    d  recipes
+
+If any of the files or directories created by a recipe are removed,
+the part will be reinstalled:
+
+    >>> rmdir(sample_buildout, 'mydata')
+    >>> print system(buildout),
+    Develop: '/sample-buildout/recipes'
+    Uninstalling data-dir.
+    Installing data-dir.
+    data-dir: Creating directory mydata
+
+Error reporting
+---------------
+
+If a user makes an error, an error needs to be printed and work needs
+to stop.  This is accomplished by logging a detailed error message and
+then raising a (or an instance of a subclass of a)
+zc.buildout.UserError exception.  Raising an error other than a
+UserError still displays the error, but labels it as a bug in the
+buildout software or recipe. In the sample above, of someone gives a
+non-existent directory to create the directory in:
+
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... develop = recipes
+    ... parts = data-dir
+    ...
+    ... [data-dir]
+    ... recipe = recipes:mkdir
+    ... path = /xxx/mydata
+    ... """)
+
+We'll get a user error, not a traceback.
+
+    >>> print system(buildout),
+    Develop: '/sample-buildout/recipes'
+    data-dir: Cannot create /xxx/mydata. /xxx is not a directory.
+    While:
+      Installing.
+      Getting section data-dir.
+      Initializing part data-dir.
+    Error: Invalid Path
+
+
+Recipe Error Handling
+---------------------
+
+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
+the mkdir recipe to support multiple paths:
+
+    >>> write(sample_buildout, 'recipes', 'mkdir.py',
+    ... """
+    ... import logging, os, zc.buildout
+    ...
+    ... class Mkdir:
+    ...
+    ...     def __init__(self, buildout, name, options):
+    ...         self.name, self.options = name, options
+    ...
+    ...         # Normalize paths and check that their parent
+    ...         # directories exist:
+    ...         paths = []
+    ...         for path in options['path'].split():
+    ...             path = os.path.join(buildout['buildout']['directory'], path)
+    ...             if not os.path.isdir(os.path.dirname(path)):
+    ...                 logging.getLogger(self.name).error(
+    ...                     'Cannot create %s. %s is not a directory.',
+    ...                     options['path'], os.path.dirname(options['path']))
+    ...                 raise zc.buildout.UserError('Invalid Path')
+    ...             paths.append(path)
+    ...         options['path'] = ' '.join(paths)
+    ...
+    ...     def install(self):
+    ...         paths = self.options['path'].split()
+    ...         for path in paths:
+    ...             logging.getLogger(self.name).info(
+    ...                 'Creating directory %s', os.path.basename(path))
+    ...             os.mkdir(path)
+    ...         return paths
+    ...
+    ...     def update(self):
+    ...         pass
+    ... """)
+
+If there is an error creating a path, the install method will exit and
+leave previously created paths in place:
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... develop = recipes
+    ... parts = data-dir
+    ...
+    ... [data-dir]
+    ... recipe = recipes:mkdir
+    ... path = foo bin
+    ... """)
+
+    >>> print system(buildout), # doctest: +ELLIPSIS
+    Develop: '/sample-buildout/recipes'
+    Uninstalling data-dir.
+    Installing data-dir.
+    data-dir: Creating directory foo
+    data-dir: Creating directory bin
+    While:
+      Installing data-dir.
+    <BLANKLINE>
+    An internal error occurred due to a bug in either zc.buildout or in a
+    recipe being used:
+    Traceback (most recent call last):
+      ...
+    OSError: [Errno 17] File exists: '/sample-buildout/bin'
+
+We meant to create a directory bins, but typed bin.  Now foo was
+left behind.
+
+    >>> os.path.exists('foo')
+    True
+
+If we fix the typo:
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... develop = recipes
+    ... parts = data-dir
+    ...
+    ... [data-dir]
+    ... recipe = recipes:mkdir
+    ... path = foo bins
+    ... """)
+
+    >>> print system(buildout), # doctest: +ELLIPSIS
+    Develop: '/sample-buildout/recipes'
+    Installing data-dir.
+    data-dir: Creating directory foo
+    While:
+      Installing data-dir.
+    <BLANKLINE>
+    An internal error occurred due to a bug in either zc.buildout or in a
+    recipe being used:
+    Traceback (most recent call last):
+    ...
+    OSError: [Errno 17] File exists: '/sample-buildout/foo'
+
+Now they fail because foo exists, because it was left behind.
+
+    >>> remove('foo')
+
+Let's fix the recipe:
+
+    >>> write(sample_buildout, 'recipes', 'mkdir.py',
+    ... """
+    ... import logging, os, zc.buildout
+    ...
+    ... class Mkdir:
+    ...
+    ...     def __init__(self, buildout, name, options):
+    ...         self.name, self.options = name, options
+    ...
+    ...         # Normalize paths and check that their parent
+    ...         # directories exist:
+    ...         paths = []
+    ...         for path in options['path'].split():
+    ...             path = os.path.join(buildout['buildout']['directory'], path)
+    ...             if not os.path.isdir(os.path.dirname(path)):
+    ...                 logging.getLogger(self.name).error(
+    ...                     'Cannot create %s. %s is not a directory.',
+    ...                     options['path'], os.path.dirname(options['path']))
+    ...                 raise zc.buildout.UserError('Invalid Path')
+    ...             paths.append(path)
+    ...         options['path'] = ' '.join(paths)
+    ...
+    ...     def install(self):
+    ...         paths = self.options['path'].split()
+    ...         created = []
+    ...         try:
+    ...             for path in paths:
+    ...                 logging.getLogger(self.name).info(
+    ...                     'Creating directory %s', os.path.basename(path))
+    ...                 os.mkdir(path)
+    ...                 created.append(path)
+    ...         except:
+    ...             for d in created:
+    ...                 os.rmdir(d)
+    ...             raise
+    ...
+    ...         return paths
+    ...
+    ...     def update(self):
+    ...         pass
+    ... """)
+
+And put back the typo:
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... develop = recipes
+    ... parts = data-dir
+    ...
+    ... [data-dir]
+    ... recipe = recipes:mkdir
+    ... path = foo bin
+    ... """)
+
+When we rerun the buildout:
+
+    >>> print system(buildout), # doctest: +ELLIPSIS
+    Develop: '/sample-buildout/recipes'
+    Installing data-dir.
+    data-dir: Creating directory foo
+    data-dir: Creating directory bin
+    While:
+      Installing data-dir.
+    <BLANKLINE>
+    An internal error occurred due to a bug in either zc.buildout or in a
+    recipe being used:
+    Traceback (most recent call last):
+    ...
+    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'),
+    ...            timeout=200)
+
+we get the same error, but we don't get the directory left behind:
+
+    >>> os.path.exists('foo')
+    False
+
+It's critical that recipes clean up partial effects when errors
+occur.  Because recipes most commonly create files and directories,
+buildout provides a helper API for removing created files when an
+error occurs.  Option objects have a created method that can be called
+to record files as they are created.  If the install or update method
+returns with an error, then any registered paths are removed
+automatically.  The method returns the files registered and can be
+used to return the files created.  Let's use this API to simplify the
+recipe:
+
+    >>> write(sample_buildout, 'recipes', 'mkdir.py',
+    ... """
+    ... import logging, os, zc.buildout
+    ...
+    ... class Mkdir:
+    ...
+    ...     def __init__(self, buildout, name, options):
+    ...         self.name, self.options = name, options
+    ...
+    ...         # Normalize paths and check that their parent
+    ...         # directories exist:
+    ...         paths = []
+    ...         for path in options['path'].split():
+    ...             path = os.path.join(buildout['buildout']['directory'], path)
+    ...             if not os.path.isdir(os.path.dirname(path)):
+    ...                 logging.getLogger(self.name).error(
+    ...                     'Cannot create %s. %s is not a directory.',
+    ...                     options['path'], os.path.dirname(options['path']))
+    ...                 raise zc.buildout.UserError('Invalid Path')
+    ...             paths.append(path)
+    ...         options['path'] = ' '.join(paths)
+    ...
+    ...     def install(self):
+    ...         paths = self.options['path'].split()
+    ...         for path in paths:
+    ...             logging.getLogger(self.name).info(
+    ...                 'Creating directory %s', os.path.basename(path))
+    ...             os.mkdir(path)
+    ...             self.options.created(path)
+    ...
+    ...         return self.options.created()
+    ...
+    ...     def update(self):
+    ...         pass
+    ... """)
+
+..
+
+    >>> remove(sample_buildout, 'recipes', 'mkdir.pyc')
+
+We returned by calling created, taking advantage of the fact that it
+returns the registered paths.  We did this for illustrative purposes.
+It would be simpler just to return the paths as before.
+
+If we rerun the buildout, again, we'll get the error and no
+directories will be created:
+
+    >>> print system(buildout), # doctest: +ELLIPSIS
+    Develop: '/sample-buildout/recipes'
+    Installing data-dir.
+    data-dir: Creating directory foo
+    data-dir: Creating directory bin
+    While:
+      Installing data-dir.
+    <BLANKLINE>
+    An internal error occurred due to a bug in either zc.buildout or in a
+    recipe being used:
+    Traceback (most recent call last):
+    ...
+    OSError: [Errno 17] File exists: '/sample-buildout/bin'
+
+    >>> os.path.exists('foo')
+    False
+
+Now, we'll fix the typo again and we'll get the directories we expect:
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... develop = recipes
+    ... parts = data-dir
+    ...
+    ... [data-dir]
+    ... recipe = recipes:mkdir
+    ... path = foo bins
+    ... """)
+
+    >>> print system(buildout),
+    Develop: '/sample-buildout/recipes'
+    Installing data-dir.
+    data-dir: Creating directory foo
+    data-dir: Creating directory bins
+
+    >>> os.path.exists('foo')
+    True
+    >>> os.path.exists('bins')
+    True
+
+Configuration file syntax
+-------------------------
+
+As mentioned earlier, buildout configuration files use the format
+defined by the Python ConfigParser module with extensions.  The
+extensions are:
+
+- option names are case sensitive
+
+- option values can use a substitution syntax, described below, to
+  refer to option values in specific sections.
+
+- option values can be appended or removed using the - and +
+  operators.
+
+The ConfigParser syntax is very flexible.  Section names can contain
+any characters other than newlines and right square braces ("]").
+Option names can contain any characters other than newlines, colons,
+and equal signs, can not start with a space, and don't include
+trailing spaces.
+
+It is likely that, in the future, some characters will be given
+special buildout-defined meanings.  This is already true of the
+characters ":", "$", "%", "(", and ")".  For now, it is a good idea to
+keep section and option names simple, sticking to alphanumeric
+characters, hyphens, and periods.
+
+Annotated sections
+------------------
+
+When used with the `annotate` command, buildout displays annotated sections.
+All sections are displayed, sorted alphabetically. For each section,
+all key-value pairs are displayed, sorted alphabetically, along with
+the origin of the value (file name or COMPUTED_VALUE, DEFAULT_VALUE,
+COMMAND_LINE_VALUE).
+
+    >>> print system(buildout+ ' annotate'),
+    ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
+    <BLANKLINE>
+    Annotated sections
+    ==================
+    <BLANKLINE>
+    [buildout]
+    accept-buildout-test-releases= false
+        DEFAULT_VALUE
+    allow-hosts= *
+        DEFAULT_VALUE
+    allow-picked-versions= true
+        DEFAULT_VALUE
+    allowed-eggs-from-site-packages= *
+        DEFAULT_VALUE
+    bin-directory= bin
+        DEFAULT_VALUE
+    develop= recipes
+        /sample-buildout/buildout.cfg
+    develop-eggs-directory= develop-eggs
+        DEFAULT_VALUE
+    directory= /sample-buildout
+        COMPUTED_VALUE
+    eggs-directory= eggs
+        DEFAULT_VALUE
+    exec-sitecustomize= true
+        DEFAULT_VALUE
+    executable= ...
+        DEFAULT_VALUE
+    find-links=
+        DEFAULT_VALUE
+    include-site-packages= true
+        DEFAULT_VALUE
+    install-from-cache= false
+        DEFAULT_VALUE
+    installed= .installed.cfg
+        DEFAULT_VALUE
+    log-format=
+        DEFAULT_VALUE
+    log-level= INFO
+        DEFAULT_VALUE
+    newest= true
+        DEFAULT_VALUE
+    offline= false
+        DEFAULT_VALUE
+    parts= data-dir
+        /sample-buildout/buildout.cfg
+    parts-directory= parts
+        DEFAULT_VALUE
+    prefer-final= false
+        DEFAULT_VALUE
+    python= buildout
+        DEFAULT_VALUE
+    relative-paths= false
+        DEFAULT_VALUE
+    socket-timeout=
+        DEFAULT_VALUE
+    unzip= false
+        DEFAULT_VALUE
+    use-dependency-links= true
+        DEFAULT_VALUE
+    <BLANKLINE>
+    [data-dir]
+    path= foo bins
+        /sample-buildout/buildout.cfg
+    recipe= recipes:mkdir
+        /sample-buildout/buildout.cfg
+    <BLANKLINE>
+
+Variable substitutions
+----------------------
+
+Buildout configuration files support variable substitution.
+To illustrate this, we'll create an debug recipe to
+allow us to see interactions with the buildout:
+
+    >>> write(sample_buildout, 'recipes', 'debug.py',
+    ... """
+    ... class Debug:
+    ...
+    ...     def __init__(self, buildout, name, options):
+    ...         self.buildout = buildout
+    ...         self.name = name
+    ...         self.options = options
+    ...
+    ...     def install(self):
+    ...         items = self.options.items()
+    ...         items.sort()
+    ...         for option, value in items:
+    ...             print option, value
+    ...         return ()
+    ...
+    ...     update = install
+    ... """)
+
+This recipe doesn't actually create anything. The install method
+doesn't return anything, because it didn't create any files or
+directories.
+
+We also have to update our setup script:
+
+    >>> write(sample_buildout, 'recipes', 'setup.py',
+    ... """
+    ... from setuptools import setup
+    ... entry_points = (
+    ... '''
+    ... [zc.buildout]
+    ... mkdir = mkdir:Mkdir
+    ... debug = debug:Debug
+    ... ''')
+    ... setup(name="recipes", entry_points=entry_points)
+    ... """)
+
+We've rearranged the script a bit to make the entry points easier to
+edit.  In particular, entry points are now defined as a configuration
+string, rather than a dictionary.
+
+Let's update our configuration to provide variable substitution
+examples:
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... develop = recipes
+    ... parts = data-dir debug
+    ... log-level = INFO
+    ...
+    ... [debug]
+    ... recipe = recipes:debug
+    ... File 1 = ${data-dir:path}/file
+    ... File 2 = ${debug:File 1}/log
+    ...
+    ... [data-dir]
+    ... recipe = recipes:mkdir
+    ... path = mydata
+    ... """)
+
+We used a string-template substitution for File 1 and File 2.  This
+type of substitution uses the string.Template syntax.  Names
+substituted are qualified option names, consisting of a section name
+and option name joined by a colon.
+
+Now, if we run the buildout, we'll see the options with the values
+substituted.
+
+    >>> print system(buildout),
+    Develop: '/sample-buildout/recipes'
+    Uninstalling data-dir.
+    Installing data-dir.
+    data-dir: Creating directory mydata
+    Installing debug.
+    File 1 /sample-buildout/mydata/file
+    File 2 /sample-buildout/mydata/file/log
+    recipe recipes:debug
+
+Note that the substitution of the data-dir path option reflects the
+update to the option performed by the mkdir recipe.
+
+It might seem surprising that mydata was created again.  This is
+because we changed our recipes package by adding the debug module.
+The buildout system didn't know if this module could effect the mkdir
+recipe, so it assumed it could and reinstalled mydata.  If we rerun
+the buildout:
+
+    >>> print system(buildout),
+    Develop: '/sample-buildout/recipes'
+    Updating data-dir.
+    Updating debug.
+    File 1 /sample-buildout/mydata/file
+    File 2 /sample-buildout/mydata/file/log
+    recipe recipes:debug
+
+We can see that mydata was not recreated.
+
+Note that, in this case, we didn't specify a log level, so
+we didn't get output about what the buildout was doing.
+
+Section and option names in variable substitutions are only allowed to
+contain alphanumeric characters, hyphens, periods and spaces. This
+restriction might be relaxed in future releases.
+
+We can ommit the section name in a variable substitution to refer to
+the current section.  We can also use the special option,
+_buildout_section_name_ to get the current section name.
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... develop = recipes
+    ... parts = data-dir debug
+    ... log-level = INFO
+    ...
+    ... [debug]
+    ... recipe = recipes:debug
+    ... File 1 = ${data-dir:path}/file
+    ... File 2 = ${:File 1}/log
+    ... my_name = ${:_buildout_section_name_}
+    ...
+    ... [data-dir]
+    ... recipe = recipes:mkdir
+    ... path = mydata
+    ... """)
+
+    >>> print system(buildout),
+    Develop: '/sample-buildout/recipes'
+    Uninstalling debug.
+    Updating data-dir.
+    Installing debug.
+    File 1 /sample-buildout/mydata/file
+    File 2 /sample-buildout/mydata/file/log
+    my_name debug
+    recipe recipes:debug
+
+Automatic part selection and ordering
+-------------------------------------
+
+When a section with a recipe is referred to, either through variable
+substitution or by an initializing recipe, the section is treated as a
+part and added to the part list before the referencing part.  For
+example, we can leave data-dir out of the parts list:
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... develop = recipes
+    ... parts = debug
+    ... log-level = INFO
+    ...
+    ... [debug]
+    ... recipe = recipes:debug
+    ... File 1 = ${data-dir:path}/file
+    ... File 2 = ${debug:File 1}/log
+    ...
+    ... [data-dir]
+    ... recipe = recipes:mkdir
+    ... path = mydata
+    ... """)
+
+
+It will still be treated as a part:
+
+    >>> print system(buildout),
+    Develop: '/sample-buildout/recipes'
+    Uninstalling debug.
+    Updating data-dir.
+    Installing debug.
+    File 1 /sample-buildout/mydata/file
+    File 2 /sample-buildout/mydata/file/log
+    recipe recipes:debug
+
+    >>> cat('.installed.cfg') # doctest: +ELLIPSIS
+    [buildout]
+    installed_develop_eggs = /sample-buildout/develop-eggs/recipes.egg-link
+    parts = data-dir debug
+    ...
+
+Note that the data-dir part is included *before* the debug part,
+because the debug part refers to the data-dir part.  Even if we list
+the data-dir part after the debug part, it will be included before:
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... develop = recipes
+    ... parts = debug data-dir
+    ... log-level = INFO
+    ...
+    ... [debug]
+    ... recipe = recipes:debug
+    ... File 1 = ${data-dir:path}/file
+    ... File 2 = ${debug:File 1}/log
+    ...
+    ... [data-dir]
+    ... recipe = recipes:mkdir
+    ... path = mydata
+    ... """)
+
+
+It will still be treated as a part:
+
+    >>> print system(buildout),
+    Develop: '/sample-buildout/recipes'
+    Updating data-dir.
+    Updating debug.
+    File 1 /sample-buildout/mydata/file
+    File 2 /sample-buildout/mydata/file/log
+    recipe recipes:debug
+
+    >>> cat('.installed.cfg') # doctest: +ELLIPSIS
+    [buildout]
+    installed_develop_eggs = /sample-buildout/develop-eggs/recipes.egg-link
+    parts = data-dir debug
+    ...
+
+Extending sections (macros)
+---------------------------
+
+A section (other than the buildout section) can extend one or more
+other sections using the ``<=`` option.  Options from the referenced
+sections are copied to the refering section *before* variable
+substitution.  This, together with the ability to refer to variables
+of the current section allows sections to be used as macros.
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... develop = recipes
+    ... parts = myfiles
+    ... log-level = INFO
+    ...
+    ... [debug]
+    ... recipe = recipes:debug
+    ...
+    ... [with_file1]
+    ... <= debug
+    ... file1 = ${:path}/file1
+    ... color = red
+    ...
+    ... [with_file2]
+    ... <= debug
+    ... file2 = ${:path}/file2
+    ... color = blue
+    ...
+    ... [myfiles]
+    ... <= with_file1
+    ...    with_file2
+    ... path = mydata
+    ... """)
+
+    >>> print system(buildout),
+    Develop: '/sample-buildout/recipes'
+    Uninstalling debug.
+    Uninstalling data-dir.
+    Installing myfiles.
+    color blue
+    file1 mydata/file1
+    file2 mydata/file2
+    path mydata
+    recipe recipes:debug
+
+In this example, the debug, with_file1 and with_file2 sections act as
+macros. In particular, the variable substitutions are performed
+relative to the myfiles section.
+
+Adding and removing options
+---------------------------
+
+We can append and remove values to an option by using the + and -
+operators.
+
+This is illustrated below; first we define a base configuration.
+
+    >>> write(sample_buildout, 'base.cfg',
+    ... """
+    ... [buildout]
+    ... parts = part1 part2 part3
+    ...
+    ... [part1]
+    ... recipe =
+    ... option = a1 a2
+    ...
+    ... [part2]
+    ... recipe =
+    ... option = b1 b2 b3 b4
+    ...
+    ... [part3]
+    ... recipe =
+    ... option = c1 c2
+    ...
+    ... """)
+
+Extending this configuration, we can "adjust" the values set in the
+base configuration file.
+
+    >>> write(sample_buildout, 'extension1.cfg',
+    ... """
+    ... [buildout]
+    ... extends = base.cfg
+    ...
+    ... # appending values
+    ... [part1]
+    ... option += a3 a4
+    ...
+    ... # removing values
+    ... [part2]
+    ... option -= b1 b2
+    ...
+    ... # alt. spelling
+    ... [part3]
+    ... option+=c3 c4 c5
+    ...
+    ... # normal assignment
+    ... [part4]
+    ... option = h1 h2
+    ...
+    ... """)
+
+An additional extension.
+
+    >>> write(sample_buildout, 'extension2.cfg',
+    ... """
+    ... [buildout]
+    ... extends = extension1.cfg
+    ...
+    ... # appending values
+    ... [part1]
+    ... option += a5
+    ...
+    ... # removing values
+    ... [part2]
+    ... option -= b1 b2 b3
+    ...
+    ... """)
+
+To verify that the options are adjusted correctly, we'll set up an
+extension that prints out the options.
+
+    >>> mkdir(sample_buildout, 'demo')
+    >>> write(sample_buildout, 'demo', 'demo.py',
+    ... """
+    ... def ext(buildout):
+    ...     print [part['option'] for name, part in buildout.items() \
+    ...           if name.startswith('part')]
+    ... """)
+
+    >>> write(sample_buildout, 'demo', 'setup.py',
+    ... """
+    ... from setuptools import setup
+    ...
+    ... setup(
+    ...     name="demo",
+    ...     entry_points={'zc.buildout.extension': ['ext = demo:ext']},
+    ...     )
+    ... """)
+
+Set up a buildout configuration for this extension.
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... develop = demo
+    ... parts =
+    ... """)
+
+    >>> os.chdir(sample_buildout)
+    >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')),
+    Develop: '/sample-buildout/demo'
+    Uninstalling myfiles.
+    Getting distribution for 'recipes'.
+    zip_safe flag not set; analyzing archive contents...
+    Got recipes 0.0.0.
+    warning: install_lib: 'build/lib' does not exist -- no Python modules to install
+
+Verify option values.
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... develop = demo
+    ... extensions = demo
+    ... extends = extension2.cfg
+    ... """)
+
+    >>> print system(os.path.join('bin', 'buildout')),
+    ['a1 a2/na3 a4/na5', 'b1 b2 b3 b4', 'c1 c2/nc3 c4 c5', 'h1 h2']
+    Develop: '/sample-buildout/demo'
+
+Annotated sections output shows which files are responsible for which
+operations.
+
+    >>> print system(os.path.join('bin', 'buildout') + ' annotate'),
+    ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
+    <BLANKLINE>
+    Annotated sections
+    ==================
+    ...
+    <BLANKLINE>
+    [part1]
+    option= a1 a2
+    a3 a4
+    a5
+        /sample-buildout/base.cfg
+    +=  /sample-buildout/extension1.cfg
+    +=  /sample-buildout/extension2.cfg
+    recipe=
+        /sample-buildout/base.cfg
+    <BLANKLINE>
+    [part2]
+    option= b1 b2 b3 b4
+        /sample-buildout/base.cfg
+    -=  /sample-buildout/extension1.cfg
+    -=  /sample-buildout/extension2.cfg
+    recipe=
+        /sample-buildout/base.cfg
+    <BLANKLINE>
+    [part3]
+    option= c1 c2
+    c3 c4 c5
+        /sample-buildout/base.cfg
+    +=  /sample-buildout/extension1.cfg
+    recipe=
+        /sample-buildout/base.cfg
+    <BLANKLINE>
+    [part4]
+    option= h1 h2
+        /sample-buildout/extension1.cfg
+
+Cleanup.
+
+    >>> os.remove(os.path.join(sample_buildout, 'base.cfg'))
+    >>> os.remove(os.path.join(sample_buildout, 'extension1.cfg'))
+    >>> os.remove(os.path.join(sample_buildout, 'extension2.cfg'))
+
+Multiple configuration files
+----------------------------
+
+A configuration file can "extend" another configuration file.
+Options are read from the other configuration file if they aren't
+already defined by your configuration file.
+
+The configuration files your file extends can extend
+other configuration files.  The same file may be
+used more than once although, of course, cycles aren't allowed.
+
+To see how this works, we use an example:
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... extends = base.cfg
+    ...
+    ... [debug]
+    ... op = buildout
+    ... """)
+
+    >>> write(sample_buildout, 'base.cfg',
+    ... """
+    ... [buildout]
+    ... develop = recipes
+    ... parts = debug
+    ...
+    ... [debug]
+    ... recipe = recipes:debug
+    ... op = base
+    ... """)
+
+    >>> print system(buildout),
+    Develop: '/sample-buildout/recipes'
+    Installing debug.
+    op buildout
+    recipe recipes:debug
+
+The example is pretty trivial, but the pattern it illustrates is
+pretty common.  In a more practical example, the base buildout might
+represent a product and the extending buildout might be a
+customization.
+
+Here is a more elaborate example.
+
+    >>> other = tmpdir('other')
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... extends = b1.cfg b2.cfg %(b3)s
+    ...
+    ... [debug]
+    ... op = buildout
+    ... """ % dict(b3=os.path.join(other, 'b3.cfg')))
+
+    >>> write(sample_buildout, 'b1.cfg',
+    ... """
+    ... [buildout]
+    ... extends = base.cfg
+    ...
+    ... [debug]
+    ... op1 = b1 1
+    ... op2 = b1 2
+    ... """)
+
+    >>> write(sample_buildout, 'b2.cfg',
+    ... """
+    ... [buildout]
+    ... extends = base.cfg
+    ...
+    ... [debug]
+    ... op2 = b2 2
+    ... op3 = b2 3
+    ... """)
+
+    >>> write(other, 'b3.cfg',
+    ... """
+    ... [buildout]
+    ... extends = b3base.cfg
+    ...
+    ... [debug]
+    ... op4 = b3 4
+    ... """)
+
+    >>> write(other, 'b3base.cfg',
+    ... """
+    ... [debug]
+    ... op5 = b3base 5
+    ... """)
+
+    >>> write(sample_buildout, 'base.cfg',
+    ... """
+    ... [buildout]
+    ... develop = recipes
+    ... parts = debug
+    ...
+    ... [debug]
+    ... recipe = recipes:debug
+    ... name = base
+    ... """)
+
+    >>> print system(buildout),
+    Develop: '/sample-buildout/recipes'
+    Uninstalling debug.
+    Installing debug.
+    name base
+    op buildout
+    op1 b1 1
+    op2 b2 2
+    op3 b2 3
+    op4 b3 4
+    op5 b3base 5
+    recipe recipes:debug
+
+There are several things to note about this example:
+
+- We can name multiple files in an extends option.
+
+- We can reference files recursively.
+
+- Relative file names in extended options are interpreted relative to
+  the directory containing the referencing configuration file.
+
+Loading Configuration from URLs
+-------------------------------
+
+Configuration files can be loaded from URLs.  To see how this works,
+we'll set up a web server with some configuration files.
+
+    >>> server_data = tmpdir('server_data')
+
+    >>> write(server_data, "r1.cfg",
+    ... """
+    ... [debug]
+    ... op1 = r1 1
+    ... op2 = r1 2
+    ... """)
+
+    >>> write(server_data, "r2.cfg",
+    ... """
+    ... [buildout]
+    ... extends = r1.cfg
+    ...
+    ... [debug]
+    ... op2 = r2 2
+    ... op3 = r2 3
+    ... """)
+
+    >>> server_url = start_server(server_data)
+
+    >>> write('client.cfg',
+    ... """
+    ... [buildout]
+    ... develop = recipes
+    ... parts = debug
+    ... extends = %(url)s/r2.cfg
+    ...
+    ... [debug]
+    ... recipe = recipes:debug
+    ... name = base
+    ... """ % dict(url=server_url))
+
+
+    >>> print system(buildout+ ' -c client.cfg'),
+    Develop: '/sample-buildout/recipes'
+    Uninstalling debug.
+    Installing debug.
+    name base
+    op1 r1 1
+    op2 r2 2
+    op3 r2 3
+    recipe recipes:debug
+
+Here we specified a URL for the file we extended.  The file we
+downloaded, itself referred to a file on the server using a relative
+URL reference.  Relative references are interpreted relative to the
+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
+buildout.
+
+    >>> os.remove('client.cfg')
+    >>> write(server_data, 'remote.cfg',
+    ... """
+    ... [buildout]
+    ... develop = recipes
+    ... parts = debug
+    ... extends = r2.cfg
+    ...
+    ... [debug]
+    ... recipe = recipes:debug
+    ... name = remote
+    ... """)
+
+    >>> print system(buildout + ' -c ' + server_url + '/remote.cfg'),
+    While:
+      Initializing.
+    Error: Missing option: buildout:directory
+
+Normally, the buildout directory defaults to directory
+containing a configuration file.  This won't work for configuration
+files loaded from URLs.  In this case, the buildout directory would
+normally be defined on the command line:
+
+    >>> print system(buildout
+    ...              + ' -c ' + server_url + '/remote.cfg'
+    ...              + ' buildout:directory=' + sample_buildout
+    ...              ),
+    Develop: '/sample-buildout/recipes'
+    Uninstalling debug.
+    Installing debug.
+    name remote
+    op1 r1 1
+    op2 r2 2
+    op3 r2 3
+    recipe recipes:debug
+
+User defaults
+-------------
+
+If the file $HOME/.buildout/default.cfg, exists, it is read before
+reading the configuration file.  ($HOME is the value of the HOME
+environment variable. The '/' is replaced by the operating system file
+delimiter.)
+
+    >>> old_home = os.environ['HOME']
+    >>> home = tmpdir('home')
+    >>> mkdir(home, '.buildout')
+    >>> write(home, '.buildout', 'default.cfg',
+    ... """
+    ... [debug]
+    ... op1 = 1
+    ... op7 = 7
+    ... """)
+
+    >>> os.environ['HOME'] = home
+    >>> print system(buildout),
+    Develop: '/sample-buildout/recipes'
+    Uninstalling debug.
+    Installing debug.
+    name base
+    op buildout
+    op1 b1 1
+    op2 b2 2
+    op3 b2 3
+    op4 b3 4
+    op5 b3base 5
+    op7 7
+    recipe recipes:debug
+
+A buildout command-line argument, -U, can be used to suppress reading
+user defaults:
+
+    >>> print system(buildout + ' -U'),
+    Develop: '/sample-buildout/recipes'
+    Uninstalling debug.
+    Installing debug.
+    name base
+    op buildout
+    op1 b1 1
+    op2 b2 2
+    op3 b2 3
+    op4 b3 4
+    op5 b3base 5
+    recipe recipes:debug
+
+    >>> os.environ['HOME'] = old_home
+
+Log level
+---------
+
+We can control the level of logging by specifying a log level in out
+configuration file.  For example, so suppress info messages, we can
+set the logging level to WARNING
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... log-level = WARNING
+    ... extends = b1.cfg b2.cfg
+    ... """)
+
+    >>> print system(buildout),
+    name base
+    op1 b1 1
+    op2 b2 2
+    op3 b2 3
+    recipe recipes:debug
+
+Uninstall recipes
+-----------------
+
+As we've seen, when parts are installed, buildout keeps track of files
+and directories that they create. When the parts are uninstalled these
+files and directories are deleted.
+
+Sometimes more clean up is needed. For example, a recipe might add a
+system service by calling chkconfig --add during installation. Later
+during uninstallation, chkconfig --del will need to be called to
+remove the system service.
+
+In order to deal with these uninstallation issues, you can register
+uninstall recipes. Uninstall recipes are registered using the
+'zc.buildout.uninstall' entry point. Parts specify uninstall recipes
+using the 'uninstall' option.
+
+In comparison to regular recipes, uninstall recipes are much
+simpler. They are simply callable objects that accept the name of the
+part to be uninstalled and the part's options dictionary. Uninstall
+recipes don't have access to the part itself since it maybe not be
+able to be instantiated at uninstallation time.
+
+Here's a recipe that simulates installation of a system service, along
+with an uninstall recipe that simulates removing the service.
+
+    >>> write(sample_buildout, 'recipes', 'service.py',
+    ... """
+    ... class Service:
+    ...
+    ...     def __init__(self, buildout, name, options):
+    ...         self.buildout = buildout
+    ...         self.name = name
+    ...         self.options = options
+    ...
+    ...     def install(self):
+    ...         print "chkconfig --add %s" % self.options['script']
+    ...         return ()
+    ...
+    ...     def update(self):
+    ...         pass
+    ...
+    ...
+    ... def uninstall_service(name, options):
+    ...     print "chkconfig --del %s" % options['script']
+    ... """)
+
+To use these recipes we must register them using entry points. Make
+sure to use the same name for the recipe and uninstall recipe. This is
+required to let buildout know which uninstall recipe goes with which
+recipe.
+
+    >>> write(sample_buildout, 'recipes', 'setup.py',
+    ... """
+    ... from setuptools import setup
+    ... entry_points = (
+    ... '''
+    ... [zc.buildout]
+    ... mkdir = mkdir:Mkdir
+    ... debug = debug:Debug
+    ... service = service:Service
+    ...
+    ... [zc.buildout.uninstall]
+    ... service = service:uninstall_service
+    ... ''')
+    ... setup(name="recipes", entry_points=entry_points)
+    ... """)
+
+Here's how these recipes could be used in a buildout:
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... develop = recipes
+    ... parts = service
+    ...
+    ... [service]
+    ... recipe = recipes:service
+    ... script = /path/to/script
+    ... """)
+
+When the buildout is run the service will be installed
+
+    >>> print system(buildout)
+    Develop: '/sample-buildout/recipes'
+    Uninstalling debug.
+    Installing service.
+    chkconfig --add /path/to/script
+    <BLANKLINE>
+
+The service has been installed. If the buildout is run again with no
+changes, the service shouldn't be changed.
+
+    >>> print system(buildout)
+    Develop: '/sample-buildout/recipes'
+    Updating service.
+    <BLANKLINE>
+
+Now we change the service part to trigger uninstallation and
+re-installation.
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... develop = recipes
+    ... parts = service
+    ...
+    ... [service]
+    ... recipe = recipes:service
+    ... script = /path/to/a/different/script
+    ... """)
+
+    >>> print system(buildout)
+    Develop: '/sample-buildout/recipes'
+    Uninstalling service.
+    Running uninstall recipe.
+    chkconfig --del /path/to/script
+    Installing service.
+    chkconfig --add /path/to/a/different/script
+    <BLANKLINE>
+
+Now we remove the service part, and add another part.
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... develop = recipes
+    ... parts = debug
+    ...
+    ... [debug]
+    ... recipe = recipes:debug
+    ... """)
+
+    >>> print system(buildout)
+    Develop: '/sample-buildout/recipes'
+    Uninstalling service.
+    Running uninstall recipe.
+    chkconfig --del /path/to/a/different/script
+    Installing debug.
+    recipe recipes:debug
+    <BLANKLINE>
+
+Uninstall recipes don't have to take care of removing all the files
+and directories created by the part. This is still done automatically,
+following the execution of the uninstall recipe. An upshot is that an
+uninstallation recipe can access files and directories created by a
+recipe before they are deleted.
+
+For example, here's an uninstallation recipe that simulates backing up
+a directory before it is deleted. It is designed to work with the
+mkdir recipe introduced earlier.
+
+    >>> write(sample_buildout, 'recipes', 'backup.py',
+    ... """
+    ... import os
+    ... def backup_directory(name, options):
+    ...     path = options['path']
+    ...     size = len(os.listdir(path))
+    ...     print "backing up directory %s of size %s" % (path, size)
+    ... """)
+
+It must be registered with the zc.buildout.uninstall entry
+point. Notice how it is given the name 'mkdir' to associate it with
+the mkdir recipe.
+
+    >>> write(sample_buildout, 'recipes', 'setup.py',
+    ... """
+    ... from setuptools import setup
+    ... entry_points = (
+    ... '''
+    ... [zc.buildout]
+    ... mkdir = mkdir:Mkdir
+    ... debug = debug:Debug
+    ... service = service:Service
+    ...
+    ... [zc.buildout.uninstall]
+    ... uninstall_service = service:uninstall_service
+    ... mkdir = backup:backup_directory
+    ... ''')
+    ... setup(name="recipes", entry_points=entry_points)
+    ... """)
+
+Now we can use it with a mkdir part.
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... develop = recipes
+    ... parts = dir debug
+    ...
+    ... [dir]
+    ... recipe = recipes:mkdir
+    ... path = my_directory
+    ...
+    ... [debug]
+    ... recipe = recipes:debug
+    ... """)
+
+Run the buildout to install the part.
+
+    >>> print system(buildout)
+    Develop: '/sample-buildout/recipes'
+    Uninstalling debug.
+    Installing dir.
+    dir: Creating directory my_directory
+    Installing debug.
+    recipe recipes:debug
+    <BLANKLINE>
+
+Now we remove the part from the configuration file.
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... develop = recipes
+    ... parts = debug
+    ...
+    ... [debug]
+    ... recipe = recipes:debug
+    ... """)
+
+When the buildout is run the part is removed, and the uninstall recipe
+is run before the directory is deleted.
+
+    >>> print system(buildout)
+    Develop: '/sample-buildout/recipes'
+    Uninstalling dir.
+    Running uninstall recipe.
+    backing up directory /sample-buildout/my_directory of size 0
+    Updating debug.
+    recipe recipes:debug
+    <BLANKLINE>
+
+Now we will return the registration to normal for the benefit of the
+rest of the examples.
+
+    >>> write(sample_buildout, 'recipes', 'setup.py',
+    ... """
+    ... from setuptools import setup
+    ... entry_points = (
+    ... '''
+    ... [zc.buildout]
+    ... mkdir = mkdir:Mkdir
+    ... debug = debug:Debug
+    ... ''')
+    ... setup(name="recipes", entry_points=entry_points)
+    ... """)
+
+
+Command-line usage
+------------------
+
+A number of arguments can be given on the buildout command line.  The
+command usage is::
+
+  buildout [options and assignments] [command [command arguments]]
+
+The following options are supported:
+
+-h (or --help)
+    Print basic usage information.  If this option is used, then all
+    other options are ignored.
+
+-c filename
+    The -c option can be used to specify a configuration file, rather than
+    buildout.cfg in the current directory.
+
+
+-t socket_timeout
+
+   Specify the socket timeout in seconds.
+
+-v
+    Increment the verbosity by 10.  The verbosity is used to adjust
+    the logging level.  The verbosity is subtracted from the numeric
+    value of the log-level option specified in the configuration file.
+
+-q
+    Decrement the verbosity by 10.
+
+-U
+    Don't read user-default configuration.
+
+-o
+    Run in off-line mode.  This is equivalent to the assignment
+    buildout:offline=true.
+
+-O
+    Run in non-off-line mode.  This is equivalent to the assignment
+    buildout:offline=false.  This is the default buildout mode.  The
+    -O option would normally be used to override a true offline
+    setting in a configuration file.
+
+-n
+    Run in newest mode.  This is equivalent to the assignment
+    buildout:newest=true.  With this setting, which is the default,
+    buildout will try to find the newest versions of distributions
+    available that satisfy its requirements.
+
+-N
+    Run in non-newest mode.  This is equivalent to the assignment
+    buildout:newest=false.  With this setting, buildout will not seek
+    new distributions if installed distributions satisfy it's
+    requirements.
+
+Assignments are of the form::
+
+  section_name:option_name=value
+
+Options and assignments can be given in any order.
+
+Here's an example:
+
+    >>> write(sample_buildout, 'other.cfg',
+    ... """
+    ... [buildout]
+    ... develop = recipes
+    ... parts = debug
+    ... installed = .other.cfg
+    ... log-level = WARNING
+    ...
+    ... [debug]
+    ... name = other
+    ... recipe = recipes:debug
+    ... """)
+
+Note that we used the installed buildout option to specify an
+alternate file to store information about installed parts.
+
+    >>> print system(buildout+' -c other.cfg debug:op1=foo -v'),
+    Develop: '/sample-buildout/recipes'
+    Installing debug.
+    name other
+    op1 foo
+    recipe recipes:debug
+
+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,
+WARNING.
+
+Options can also be combined in the usual Unix way, as in:
+
+    >>> print system(buildout+' -vcother.cfg debug:op1=foo'),
+    Develop: '/sample-buildout/recipes'
+    Updating debug.
+    name other
+    op1 foo
+    recipe recipes:debug
+
+Here we combined the -v and -c options with the configuration file
+name.  Note that the -c option has to be last, because it takes an
+argument.
+
+    >>> os.remove(os.path.join(sample_buildout, 'other.cfg'))
+    >>> os.remove(os.path.join(sample_buildout, '.other.cfg'))
+
+The most commonly used command is 'install' and it takes a list of
+parts to install. if any parts are specified, only those parts are
+installed.  To illustrate this, we'll update our configuration and run
+the buildout in the usual way:
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... develop = recipes
+    ... parts = debug d1 d2 d3
+    ...
+    ... [d1]
+    ... recipe = recipes:mkdir
+    ... path = d1
+    ...
+    ... [d2]
+    ... recipe = recipes:mkdir
+    ... path = d2
+    ...
+    ... [d3]
+    ... recipe = recipes:mkdir
+    ... path = d3
+    ...
+    ... [debug]
+    ... recipe = recipes:debug
+    ... """)
+
+    >>> print system(buildout),
+    Develop: '/sample-buildout/recipes'
+    Uninstalling debug.
+    Installing debug.
+    recipe recipes:debug
+    Installing d1.
+    d1: Creating directory d1
+    Installing d2.
+    d2: Creating directory d2
+    Installing d3.
+    d3: Creating directory d3
+
+    >>> ls(sample_buildout)
+    -  .installed.cfg
+    -  b1.cfg
+    -  b2.cfg
+    -  base.cfg
+    d  bin
+    -  buildout.cfg
+    d  d1
+    d  d2
+    d  d3
+    d  demo
+    d  develop-eggs
+    d  eggs
+    d  parts
+    d  recipes
+
+    >>> cat(sample_buildout, '.installed.cfg')
+    ... # doctest: +NORMALIZE_WHITESPACE
+    [buildout]
+    installed_develop_eggs = /sample-buildout/develop-eggs/recipes.egg-link
+    parts = debug d1 d2 d3
+    <BLANKLINE>
+    [debug]
+    __buildout_installed__ =
+    __buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
+    recipe = recipes:debug
+    <BLANKLINE>
+    [d1]
+    __buildout_installed__ = /sample-buildout/d1
+    __buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
+    path = /sample-buildout/d1
+    recipe = recipes:mkdir
+    <BLANKLINE>
+    [d2]
+    __buildout_installed__ = /sample-buildout/d2
+    __buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
+    path = /sample-buildout/d2
+    recipe = recipes:mkdir
+    <BLANKLINE>
+    [d3]
+    __buildout_installed__ = /sample-buildout/d3
+    __buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
+    path = /sample-buildout/d3
+    recipe = recipes:mkdir
+
+Now we'll update our configuration file:
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... develop = recipes
+    ... parts = debug d2 d3 d4
+    ...
+    ... [d2]
+    ... recipe = recipes:mkdir
+    ... path = data2
+    ...
+    ... [d3]
+    ... recipe = recipes:mkdir
+    ... path = data3
+    ...
+    ... [d4]
+    ... recipe = recipes:mkdir
+    ... path = ${d2:path}-extra
+    ...
+    ... [debug]
+    ... recipe = recipes:debug
+    ... x = 1
+    ... """)
+
+and run the buildout specifying just d3 and d4:
+
+    >>> print system(buildout+' install d3 d4'),
+    Develop: '/sample-buildout/recipes'
+    Uninstalling d3.
+    Installing d3.
+    d3: Creating directory data3
+    Installing d4.
+    d4: Creating directory data2-extra
+
+    >>> ls(sample_buildout)
+    -  .installed.cfg
+    -  b1.cfg
+    -  b2.cfg
+    -  base.cfg
+    d  bin
+    -  buildout.cfg
+    d  d1
+    d  d2
+    d  data2-extra
+    d  data3
+    d  demo
+    d  develop-eggs
+    d  eggs
+    d  parts
+    d  recipes
+
+Only the d3 and d4 recipes ran.  d3 was removed and data3 and data2-extra
+were created.
+
+The .installed.cfg is only updated for the recipes that ran:
+
+    >>> cat(sample_buildout, '.installed.cfg')
+    ... # doctest: +NORMALIZE_WHITESPACE
+    [buildout]
+    installed_develop_eggs = /sample-buildout/develop-eggs/recipes.egg-link
+    parts = debug d1 d2 d3 d4
+    <BLANKLINE>
+    [debug]
+    __buildout_installed__ =
+    __buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
+    recipe = recipes:debug
+    <BLANKLINE>
+    [d1]
+    __buildout_installed__ = /sample-buildout/d1
+    __buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
+    path = /sample-buildout/d1
+    recipe = recipes:mkdir
+    <BLANKLINE>
+    [d2]
+    __buildout_installed__ = /sample-buildout/d2
+    __buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
+    path = /sample-buildout/d2
+    recipe = recipes:mkdir
+    <BLANKLINE>
+    [d3]
+    __buildout_installed__ = /sample-buildout/data3
+    __buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
+    path = /sample-buildout/data3
+    recipe = recipes:mkdir
+    <BLANKLINE>
+    [d4]
+    __buildout_installed__ = /sample-buildout/data2-extra
+    __buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
+    path = /sample-buildout/data2-extra
+    recipe = recipes:mkdir
+
+Note that the installed data for debug, d1, and d2 haven't changed,
+because we didn't install those parts and that the d1 and d2
+directories are still there.
+
+Now, if we run the buildout without the install command:
+
+    >>> print system(buildout),
+    Develop: '/sample-buildout/recipes'
+    Uninstalling d2.
+    Uninstalling d1.
+    Uninstalling debug.
+    Installing debug.
+    recipe recipes:debug
+    x 1
+    Installing d2.
+    d2: Creating directory data2
+    Updating d3.
+    Updating d4.
+
+We see the output of the debug recipe and that data2 was created.  We
+also see that d1 and d2 have gone away:
+
+    >>> ls(sample_buildout)
+    -  .installed.cfg
+    -  b1.cfg
+    -  b2.cfg
+    -  base.cfg
+    d  bin
+    -  buildout.cfg
+    d  data2
+    d  data2-extra
+    d  data3
+    d  demo
+    d  develop-eggs
+    d  eggs
+    d  parts
+    d  recipes
+
+Alternate directory and file locations
+--------------------------------------
+
+The buildout normally puts the bin, eggs, and parts directories in the
+directory in the directory containing the configuration file. You can
+provide alternate locations, and even names for these directories.
+
+    >>> alt = tmpdir('sample-alt')
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... develop = recipes
+    ... parts =
+    ... develop-eggs-directory = %(developbasket)s
+    ... eggs-directory = %(basket)s
+    ... bin-directory = %(scripts)s
+    ... parts-directory = %(work)s
+    ... """ % dict(
+    ...    developbasket = os.path.join(alt, 'developbasket'),
+    ...    basket = os.path.join(alt, 'basket'),
+    ...    scripts = os.path.join(alt, 'scripts'),
+    ...    work = os.path.join(alt, 'work'),
+    ... ))
+
+    >>> print system(buildout),
+    Creating directory '/sample-alt/scripts'.
+    Creating directory '/sample-alt/work'.
+    Creating directory '/sample-alt/basket'.
+    Creating directory '/sample-alt/developbasket'.
+    Develop: '/sample-buildout/recipes'
+    Uninstalling d4.
+    Uninstalling d3.
+    Uninstalling d2.
+    Uninstalling debug.
+
+    >>> ls(alt)
+    d  basket
+    d  developbasket
+    d  scripts
+    d  work
+
+    >>> ls(alt, 'developbasket')
+    -  recipes.egg-link
+
+You can also specify an alternate buildout directory:
+
+    >>> rmdir(alt)
+    >>> alt = tmpdir('sample-alt')
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... directory = %(alt)s
+    ... develop = %(recipes)s
+    ... parts =
+    ... """ % dict(
+    ...    alt=alt,
+    ...    recipes=os.path.join(sample_buildout, 'recipes'),
+    ...    ))
+
+    >>> print system(buildout),
+    Creating directory '/sample-alt/bin'.
+    Creating directory '/sample-alt/parts'.
+    Creating directory '/sample-alt/eggs'.
+    Creating directory '/sample-alt/develop-eggs'.
+    Develop: '/sample-buildout/recipes'
+
+    >>> ls(alt)
+    -  .installed.cfg
+    d  bin
+    d  develop-eggs
+    d  eggs
+    d  parts
+
+    >>> ls(alt, 'develop-eggs')
+    -  recipes.egg-link
+
+Logging control
+---------------
+
+Three buildout options are used to control logging:
+
+log-level
+   specifies the log level
+
+verbosity
+   adjusts the log level
+
+log-format
+   allows an alternate logging for mat to be specified
+
+We've already seen the log level and verbosity.  Let's look at an example
+of changing the format:
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... develop = recipes
+    ... parts =
+    ... log-level = 25
+    ... verbosity = 5
+    ... log-format = %(levelname)s %(message)s
+    ... """)
+
+Here, we've changed the format to include the log-level name, rather
+than the logger name.
+
+We've also illustrated, with a contrived example, that the log level
+can be a numeric value and that the verbosity can be specified in the
+configuration file.  Because the verbosity is subtracted from the log
+level, we get a final log level of 20, which is the INFO level.
+
+    >>> print system(buildout),
+    INFO Develop: '/sample-buildout/recipes'
+
+Predefined buildout options
+---------------------------
+
+Buildouts have a number of predefined options that recipes can use
+and that users can override in their configuration files.  To see
+these, we'll run a minimal buildout configuration with a debug logging
+level.  One of the features of debug logging is that the configuration
+database is shown.
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... parts =
+    ... """)
+
+    >>> print system(buildout+' -vv'), # doctest: +NORMALIZE_WHITESPACE
+    Installing 'zc.buildout', 'setuptools'.
+    We have a develop egg: zc.buildout X.X.
+    We have the best distribution that satisfies 'setuptools'.
+    Picked: setuptools = V.V
+    <BLANKLINE>
+    Configuration data:
+    [buildout]
+    accept-buildout-test-releases = false
+    allow-hosts = *
+    allow-picked-versions = true
+    allowed-eggs-from-site-packages = *
+    bin-directory = /sample-buildout/bin
+    develop-eggs-directory = /sample-buildout/develop-eggs
+    directory = /sample-buildout
+    eggs-directory = /sample-buildout/eggs
+    exec-sitecustomize = true
+    executable = python
+    find-links =
+    include-site-packages = true
+    install-from-cache = false
+    installed = /sample-buildout/.installed.cfg
+    log-format =
+    log-level = INFO
+    newest = true
+    offline = false
+    parts =
+    parts-directory = /sample-buildout/parts
+    prefer-final = false
+    python = buildout
+    relative-paths = false
+    socket-timeout =
+    unzip = false
+    use-dependency-links = true
+    verbosity = 20
+    <BLANKLINE>
+
+All of these options can be overridden by configuration files or by
+command-line assignments.  We've discussed most of these options
+already, but let's review them and touch on some we haven't discussed:
+
+allowed-eggs-from-site-packages
+    Sometimes you need or want to control what eggs from site-packages are
+    used. The allowed-eggs-from-site-packages option allows you to specify a
+    whitelist of project names that may be included from site-packages.  You
+    can use globs to specify the value.  It defaults to a single value of '*',
+    indicating that any package may come from site-packages.
+
+    Here's a usage example::
+
+        [buildout]
+        ...
+
+        allowed-eggs-from-site-packages =
+            demo
+            bigdemo
+            zope.*
+
+    This option interacts with the ``include-site-packages`` option in the
+    following ways.
+
+    If ``include-site-packages`` is true, then
+    ``allowed-eggs-from-site-packages`` filters what eggs from site-packages
+    may be chosen.  Therefore, if ``allowed-eggs-from-site-packages`` is an
+    empty list, then no eggs from site-packages are chosen, but site-packages
+    will still be included at the end of path lists.
+
+    If ``include-site-packages`` is false, the value of
+    ``allowed-eggs-from-site-packages`` is irrelevant.
+
+    See the ``include-site-packages`` description for more information.
+
+bin-directory
+   The directory path where scripts are written.  This can be a
+   relative path, which is interpreted relative to the directory
+   option.
+
+develop-eggs-directory
+   The directory path where development egg links are created for software
+   being created in the local project.  This can be a relative path,
+   which is interpreted relative to the directory option.
+
+directory
+   The buildout directory.  This is the base for other buildout file
+   and directory locations, when relative locations are used.
+
+eggs-directory
+   The directory path where downloaded eggs are put.  It is common to share
+   this directory across buildouts. Eggs in this directory should
+   *never* be modified.  This can be a relative path, which is
+   interpreted relative to the directory option.
+
+exec-sitecustomize
+    Normally the Python's real sitecustomize module is processed.
+    If you do not want it to be processed in order to increase the
+    repeatability of your buildout, set this value to 'false'.  This will
+    be honored irrespective of the setting for include-site-packages.
+    This option will be honored by some recipes and not others.
+    z3c.recipe.scripts honors this and zc.recipe.egg does not, for
+    instance.
+
+executable
+   The Python executable used to run the buildout.  See the python
+   option below.
+
+include-site-packages
+    You can choose not to have the site-packages of the underlying Python
+    available to your script or interpreter, in addition to the packages
+    from your eggs.  This can increase repeatability for your buildout.
+    This option will be better used by some recipes than others.
+    z3c.recipe.scripts honors this fully and zc.recipe.egg only
+    partially, for instance.
+
+installed
+   The file path where information about the results of the previous
+   buildout run is written.  This can be a relative path, which is
+   interpreted relative to the directory option.  This file provides
+   an inventory of installed parts with information needed to decide
+   which if any parts need to be uninstalled.
+
+log-format
+   The format used for logging messages.
+
+log-level
+   The log level before verbosity adjustment
+
+parts
+   A white space separated list of parts to be installed.
+
+parts-directory
+   A working directory that parts can used to store data.
+
+python
+   The name of a section containing information about the default
+   Python interpreter.  Recipes that need a installation
+   typically have options to tell them which Python installation to
+   use.  By convention, if a section-specific option isn't used, the
+   option is looked for in the buildout section.  The option must
+   point to a section with an executable option giving the path to a
+   Python executable.  By default, the buildout section defines the
+   default Python as the Python used to run the buildout.
+
+relative-paths
+    The paths generated by zc.buildout are absolute by default, and this
+    option is ``false``.  However, if you set this value to be ``true``,
+    bin/buildout will be generated with code that makes the paths relative.
+    Some recipes, such as zc.recipe.egg and z3c.recipe.scripts, honor this
+    value as well.
+
+unzip
+    By default, zc.buildout doesn't unzip zip-safe eggs ("unzip = false").
+    This follows the policy followed by setuptools itself.  Experience shows
+    this policy to to be inconvenient.  Zipped eggs make debugging more
+    difficult and often import more slowly.  You can include an unzip option in
+    the buildout section to change the default unzipping policy ("unzip =
+    true").
+
+use-dependency-links
+    By default buildout will obey the setuptools dependency_links metadata
+    when it looks for dependencies. This behavior can be controlled with
+    the use-dependency-links buildout option::
+
+      [buildout]
+      ...
+      use-dependency-links = false
+
+    The option defaults to true. If you set it to false, then dependency
+    links are only looked for in the locations specified by find-links.
+
+verbosity
+   A log-level adjustment.  Typically, this is set via the -q and -v
+   command-line options.
+
+
+Creating new buildouts and bootstrapping
+----------------------------------------
+
+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
+local buildout scripts.
+
+    >>> sample_bootstrapped = tmpdir('sample-bootstrapped')
+
+    >>> print system(buildout
+    ...              +' -c'+os.path.join(sample_bootstrapped, 'setup.cfg')
+    ...              +' init'),
+    Creating '/sample-bootstrapped/setup.cfg'.
+    Creating directory '/sample-bootstrapped/bin'.
+    Creating directory '/sample-bootstrapped/parts'.
+    Creating directory '/sample-bootstrapped/eggs'.
+    Creating directory '/sample-bootstrapped/develop-eggs'.
+    Generated script '/sample-bootstrapped/bin/buildout'.
+
+Note that a basic setup.cfg was created for us.
+
+    >>> ls(sample_bootstrapped)
+    d  bin
+    d  develop-eggs
+    d  eggs
+    d  parts
+    -  setup.cfg
+
+    >>> ls(sample_bootstrapped, 'bin')
+    -  buildout
+
+    >>> _ = (ls(sample_bootstrapped, 'eggs'),
+    ...      ls(sample_bootstrapped, 'develop-eggs'))
+    -  setuptools-0.6-py2.3.egg
+    -  zc.buildout-1.0-py2.3.egg
+
+(We list both the eggs and develop-eggs directories because the
+buildout or setuptools egg could be installed in the develop-eggs
+directory if the original buildout had develop eggs for either
+buildout or setuptools.)
+
+If relative-paths is ``true``, the buildout script uses relative paths.
+
+    >>> write(sample_bootstrapped, 'setup.cfg',
+    ... '''
+    ... [buildout]
+    ... relative-paths = true
+    ... parts =
+    ... ''')
+
+    >>> print system(buildout
+    ...              +' -c'+os.path.join(sample_bootstrapped, 'setup.cfg')
+    ...              +' bootstrap'),
+    Generated script '/sample-bootstrapped/bin/buildout'.
+
+    >>> buildout_script = join(sample_bootstrapped, 'bin', 'buildout')
+    >>> import sys
+    >>> if sys.platform.startswith('win'):
+    ...     buildout_script += '-script.py'
+    >>> print open(buildout_script).read() # doctest: +ELLIPSIS
+    #!... -S
+    <BLANKLINE>
+    import os
+    <BLANKLINE>
+    join = os.path.join
+    base = os.path.dirname(os.path.abspath(os.path.realpath(__file__)))
+    base = os.path.dirname(base)
+    <BLANKLINE>
+    import sys
+    sys.path[0:0] = [
+        join(base, 'parts/buildout'),
+        ]
+    <BLANKLINE>
+    <BLANKLINE>
+    import os
+    path = sys.path[0]
+    if os.environ.get('PYTHONPATH'):
+        path = os.pathsep.join([path, os.environ['PYTHONPATH']])
+    os.environ['BUILDOUT_ORIGINAL_PYTHONPATH'] = os.environ.get('PYTHONPATH', '')
+    os.environ['PYTHONPATH'] = path
+    import site # imports custom buildout-generated site.py
+    <BLANKLINE>
+    import zc.buildout.buildout
+    <BLANKLINE>
+    if __name__ == '__main__':
+        zc.buildout.buildout.main()
+    <BLANKLINE>
+
+
+Note that, in the above two examples, the buildout script was installed
+but not run.  To run the buildout, we'd have to run the installed
+buildout script.
+
+If we have an existing buildout that already has a buildout.cfg, we'll
+normally use the bootstrap command instead of init.  It will complain
+if there isn't a configuration file:
+
+    >>> sample_bootstrapped2 = tmpdir('sample-bootstrapped2')
+
+    >>> print system(buildout
+    ...              +' -c'+os.path.join(sample_bootstrapped2, 'setup.cfg')
+    ...              +' bootstrap'),
+    While:
+      Initializing.
+    Error: Couldn't open /sample-bootstrapped2/setup.cfg
+
+    >>> write(sample_bootstrapped2, 'setup.cfg',
+    ... """
+    ... [buildout]
+    ... parts =
+    ... """)
+
+    >>> print system(buildout
+    ...              +' -c'+os.path.join(sample_bootstrapped2, 'setup.cfg')
+    ...              +' bootstrap'),
+    Creating directory '/sample-bootstrapped2/bin'.
+    Creating directory '/sample-bootstrapped2/parts'.
+    Creating directory '/sample-bootstrapped2/eggs'.
+    Creating directory '/sample-bootstrapped2/develop-eggs'.
+    Generated script '/sample-bootstrapped2/bin/buildout'.
+
+
+Newest and Offline Modes
+------------------------
+
+By default buildout and recipes will try to find the newest versions
+of distributions needed to satisfy requirements.  This can be very
+time consuming, especially when incrementally working on setting up a
+buildout or working on a recipe.  The buildout newest option can be
+used to to suppress this.  If the newest option is set to false, then
+new distributions won't be sought if an installed distribution meets
+requirements.  The newest option can be set to false using the -N
+command-line option.
+
+The offline option goes a bit further.  If the buildout offline option
+is given a value of "true", the buildout and recipes that are aware of
+the option will avoid doing network access.  This is handy when
+running the buildout when not connected to the internet.  It also
+makes buildouts run much faster. This option is typically set using
+the buildout -o option.
+
+Preferring Final Releases
+-------------------------
+
+Currently, when searching for new releases of your project's
+dependencies, the newest available release is used.  This isn't usually
+ideal, as you may get a development release or alpha releases not ready
+to be widely used. You can request that final releases be preferred
+using the ``prefer-final`` option in the buildout section::
+
+  [buildout]
+  ...
+  prefer-final = true
+
+When the ``prefer-final`` option is set to true, then when searching for
+new releases, final releases are preferred.  If there are final
+releases that satisfy distribution requirements, then those releases
+are used even if newer non-final releases are available.
+
+In buildout version 2, all final releases will be preferred by
+default--that is ``prefer-final`` will also default to 'true'. You will
+then need to use a 'false' value for ``prefer-final`` to get the newest
+releases.
+
+A separate option controls the behavior of the build system itself.
+When buildout looks for recipes, extensions, and for updates to itself,
+it does prefer final releases by default, as of the 1.5.0 release.  The
+``accept-buildout-test-releases`` option will let you override this behavior.
+However, it is typically changed by the --accept-buildout-test-releases
+option to the bootstrap script, since bootstrapping is the first step to
+selecting a buildout.
+
+Finding distributions
+---------------------
+
+By default, buildout searches the Python Package Index when looking
+for distributions. You can, instead, specify your own index to search
+using the `index` option::
+
+  [buildout]
+  ...
+  index = http://index.example.com/
+
+This index, or the default of http://pypi.python.org/simple/ if no
+index is specified, will always be searched for distributions unless
+running buildout with options that prevent searching for
+distributions. The latest version of the distribution that meets the
+requirements of the buildout will always be used.
+
+You can also specify more locations to search for distributions using
+the `find-links` option. All locations specified will be searched for
+distributions along with the package index as described before.
+
+Locations can be urls::
+
+  [buildout]
+  ...
+  find-links = http://download.zope.org/distribution/
+
+They can also be directories on disk::
+
+  [buildout]
+  ...
+  find-links = /some/path
+
+Finally, they can also be direct paths to distributions::
+
+  [buildout]
+  ...
+  find-links = /some/path/someegg-1.0.0-py2.3.egg
+
+Any number of locations can be specified in the `find-links` option::
+
+  [buildout]
+  ...
+  find-links =
+      http://download.zope.org/distribution/
+      /some/otherpath
+      /some/path/someegg-1.0.0-py2.3.egg
+
+Dependency links
+----------------
+
+By default buildout will obey the setuptools dependency_links metadata
+when it looks for dependencies. This behavior can be controlled with
+the use-dependency-links buildout option::
+
+  [buildout]
+  ...
+  use-dependency-links = false
+
+The option defaults to true. If you set it to false, then dependency
+links are only looked for in the locations specified by find-links.
+
+Controlling the installation database
+-------------------------------------
+
+The buildout installed option is used to specify the file used to save
+information on installed parts.  This option is initialized to
+".installed.cfg", but it can be overridden in the configuration file
+or on the command line:
+
+    >>> write('buildout.cfg',
+    ... """
+    ... [buildout]
+    ... develop = recipes
+    ... parts = debug
+    ...
+    ... [debug]
+    ... recipe = recipes:debug
+    ... """)
+
+    >>> print system(buildout+' buildout:installed=inst.cfg'),
+    Develop: '/sample-buildout/recipes'
+    Installing debug.
+    recipe recipes:debug
+
+    >>> ls(sample_buildout)
+    -  b1.cfg
+    -  b2.cfg
+    -  base.cfg
+    d  bin
+    -  buildout.cfg
+    d  demo
+    d  develop-eggs
+    d  eggs
+    -  inst.cfg
+    d  parts
+    d  recipes
+
+The installation database can be disabled by supplying an empty
+buildout installed option:
+
+    >>> os.remove('inst.cfg')
+    >>> print system(buildout+' buildout:installed='),
+    Develop: '/sample-buildout/recipes'
+    Installing debug.
+    recipe recipes:debug
+
+    >>> ls(sample_buildout)
+    -  b1.cfg
+    -  b2.cfg
+    -  base.cfg
+    d  bin
+    -  buildout.cfg
+    d  demo
+    d  develop-eggs
+    d  eggs
+    d  parts
+    d  recipes
+
+
+Note that there will be no installation database if there are no parts:
+
+    >>> write('buildout.cfg',
+    ... """
+    ... [buildout]
+    ... parts =
+    ... """)
+
+    >>> print system(buildout+' buildout:installed=inst.cfg'),
+
+    >>> ls(sample_buildout)
+    -  b1.cfg
+    -  b2.cfg
+    -  base.cfg
+    d  bin
+    -  buildout.cfg
+    d  demo
+    d  develop-eggs
+    d  eggs
+    d  parts
+    d  recipes
+
+Extensions
+----------
+
+A feature allows code to be loaded and run after
+configuration files have been read but before the buildout has begun
+any processing.  The intent is to allow special plugins such as
+urllib2 request handlers to be loaded.
+
+To load an extension, we use the extensions option and list one or
+more distribution requirements, on separate lines.  The distributions
+named will be loaded and any ``zc.buildout.extension`` entry points found
+will be called with the buildout as an argument.  When buildout
+finishes processing, any ``zc.buildout.unloadextension`` entry points
+found will be called with the buildout as an argument.
+
+Let's create a sample extension in our sample buildout created in the
+previous section:
+
+    >>> mkdir(sample_bootstrapped, 'demo')
+
+    >>> write(sample_bootstrapped, 'demo', 'demo.py',
+    ... """
+    ... def ext(buildout):
+    ...     print 'ext', list(buildout)
+    ... def unload(buildout):
+    ...     print 'unload', list(buildout)
+    ... """)
+
+    >>> write(sample_bootstrapped, 'demo', 'setup.py',
+    ... """
+    ... from setuptools import setup
+    ...
+    ... setup(
+    ...     name = "demo",
+    ...     entry_points = {
+    ...        'zc.buildout.extension': ['ext = demo:ext'],
+    ...        'zc.buildout.unloadextension': ['ext = demo:unload'],
+    ...        },
+    ...     )
+    ... """)
+
+Our extension just prints out the word 'demo', and lists the sections
+found in the buildout passed to it.
+
+We'll update our buildout.cfg to list the demo directory as a develop
+egg to be built:
+
+    >>> write(sample_bootstrapped, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... develop = demo
+    ... parts =
+    ... """)
+
+    >>> os.chdir(sample_bootstrapped)
+    >>> print system(os.path.join(sample_bootstrapped, 'bin', 'buildout')),
+    Develop: '/sample-bootstrapped/demo'
+
+Now we can add the extensions option.  We were a bit tricky and ran
+the buildout once with the demo develop egg defined but without the
+extension option.  This is because extensions are loaded before the
+buildout creates develop eggs. We needed to use a separate buildout
+run to create the develop egg.  Normally, when eggs are loaded from
+the network, we wouldn't need to do anything special.
+
+    >>> write(sample_bootstrapped, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... develop = demo
+    ... extensions = demo
+    ... parts =
+    ... """)
+
+We see that our extension is loaded and executed:
+
+    >>> print system(os.path.join(sample_bootstrapped, 'bin', 'buildout')),
+    ext ['buildout']
+    Develop: '/sample-bootstrapped/demo'
+    unload ['buildout']
+
+Allow hosts
+-----------
+
+On some environments the links visited by `zc.buildout` can be forbidden
+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,
+wheter they are defined by various eggs in their `url`, `download_url`,
+`dependency_links` metadata.
+
+It is even harder to track that package_index works like a spider and
+might visit links and go to other location.
+
+The `allow-hosts` option provides a way to prevent this, and
+works exactly like the one provided in `easy_install`.
+
+You can provide a list of allowed host, together with wildcards::
+
+    [buildout]
+    ...
+
+    allow-hosts =
+        *.python.org
+        example.com
+
+All urls that does not match these hosts will not be visited.
+
+.. [#future_recipe_methods] In the future, additional methods may be
+       added. Older recipes with fewer methods will still be
+       supported.
+
+.. [#packaging_info] If we wanted to create a distribution from this
+       package, we would need specify much more information.  See the
+       `setuptools documentation
+       <http://peak.telecommunity.com/DevCenter/setuptools>`_.