Commit a85b2c1b authored by jim's avatar jim

Refined documentation.

Fixed small bug in handling of custom installed.cfg location.


git-svn-id: http://svn.zope.org/repos/main/zc.buildout/trunk@68652 62d5b8a3-27da-0310-9561-8e5933582275
parent 7ab3e42d
...@@ -8,7 +8,7 @@ may actually contain multiple programs, processes, and configuration ...@@ -8,7 +8,7 @@ may actually contain multiple programs, processes, and configuration
settings. settings.
The word "buildout" refers to a description of a set of parts and the The word "buildout" refers to a description of a set of parts and the
software to create ans assemble them. It is often used informally to software to create and assemble them. It is often used informally to
refer to an installed system based on a buildout definition. For refer to an installed system based on a buildout definition. For
example, if we are creating an application named "Foo", then "the Foo 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
......
...@@ -119,6 +119,9 @@ class Buildout(dict): ...@@ -119,6 +119,9 @@ class Buildout(dict):
if not os.path.exists(d): if not os.path.exists(d):
os.mkdir(d) os.mkdir(d)
options['installed'] = os.path.join(options['directory'],
options['installed'])
def _dosubs(self, section, option, value, data, converted, seen): def _dosubs(self, section, option, value, data, converted, seen):
key = section, option key = section, option
r = converted.get(key) r = converted.get(key)
......
Defining Buildouts 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 This document describes how to define buildouts using buildout
configuation files and recipes. There are two ways to set up the configuation files and recipes. There are two ways to set up the
buildout software and create a buildout: buildout software and create a buildout instance:
1. Install the zc.buildout egg with easy_install and use the buildout 1. Install the zc.buildout egg with easy_install and use the buildout
script installed in a Python scripts area. script installed in a Python scripts area.
2. Use the buildout bootstrap script to install both the setuptools 2. Use the buildout bootstrap script to create a buildout that
and zc.buildout eggs into your buildout. This allows you to use includes both the setuptools and zc.buildout eggs. This allows you
the buildout software without modifying a Python install. to use the buildout software without modifying a Python install.
The buildout script is installed into your buildout local scripts The buildout script is installed into your buildout local scripts
area. area.
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 has already been created for us. It We have a sample buildout that has already been created for us. It
has the absolute minimum information. We have bin, eggs and parts has the absolute minimum information. We have bin, eggs and parts
directories, a configuration file, and an .installed,cfg that contains directories, a configuration file, and an .installed,cfg that contains
...@@ -27,20 +44,15 @@ informatiion about previously-installed parts: ...@@ -27,20 +44,15 @@ informatiion about previously-installed parts:
d parts d parts
The bin directory contains scripts. In the examples shown here, we've The bin directory contains scripts. In the examples shown here, we've
used a hybrid approach for creating the to ease automated setup. We used a hybrid approach for creating the buildout to ease automated
have a buildout script in our buildout script directory, but the eggs setup. We have a buildout script in our buildout script directory,
actually live elsewhere. but the zc.buildout and setuptools eggs actually live elsewhere.
>>> ls(sample_buildout, 'bin') >>> ls(sample_buildout, 'bin')
- buildout - buildout
>>> ls(sample_buildout, 'eggs') >>> ls(sample_buildout, 'eggs')
Buildouts are defined using configuration files. These are in the
format defined by the Python ConfigParser module, with an extension
that we'll describe later. When a buildout is run, it looks for the
file buildout.cfg in the directory where the buidout is run.
The parts directory is initially empty: The parts directory is initially empty:
>>> ls(sample_buildout, 'parts') >>> ls(sample_buildout, 'parts')
...@@ -50,13 +62,11 @@ part data. For example, if we built a custom Python, we would ...@@ -50,13 +62,11 @@ part data. For example, if we built a custom Python, we would
install it in the part directory. Part data is stored in a install it in the part directory. Part data is stored in a
subdirectory of the parts directory with the same name as the part. subdirectory of the parts directory with the same name as the part.
The file .installed.cfg contains information about previously installed Buildouts are defined using configuration files. These are in the
parts. Because this is a new buildout, this file isn't very format defined by the Python ConfigParser module, with extensions
interesting: that we'll describe later. By default, when a buildout is run, it
looks for the file buildout.cfg in the directory where the buidout is
>>> cat(sample_buildout, '.installed.cfg') run.
[buildout]
parts =
The minimal configuration file has a buildout section that defines no The minimal configuration file has a buildout section that defines no
parts: parts:
...@@ -65,12 +75,20 @@ parts: ...@@ -65,12 +75,20 @@ parts:
[buildout] [buildout]
parts = parts =
The file .installed.cfg contains information about previously installed
parts. Because this is a new buildout, this file isn't very
interesting:
>>> cat(sample_buildout, '.installed.cfg')
[buildout]
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
a confguration file. even a confguration file.
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 an 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.
Let's create a recipe as part of the sample project. We'll create a Let's create a recipe as part of the sample project. We'll create a
recipe for creating directories. recipe for creating directories.
...@@ -115,22 +133,34 @@ directory is available as the directory option of the buildout ...@@ -115,22 +133,34 @@ 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.
**IMPORTANT**: Any time we use data from another section, it is important Any time we use data from another section, it is important to reflect
to reflect that data in the recipe options, as this data is used to that data in the recipe's options when the recipe is constructed.
decide if a part configuration has changed and a part needs to be When a buildout is run, it compares part-configuration data stored in
reinstalled. 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
before reinstalling it. 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 relevent data.
Of course, parts are also uninstalled if they are no-longer used.
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 case, we need the path of the directory to create. We'll use a
path option from our options dictionary. path option from our options dictionary.
We made the method chatty so that we can observe what it's doing. We made the method chatty so that we can observe what it's doing.
XXX use python logging module!
We return the path that we installed. If the part is unistalled or We return the path that we installed. If the part is unistalled or
reinstalled, then the path returned will be removed by the buildout reinstalled, then the path returned will be removed by the buildout
machinery. A recipe install method is expected to return None, a machinery. A recipe install method is expected to return None, a
string, or an iterable of strings containing paths to be removed if a string, or an iterable of strings containing paths to be removed if a
part is uninstalled. part is uninstalled. For most recipes, this is all of the uninstall
support needed. A recipe can provide custom uninstall support as will
be described later.
We need to provide packaging information so that our recipe can be We need to provide packaging information so that our recipe can be
installed as an egg. We need to define a setup script for this: installed as an egg. We need to define a setup script for this:
...@@ -145,7 +175,15 @@ installed as an egg. We need to define a setup script for this: ...@@ -145,7 +175,15 @@ installed as an egg. We need to define a setup script for this:
... ) ... )
... """) ... """)
Here we've defined a package with an entry_point. Entry points provide This setup script is incomplete. It doesn't describe what is to be
included in a distribution. This is fine if we never actually create
a distribution. If recipes are going to be used only internally in a
buildout, then we needn't include distribution information. If we
wanted to use the same recipes in multiple buildouts, then we'd need
to include proper distribution data. To find out more about creating
distributions, see the setuptools documentation.
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 a way for an egg to define the services it provides. Here we've said
that we define a zc.buildout entry point named default. Recipe that we define a zc.buildout entry point named default. Recipe
classes must be exposed as entry points in the zc.buildout group. we classes must be exposed as entry points in the zc.buildout group. we
...@@ -153,7 +191,8 @@ give entry points names within the group. The name "default" is ...@@ -153,7 +191,8 @@ give entry points names within the group. The name "default" is
somewhat special because it allows a recipe to be referenced using a somewhat special because it allows a recipe to be referenced using a
package name without naming an entry point. package name without naming an entry point.
We also need a README.txt for our recipes to avoid a warning: 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', " ") >>> write(sample_buildout, 'recipes', 'README.txt', " ")
...@@ -179,7 +218,7 @@ Any number of paths can be listed. The paths can be relative or ...@@ -179,7 +218,7 @@ Any number of paths can be listed. The paths can be relative or
absolute. If relative, they are treated as relative to the buidlout absolute. If relative, they are treated as relative to the buidlout
directory. They can be directory or file paths. If a file path is 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 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. is given, it should point to a directory containing a setup.py file.
Development eggs are installed before building any parts, as they may Development eggs are installed before building any parts, as they may
provide locally-defined recipes needed by the parts. provide locally-defined recipes needed by the parts.
...@@ -308,7 +347,8 @@ We also have to update our setup script: ...@@ -308,7 +347,8 @@ We also have to update our setup script:
... """) ... """)
We've rearranged the script a bit to make the entry points easier to We've rearranged the script a bit to make the entry points easier to
edit. 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 Let's update our configuration to provide variable substitution
examples: examples:
...@@ -335,11 +375,13 @@ examples: ...@@ -335,11 +375,13 @@ examples:
In this example, we've used ConfigParser substitutions for file2 and In this example, we've used ConfigParser substitutions for file2 and
file3. This type of substitution uses Python string format syntax. file3. This type of substitution uses Python string format syntax.
Valid names are option in the same section and options defined in the Valid names are options in the same section and options defined in the
DEFAULT section. We used a string-template substitution for file1. DEFAULT section.
This type of substituion uses the string.Template syntax. Names
substited are qualified option names, consisting of a section name and We used a string-template substitution for file1. This type of
option name joined by a colon. substituion uses the string.Template syntax. Names substited 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 Now, if we run the buildout, we'll see the options with the values
substituted. substituted.
...@@ -417,7 +459,7 @@ pretty common. In a more practical example, the base buildout might ...@@ -417,7 +459,7 @@ 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 eleborate example. Here is a more elaborate example.
>>> import tempfile >>> import tempfile
>>> extensions = tempfile.mkdtemp() >>> extensions = tempfile.mkdtemp()
...@@ -435,7 +477,6 @@ Here is a more eleborate example. ...@@ -435,7 +477,6 @@ Here is a more eleborate example.
... name = buildout ... name = buildout
... """ % dict(e2=os.path.join(extensions, 'e2.cfg'))) ... """ % dict(e2=os.path.join(extensions, 'e2.cfg')))
>>> write(sample_buildout, 'b1.cfg', >>> write(sample_buildout, 'b1.cfg',
... """ ... """
... [buildout] ... [buildout]
...@@ -532,10 +573,11 @@ There are several things to note about this example: ...@@ -532,10 +573,11 @@ There are several things to note about this example:
debug sections in several of the input files by virtue of being in debug sections in several of the input files by virtue of being in
their DEFAULT sections. their DEFAULT sections.
- Relative file names are determined relative to the directory - Relative file names in extended and extended-by options are
containing the referencing configuration file. The files eb.cfg and interpreted relative to the directory containing the referencing
ee.cfg were found in the extensions directory because they were configuration file. The files eb.cfg and ee.cfg were found in the
referenced from a file in that directory. extensions directory because they were referenced from a file in
that directory.
User defaults User defaults
------------- -------------
...@@ -580,25 +622,38 @@ buildout.cfg in the current durectory. Options are of the form:: ...@@ -580,25 +622,38 @@ buildout.cfg in the current durectory. Options are of the form::
section_name:option_name=value section_name:option_name=value
for example, as in: for example:
>>> write(sample_buildout, 'other.cfg',
... """
... [buildout]
... develop = recipes
... parts = debug
... installed = .other.cfg
...
... [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(os.path.join(sample_buildout, 'bin', 'buildout') >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')
... + ' debug:op1=foo'), ... + ' -c other.cfg debug:op1=foo'),
name ee name other
op buildout
op1 foo op1 foo
op2 b1 2
op3 b2 3
op4 b2 4
op5 eb 5
op6 ee 6
op7 7 op7 7
recipe recipes:debug recipe recipes:debug
>>> os.remove(os.path.join(sample_buildout, 'other.cfg'))
>>> os.remove(os.path.join(sample_buildout, '.other.cfg'))
Currently, the default and only command is 'install' and it takes a Currently, the default and only command is 'install' and it takes a
list of parts to install. if any parts are specified, then only those list of parts to install. if any parts are specified, then they must
parts are installed. To illustrate this, we'll update our be listed in the buildout parts option and only those parts are
configuration and run the buildout in the usual way: installed. To illustrate this, we'll update our configuration and run
the buildout in the usual way:
>>> write(sample_buildout, 'buildout.cfg', >>> write(sample_buildout, 'buildout.cfg',
... """ ... """
...@@ -793,8 +848,8 @@ also see that d1 and d2 have gone away: ...@@ -793,8 +848,8 @@ also see that d1 and d2 have gone away:
d parts d parts
d recipes d recipes
Alternate directory locations Alternate directory and file locations
----------------------------- --------------------------------------
The buildout normally puts the bin, eggs, and parts directories in the The buildout normally puts the bin, eggs, and parts directories in the
directory in the directory containing the configuration file. You can directory in the directory containing the configuration file. You can
......
...@@ -26,6 +26,16 @@ ...@@ -26,6 +26,16 @@
- Logging - Logging
- Some way to freeze versions so we can have reproducable buildouts.
- Part dependencies
- custom uninstall
- spelling :)
- example using -c. Example redefining .installed.cfg
Issues Issues
- Want to be able to control whether eggs get unzipped when they ae - Want to be able to control whether eggs get unzipped when they ae
......
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