source: TI12-security/trunk/NDGSecurity/python/buildout/ndgsecurity/eggs/zc.buildout-1.2.1-py2.5.egg/zc/buildout/buildout.txt @ 7081

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg-security/TI12-security/trunk/NDGSecurity/python/buildout/ndgsecurity/eggs/zc.buildout-1.2.1-py2.5.egg/zc/buildout/buildout.txt@7081
Revision 7081, 71.5 KB checked in by pjkersha, 11 years ago (diff)
  • Property svn:keywords set to Id
Line 
1Buildouts
2=========
3
4The word "buildout" refers to a description of a set of parts and the
5software to create and assemble them.  It is often used informally to
6refer to an installed system based on a buildout definition.  For
7example, if we are creating an application named "Foo", then "the Foo
8buildout" is the collection of configuration and application-specific
9software that allows an instance of the application to be created.  We
10may refer to such an instance of the application informally as "a Foo
11buildout".
12
13This document describes how to define buildouts using buildout
14configuration files and recipes.  There are three ways to set up the
15buildout software and create a buildout instance:
16
171. Install the zc.buildout egg with easy_install and use the buildout
18   script installed in a Python scripts area.
19
202. Use the buildout bootstrap script to create a buildout that
21   includes both the setuptools and zc.buildout eggs.  This allows you
22   to use the buildout software without modifying a Python install.
23   The buildout script is installed into your buildout local scripts
24   area.
25
263. Use a buildout command from an already installed buildout to
27   bootstrap a new buildout.  (See the section on bootstraping later
28   in this document.)
29
30Often, a software project will be managed in a software repository,
31such as a subversion repository, that includes some software source
32directories, buildout configuration files, and a copy of the buildout
33bootstrap script.  To work on the project, one would check out the
34project from the repository and run the bootstrap script which
35installs setuptools and zc.buildout into the checkout as well as any
36parts defined.
37
38We have a sample buildout that we created using the bootstrap command
39of an existing buildout (method 3 above).  It has the absolute minimum
40information.  We have bin, develop-eggs, eggs and parts directories,
41and a configuration file:
42
43    >>> ls(sample_buildout)
44    d  bin
45    -  buildout.cfg
46    d  develop-eggs
47    d  eggs
48    d  parts
49
50The bin directory contains scripts.
51
52    >>> ls(sample_buildout, 'bin')
53    -  buildout
54
55    >>> ls(sample_buildout, 'eggs')
56    -  setuptools-0.6-py2.4.egg
57    -  zc.buildout-1.0-py2.4.egg
58
59The develop-eggs and parts directories are initially empty:
60
61    >>> ls(sample_buildout, 'develop-eggs')
62    >>> ls(sample_buildout, 'parts')
63
64The develop-eggs directory holds egg links for software being
65developed in the buildout.  We separate develop-eggs and other eggs to
66allow eggs directories to be shared across multiple buildouts.  For
67example, a common developer technique is to define a common eggs
68directory in their home that all non-develop eggs are stored in.  This
69allows larger buildouts to be set up much more quickly and saves disk
70space.
71
72The parts directory provides an area where recipes can install
73part data.  For example, if we built a custom Python, we would
74install it in the part directory.  Part data is stored in a
75sub-directory of the parts directory with the same name as the part.
76
77Buildouts are defined using configuration files.  These are in the
78format defined by the Python ConfigParser module, with extensions
79that we'll describe later.  By default, when a buildout is run, it
80looks for the file buildout.cfg in the directory where the buildout is
81run.
82
83The minimal configuration file has a buildout section that defines no
84parts:
85
86    >>> cat(sample_buildout, 'buildout.cfg')
87    [buildout]
88    parts =
89
90A part is simply something to be created by a buildout.  It can be
91almost anything, such as a Python package, a program, a directory, or
92even a configuration file.
93
94Recipes
95-------
96
97A part is created by a recipe.  Recipes are always installed as Python
98eggs. They can be downloaded from a package server, such as the
99Python Package Index, or they can be developed as part of a project
100using a "develop" egg.
101
102A develop egg is a special kind of egg that gets installed as an "egg
103link" that contains the name of a source directory.  Develop eggs
104don't have to be packaged for distribution to be used and can be
105modified in place, which is especially useful while they are being
106developed.
107
108Let's create a recipe as part of the sample project.  We'll create a
109recipe for creating directories.  First, we'll create a recipes source
110directory for our local recipes:
111
112    >>> mkdir(sample_buildout, 'recipes')
113
114and then we'll create a source file for our mkdir recipe:
115
116    >>> write(sample_buildout, 'recipes', 'mkdir.py',
117    ... """
118    ... import logging, os, zc.buildout
119    ...
120    ... class Mkdir:
121    ...
122    ...     def __init__(self, buildout, name, options):
123    ...         self.name, self.options = name, options
124    ...         options['path'] = os.path.join(
125    ...                               buildout['buildout']['directory'],
126    ...                               options['path'],
127    ...                               )
128    ...         if not os.path.isdir(os.path.dirname(options['path'])):
129    ...             logging.getLogger(self.name).error(
130    ...                 'Cannot create %s. %s is not a directory.',
131    ...                 options['path'], os.path.dirname(options['path']))
132    ...             raise zc.buildout.UserError('Invalid Path')
133    ...
134    ...
135    ...     def install(self):
136    ...         path = self.options['path']
137    ...         logging.getLogger(self.name).info(
138    ...             'Creating directory %s', os.path.basename(path))
139    ...         os.mkdir(path)
140    ...         return path
141    ...
142    ...     def update(self):
143    ...         pass
144    ... """)
145
146Currently, recipes must define 3 methods [#future_recipe_methods]_:
147
148- a constructor,
149
150- an install method, and
151
152- an update method.
153
154The constructor is responsible for updating a parts options to reflect
155data read from other sections.  The buildout system keeps track of
156whether a part specification has changed.  A part specification has
157changed if it's options, after adjusting for data read from other
158sections, has changed, or if the recipe has changed.  Only the options
159for the part are considered.  If data are read from other sections,
160then that information has to be reflected in the parts options.  In
161the Mkdir example, the given path is interpreted relative to the
162buildout directory, and data from the buildout directory is read.  The
163path option is updated to reflect this.  If the directory option was
164changed in the buildout sections, we would know to update parts
165created using the mkdir recipe using relative path names.
166
167When buildout is run, it saves configuration data for installed parts
168in a file named ".installed.cfg".  In subsequent runs, it compares
169part-configuration data stored in the .installed.cfg file and the
170part-configuration data loaded from the configuration files as
171modified by recipe constructors to decide if the configuration of a
172part has changed. If the configuration has changed, or if the recipe
173has changed, then the part is uninstalled and reinstalled.  The
174buildout only looks at the part's options, so any data used to
175configure the part needs to be reflected in the part's options.  It is
176the job of a recipe constructor to make sure that the options include
177all relevant data.
178
179Of course, parts are also uninstalled if they are no-longer used.
180
181The recipe defines a constructor that takes a buildout object, a part
182name, and an options dictionary. It saves them in instance attributes.
183If the path is relative, we'll interpret it as relative to the
184buildout directory.  The buildout object passed in is a mapping from
185section name to a mapping of options for that section. The buildout
186directory is available as the directory option of the buildout
187section.  We normalize the path and save it back into the options
188directory.
189
190The install method is responsible for creating the part.  In this
191case, we need the path of the directory to create.  We'll use a path
192option from our options dictionary.  The install method logs what it's
193doing using the Python logging call.  We return the path that we
194installed.  If the part is uninstalled or reinstalled, then the path
195returned will be removed by the buildout machinery.  A recipe install
196method is expected to return a string, or an iterable of strings
197containing paths to be removed if a part is uninstalled.  For most
198recipes, this is all of the uninstall support needed. For more complex
199uninstallation scenarios use `Uninstall recipes`_.
200
201The update method is responsible for updating an already installed
202part.  An empty method is often provided, as in this example, if parts
203can't be updated.  An update method can return None, a string, or an
204iterable of strings.  If a string or iterable of strings is returned,
205then the saved list of paths to be uninstalled is updated with the new
206information by adding any new files returned by the update method.
207
208We need to provide packaging information so that our recipe can be
209installed as a develop egg. The minimum information we need to specify
210[#packaging_info]_ is a name.  For recipes, we also need to define the
211names of the recipe classes as entry points.  Packaging information is
212provided via a setup.py script:
213
214    >>> write(sample_buildout, 'recipes', 'setup.py',
215    ... """
216    ... from setuptools import setup
217    ...
218    ... setup(
219    ...     name = "recipes",
220    ...     entry_points = {'zc.buildout': ['mkdir = mkdir:Mkdir']},
221    ...     )
222    ... """)
223
224Our setup script defines an entry point. Entry points provide
225a way for an egg to define the services it provides.  Here we've said
226that we define a zc.buildout entry point named mkdir.  Recipe
227classes must be exposed as entry points in the zc.buildout group.  we
228give entry points names within the group.
229
230We also need a README.txt for our recipes to avoid an annoying warning
231from distutils, on which setuptools and zc.buildout are based:
232
233    >>> write(sample_buildout, 'recipes', 'README.txt', " ")
234
235Now let's update our buildout.cfg:
236
237    >>> write(sample_buildout, 'buildout.cfg',
238    ... """
239    ... [buildout]
240    ... develop = recipes
241    ... parts = data-dir
242    ...
243    ... [data-dir]
244    ... recipe = recipes:mkdir
245    ... path = mystuff
246    ... """)
247
248Let's go through the changes one by one::
249
250    develop = recipes
251
252This tells the buildout to install a development egg for our recipes.
253Any number of paths can be listed.  The paths can be relative or
254absolute.  If relative, they are treated as relative to the buildout
255directory.  They can be directory or file paths.  If a file path is
256given, it should point to a Python setup script.  If a directory path
257is given, it should point to a directory containing a setup.py file.
258Development eggs are installed before building any parts, as they may
259provide locally-defined recipes needed by the parts.
260
261::
262
263    parts = data-dir
264
265Here we've named a part to be "built".  We can use any name we want
266except that different part names must be unique and recipes will often
267use the part name to decide what to do.
268
269::
270
271    [data-dir]
272    recipe = recipes:mkdir
273    path = mystuff
274
275
276When we name a part, we also create a section of the same
277name that contains part data.  In this section, we'll define
278the recipe to be used to install the part.  In this case, we also
279specify the path to be created.
280
281Let's run the buildout.  We do so by running the build script in the
282buildout:
283
284    >>> import os
285    >>> os.chdir(sample_buildout)
286    >>> buildout = os.path.join(sample_buildout, 'bin', 'buildout')
287    >>> print system(buildout),
288    Develop: '/sample-buildout/recipes'
289    Installing data-dir.
290    data-dir: Creating directory mystuff
291
292We see that the recipe created the directory, as expected:
293
294    >>> ls(sample_buildout)
295    -  .installed.cfg
296    d  bin
297    -  buildout.cfg
298    d  develop-eggs
299    d  eggs
300    d  mystuff
301    d  parts
302    d  recipes
303
304In addition, .installed.cfg has been created containing information
305about the part we installed:
306
307    >>> cat(sample_buildout, '.installed.cfg')
308    [buildout]
309    installed_develop_eggs = /sample-buildout/develop-eggs/recipes.egg-link
310    parts = data-dir
311    <BLANKLINE>
312    [data-dir]
313    __buildout_installed__ = /sample-buildout/mystuff
314    __buildout_signature__ = recipes-c7vHV6ekIDUPy/7fjAaYjg==
315    path = /sample-buildout/mystuff
316    recipe = recipes:mkdir
317
318Note that the directory we installed is included in .installed.cfg.
319In addition, the path option includes the actual destination
320directory.
321
322If we change the name of the directory in the configuration file,
323we'll see that the directory gets removed and recreated:
324
325    >>> write(sample_buildout, 'buildout.cfg',
326    ... """
327    ... [buildout]
328    ... develop = recipes
329    ... parts = data-dir
330    ...
331    ... [data-dir]
332    ... recipe = recipes:mkdir
333    ... path = mydata
334    ... """)
335
336    >>> print system(buildout),
337    Develop: '/sample-buildout/recipes'
338    Uninstalling data-dir.
339    Installing data-dir.
340    data-dir: Creating directory mydata
341
342    >>> ls(sample_buildout)
343    -  .installed.cfg
344    d  bin
345    -  buildout.cfg
346    d  develop-eggs
347    d  eggs
348    d  mydata
349    d  parts
350    d  recipes
351
352If any of the files or directories created by a recipe are removed,
353the part will be reinstalled:
354
355    >>> rmdir(sample_buildout, 'mydata')
356    >>> print system(buildout),
357    Develop: '/sample-buildout/recipes'
358    Uninstalling data-dir.
359    Installing data-dir.
360    data-dir: Creating directory mydata
361
362Error reporting
363---------------
364
365If a user makes an error, an error needs to be printed and work needs
366to stop.  This is accomplished by logging a detailed error message and
367then raising a (or an instance of a subclass of a)
368zc.buildout.UserError exception.  Raising an error other than a
369UserError still displays the error, but labels it as a bug in the
370buildout software or recipe. In the sample above, of someone gives a
371non-existent directory to create the directory in:
372
373
374    >>> write(sample_buildout, 'buildout.cfg',
375    ... """
376    ... [buildout]
377    ... develop = recipes
378    ... parts = data-dir
379    ...
380    ... [data-dir]
381    ... recipe = recipes:mkdir
382    ... path = /xxx/mydata
383    ... """)
384
385We'll get a user error, not a traceback.
386
387    >>> print system(buildout),
388    Develop: '/sample-buildout/recipes'
389    data-dir: Cannot create /xxx/mydata. /xxx is not a directory.
390    While:
391      Installing.
392      Getting section data-dir.
393      Initializing part data-dir.
394    Error: Invalid Path
395
396
397Recipe Error Handling
398---------------------
399
400If an error occurs during installation, it is up to the recipe to
401clean up any system side effects, such as files created.  Let's update
402the mkdir recipe to support multiple paths:
403
404    >>> write(sample_buildout, 'recipes', 'mkdir.py',
405    ... """
406    ... import logging, os, zc.buildout
407    ...
408    ... class Mkdir:
409    ...
410    ...     def __init__(self, buildout, name, options):
411    ...         self.name, self.options = name, options
412    ...
413    ...         # Normalize paths and check that their parent
414    ...         # directories exist:
415    ...         paths = []
416    ...         for path in options['path'].split():
417    ...             path = os.path.join(buildout['buildout']['directory'], path)
418    ...             if not os.path.isdir(os.path.dirname(path)):
419    ...                 logging.getLogger(self.name).error(
420    ...                     'Cannot create %s. %s is not a directory.',
421    ...                     options['path'], os.path.dirname(options['path']))
422    ...                 raise zc.buildout.UserError('Invalid Path')
423    ...             paths.append(path)
424    ...         options['path'] = ' '.join(paths)
425    ...
426    ...     def install(self):
427    ...         paths = self.options['path'].split()
428    ...         for path in paths:
429    ...             logging.getLogger(self.name).info(
430    ...                 'Creating directory %s', os.path.basename(path))
431    ...             os.mkdir(path)
432    ...         return paths
433    ...
434    ...     def update(self):
435    ...         pass
436    ... """)
437
438If there is an error creating a path, the install method will exit and
439leave previously created paths in place:
440
441    >>> write(sample_buildout, 'buildout.cfg',
442    ... """
443    ... [buildout]
444    ... develop = recipes
445    ... parts = data-dir
446    ...
447    ... [data-dir]
448    ... recipe = recipes:mkdir
449    ... path = foo bin
450    ... """)
451
452    >>> print system(buildout), # doctest: +ELLIPSIS
453    Develop: '/sample-buildout/recipes'
454    Uninstalling data-dir.
455    Installing data-dir.
456    data-dir: Creating directory foo
457    data-dir: Creating directory bin
458    While:
459      Installing data-dir.
460    <BLANKLINE>
461    An internal error occured due to a bug in either zc.buildout or in a
462    recipe being used:
463    Traceback (most recent call last):
464      ...
465    OSError: [Errno 17] File exists: '/sample-buildout/bin'
466
467We meant to create a directory bins, but typed bin.  Now foo was
468left behind.
469
470    >>> os.path.exists('foo')
471    True
472
473If we fix the typo:
474
475    >>> write(sample_buildout, 'buildout.cfg',
476    ... """
477    ... [buildout]
478    ... develop = recipes
479    ... parts = data-dir
480    ...
481    ... [data-dir]
482    ... recipe = recipes:mkdir
483    ... path = foo bins
484    ... """)
485
486    >>> print system(buildout), # doctest: +ELLIPSIS
487    Develop: '/sample-buildout/recipes'
488    Installing data-dir.
489    data-dir: Creating directory foo
490    While:
491      Installing data-dir.
492    <BLANKLINE>
493    An internal error occured due to a bug in either zc.buildout or in a
494    recipe being used:
495    Traceback (most recent call last):
496    ...
497    OSError: [Errno 17] File exists: '/sample-buildout/foo'
498
499Now they fail because foo exists, because it was left behind.
500
501    >>> remove('foo')
502
503Let's fix the recipe:
504
505    >>> write(sample_buildout, 'recipes', 'mkdir.py',
506    ... """
507    ... import logging, os, zc.buildout
508    ...
509    ... class Mkdir:
510    ...
511    ...     def __init__(self, buildout, name, options):
512    ...         self.name, self.options = name, options
513    ...
514    ...         # Normalize paths and check that their parent
515    ...         # directories exist:
516    ...         paths = []
517    ...         for path in options['path'].split():
518    ...             path = os.path.join(buildout['buildout']['directory'], path)
519    ...             if not os.path.isdir(os.path.dirname(path)):
520    ...                 logging.getLogger(self.name).error(
521    ...                     'Cannot create %s. %s is not a directory.',
522    ...                     options['path'], os.path.dirname(options['path']))
523    ...                 raise zc.buildout.UserError('Invalid Path')
524    ...             paths.append(path)
525    ...         options['path'] = ' '.join(paths)
526    ...
527    ...     def install(self):
528    ...         paths = self.options['path'].split()
529    ...         created = []
530    ...         try:
531    ...             for path in paths:
532    ...                 logging.getLogger(self.name).info(
533    ...                     'Creating directory %s', os.path.basename(path))
534    ...                 os.mkdir(path)
535    ...                 created.append(path)
536    ...         except:
537    ...             for d in created:
538    ...                 os.rmdir(d)
539    ...             raise
540    ...
541    ...         return paths
542    ...
543    ...     def update(self):
544    ...         pass
545    ... """)
546
547And put back the typo:
548
549    >>> write(sample_buildout, 'buildout.cfg',
550    ... """
551    ... [buildout]
552    ... develop = recipes
553    ... parts = data-dir
554    ...
555    ... [data-dir]
556    ... recipe = recipes:mkdir
557    ... path = foo bin
558    ... """)
559
560When we rerun the buildout:
561
562    >>> print system(buildout), # doctest: +ELLIPSIS
563    Develop: '/sample-buildout/recipes'
564    Installing data-dir.
565    data-dir: Creating directory foo
566    data-dir: Creating directory bin
567    While:
568      Installing data-dir.
569    <BLANKLINE>
570    An internal error occured due to a bug in either zc.buildout or in a
571    recipe being used:
572    Traceback (most recent call last):
573    ...
574    OSError: [Errno 17] File exists: '/sample-buildout/bin'
575
576.. Wait for the file to really disappear. My linux is weird.
577
578    >>> wait_until("foo goes away", lambda : not os.path.exists('foo'))
579
580we get the same error, but we don't get the directory left behind:
581
582    >>> os.path.exists('foo')
583    False
584
585It's critical that recipes clean up partial effects when errors
586occur.  Because recipes most commonly create files and directories,
587buildout provides a helper API for removing created files when an
588error occurs.  Option objects have a created method that can be called
589to record files as they are created.  If the install or update method
590returns with an error, then any registered paths are removed
591automatically.  The method returns the files registered and can be
592used to return the files created.  Let's use this API to simplify the
593recipe:
594
595    >>> write(sample_buildout, 'recipes', 'mkdir.py',
596    ... """
597    ... import logging, os, zc.buildout
598    ...
599    ... class Mkdir:
600    ...
601    ...     def __init__(self, buildout, name, options):
602    ...         self.name, self.options = name, options
603    ...
604    ...         # Normalize paths and check that their parent
605    ...         # directories exist:
606    ...         paths = []
607    ...         for path in options['path'].split():
608    ...             path = os.path.join(buildout['buildout']['directory'], path)
609    ...             if not os.path.isdir(os.path.dirname(path)):
610    ...                 logging.getLogger(self.name).error(
611    ...                     'Cannot create %s. %s is not a directory.',
612    ...                     options['path'], os.path.dirname(options['path']))
613    ...                 raise zc.buildout.UserError('Invalid Path')
614    ...             paths.append(path)
615    ...         options['path'] = ' '.join(paths)
616    ...
617    ...     def install(self):
618    ...         paths = self.options['path'].split()
619    ...         for path in paths:
620    ...             logging.getLogger(self.name).info(
621    ...                 'Creating directory %s', os.path.basename(path))
622    ...             os.mkdir(path)
623    ...             self.options.created(path)
624    ...
625    ...         return self.options.created()
626    ...
627    ...     def update(self):
628    ...         pass
629    ... """)
630
631..
632
633    >>> remove(sample_buildout, 'recipes', 'mkdir.pyc')
634
635We returned by calling created, taking advantage of the fact that it
636returns the registered paths.  We did this for illustrative purposes.
637It would be simpler just to return the paths as before.
638
639If we rerun the buildout, again, we'll get the error and no
640directories will be created:
641
642    >>> print system(buildout), # doctest: +ELLIPSIS
643    Develop: '/sample-buildout/recipes'
644    Installing data-dir.
645    data-dir: Creating directory foo
646    data-dir: Creating directory bin
647    While:
648      Installing data-dir.
649    <BLANKLINE>
650    An internal error occured due to a bug in either zc.buildout or in a
651    recipe being used:
652    Traceback (most recent call last):
653    ...
654    OSError: [Errno 17] File exists: '/sample-buildout/bin'
655
656    >>> os.path.exists('foo')
657    False
658
659Now, we'll fix the typo again and we'll get the directories we expect:
660
661    >>> write(sample_buildout, 'buildout.cfg',
662    ... """
663    ... [buildout]
664    ... develop = recipes
665    ... parts = data-dir
666    ...
667    ... [data-dir]
668    ... recipe = recipes:mkdir
669    ... path = foo bins
670    ... """)
671
672    >>> print system(buildout),
673    Develop: '/sample-buildout/recipes'
674    Installing data-dir.
675    data-dir: Creating directory foo
676    data-dir: Creating directory bins
677
678    >>> os.path.exists('foo')
679    True
680    >>> os.path.exists('bins')
681    True
682
683Configuration file syntax
684-------------------------
685
686As mentioned earlier, buildout configuration files use the format
687defined by the Python ConfigParser module with extensions.  The
688extensions are:
689
690- option names are case sensitive
691
692- option values can use a substitution syntax, described below, to
693  refer to option values in specific sections.
694
695- option values can be appended or removed using the - and +
696  operators.
697
698The ConfigParser syntax is very flexible.  Section names can contain
699any characters other than newlines and right square braces ("]").
700Option names can contain any characters other than newlines, colons,
701and equal signs, can not start with a space, and don't include
702trailing spaces.
703
704It is likely that, in the future, some characters will be given
705special buildout-defined meanings.  This is already true of the
706characters ":", "$", "%", "(", and ")".  For now, it is a good idea to
707keep section and option names simple, sticking to alphanumeric
708characters, hyphens, and periods.
709
710Variable substitutions
711----------------------
712
713Buildout configuration files support variable substitution.
714To illustrate this, we'll create an debug recipe to
715allow us to see interactions with the buildout:
716
717    >>> write(sample_buildout, 'recipes', 'debug.py',
718    ... """
719    ... class Debug:
720    ...
721    ...     def __init__(self, buildout, name, options):
722    ...         self.buildout = buildout
723    ...         self.name = name
724    ...         self.options = options
725    ...
726    ...     def install(self):
727    ...         items = self.options.items()
728    ...         items.sort()
729    ...         for option, value in items:
730    ...             print option, value
731    ...         return ()
732    ...
733    ...     update = install
734    ... """)
735
736This recipe doesn't actually create anything. The install method
737doesn't return anything, because it didn't create any files or
738directories.
739
740We also have to update our setup script:
741
742    >>> write(sample_buildout, 'recipes', 'setup.py',
743    ... """
744    ... from setuptools import setup
745    ... entry_points = (
746    ... '''
747    ... [zc.buildout]
748    ... mkdir = mkdir:Mkdir
749    ... debug = debug:Debug
750    ... ''')
751    ... setup(name="recipes", entry_points=entry_points)
752    ... """)
753
754We've rearranged the script a bit to make the entry points easier to
755edit.  In particular, entry points are now defined as a configuration
756string, rather than a dictionary.
757
758Let's update our configuration to provide variable substitution
759examples:
760
761    >>> write(sample_buildout, 'buildout.cfg',
762    ... """
763    ... [buildout]
764    ... develop = recipes
765    ... parts = data-dir debug
766    ... log-level = INFO
767    ...
768    ... [debug]
769    ... recipe = recipes:debug
770    ... File 1 = ${data-dir:path}/file
771    ... File 2 = ${debug:File 1}/log
772    ...
773    ... [data-dir]
774    ... recipe = recipes:mkdir
775    ... path = mydata
776    ... """)
777
778We used a string-template substitution for File 1 and File 2.  This
779type of substitution uses the string.Template syntax.  Names
780substituted are qualified option names, consisting of a section name
781and option name joined by a colon.
782
783Now, if we run the buildout, we'll see the options with the values
784substituted.
785
786    >>> print system(buildout),
787    Develop: '/sample-buildout/recipes'
788    Uninstalling data-dir.
789    Installing data-dir.
790    data-dir: Creating directory mydata
791    Installing debug.
792    File 1 /sample-buildout/mydata/file
793    File 2 /sample-buildout/mydata/file/log
794    recipe recipes:debug
795
796Note that the substitution of the data-dir path option reflects the
797update to the option performed by the mkdir recipe.
798
799It might seem surprising that mydata was created again.  This is
800because we changed our recipes package by adding the debug module.
801The buildout system didn't know if this module could effect the mkdir
802recipe, so it assumed it could and reinstalled mydata.  If we rerun
803the buildout:
804
805    >>> print system(buildout),
806    Develop: '/sample-buildout/recipes'
807    Updating data-dir.
808    Updating debug.
809    File 1 /sample-buildout/mydata/file
810    File 2 /sample-buildout/mydata/file/log
811    recipe recipes:debug
812
813We can see that mydata was not recreated.
814
815Note that, in this case, we didn't specify a log level, so
816we didn't get output about what the buildout was doing.
817
818Section and option names in variable substitutions are only allowed to
819contain alphanumeric characters, hyphens, periods and spaces. This
820restriction might be relaxed in future releases.
821
822
823Automatic part selection and ordering
824-------------------------------------
825
826When a section with a recipe is referred to, either through variable
827substitution or by an initializing recipe, the section is treated as a
828part and added to the part list before the referencing part.  For
829example, we can leave data-dir out of the parts list:
830
831    >>> write(sample_buildout, 'buildout.cfg',
832    ... """
833    ... [buildout]
834    ... develop = recipes
835    ... parts = debug
836    ... log-level = INFO
837    ...
838    ... [debug]
839    ... recipe = recipes:debug
840    ... File 1 = ${data-dir:path}/file
841    ... File 2 = ${debug:File 1}/log
842    ...
843    ... [data-dir]
844    ... recipe = recipes:mkdir
845    ... path = mydata
846    ... """)
847
848
849It will still be treated as a part:
850
851    >>> print system(buildout),
852    Develop: '/sample-buildout/recipes'
853    Updating data-dir.
854    Updating debug.
855    File 1 /sample-buildout/mydata/file
856    File 2 /sample-buildout/mydata/file/log
857    recipe recipes:debug
858
859    >>> cat('.installed.cfg') # doctest: +ELLIPSIS
860    [buildout]
861    installed_develop_eggs = /sample-buildout/develop-eggs/recipes.egg-link
862    parts = data-dir debug
863    ...
864
865Note that the data-dir part is included *before* the debug part,
866because the debug part refers to the data-dir part.  Even if we list
867the data-dir part after the debug part, it will be included before:
868
869    >>> write(sample_buildout, 'buildout.cfg',
870    ... """
871    ... [buildout]
872    ... develop = recipes
873    ... parts = debug data-dir
874    ... log-level = INFO
875    ...
876    ... [debug]
877    ... recipe = recipes:debug
878    ... File 1 = ${data-dir:path}/file
879    ... File 2 = ${debug:File 1}/log
880    ...
881    ... [data-dir]
882    ... recipe = recipes:mkdir
883    ... path = mydata
884    ... """)
885
886
887It will still be treated as a part:
888
889    >>> print system(buildout),
890    Develop: '/sample-buildout/recipes'
891    Updating data-dir.
892    Updating debug.
893    File 1 /sample-buildout/mydata/file
894    File 2 /sample-buildout/mydata/file/log
895    recipe recipes:debug
896
897    >>> cat('.installed.cfg') # doctest: +ELLIPSIS
898    [buildout]
899    installed_develop_eggs = /sample-buildout/develop-eggs/recipes.egg-link
900    parts = data-dir debug
901    ...
902
903
904Adding and removing options
905---------------------------
906
907We can append and remove values to an option by using the + and -
908operators.
909
910This is illustrated below; first we define a base configuration.
911
912    >>> write(sample_buildout, 'base.cfg',
913    ... """
914    ... [buildout]
915    ... parts = part1 part2 part3
916    ...
917    ... [part1]
918    ... recipe =
919    ... option = a1 a2
920    ...
921    ... [part2]
922    ... recipe =
923    ... option = b1 b2 b3 b4
924    ...
925    ... [part3]
926    ... recipe =
927    ... option = c1 c2
928    ...
929    ... """)
930
931Extending this configuration, we can "adjust" the values set in the
932base configuration file.
933
934    >>> write(sample_buildout, 'extension1.cfg',
935    ... """
936    ... [buildout]
937    ... extends = base.cfg
938    ...
939    ... # appending values
940    ... [part1]
941    ... option += a3 a4
942    ...
943    ... # removing values
944    ... [part2]
945    ... option -= b1 b2
946    ...
947    ... # alt. spelling
948    ... [part3]
949    ... option+=c3 c4 c5
950    ...
951    ... # normal assignment
952    ... [part4]
953    ... option = h1 h2
954    ...
955    ... """)
956
957An additional extension.
958
959    >>> write(sample_buildout, 'extension2.cfg',
960    ... """
961    ... [buildout]
962    ... extends = extension1.cfg
963    ...
964    ... # appending values
965    ... [part1]
966    ... option += a5
967    ...
968    ... # removing values
969    ... [part2]
970    ... option -= b1 b2 b3
971    ...
972    ... """)
973
974To verify that the options are adjusted correctly, we'll set up an
975extension that prints out the options.
976
977    >>> mkdir(sample_buildout, 'demo')
978    >>> write(sample_buildout, 'demo', 'demo.py',
979    ... """
980    ... def ext(buildout):
981    ...     print [part['option'] for name, part in buildout.items() \
982    ...           if name.startswith('part')]
983    ... """)
984
985    >>> write(sample_buildout, 'demo', 'setup.py',
986    ... """
987    ... from setuptools import setup
988    ...
989    ... setup(
990    ...     name="demo",
991    ...     entry_points={'zc.buildout.extension': ['ext = demo:ext']},
992    ...     )
993    ... """)
994
995Set up a buildout configuration for this extension.
996
997    >>> write(sample_buildout, 'buildout.cfg',
998    ... """
999    ... [buildout]
1000    ... develop = demo
1001    ... parts =
1002    ... """)
1003
1004    >>> os.chdir(sample_buildout)
1005    >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')),
1006    Develop: '/sample-buildout/demo'
1007    Uninstalling debug.
1008    Getting distribution for 'recipes'.
1009    zip_safe flag not set; analyzing archive contents...
1010    Got recipes 0.0.0.
1011    Uninstalling data-dir.
1012    warning: install_lib: 'build/lib' does not exist -- no Python modules to install
1013
1014Verify option values.
1015
1016    >>> write(sample_buildout, 'buildout.cfg',
1017    ... """
1018    ... [buildout]
1019    ... develop = demo
1020    ... extensions = demo
1021    ... extends = extension2.cfg
1022    ... """)
1023
1024    >>> print system(os.path.join('bin', 'buildout')),
1025    ['a1 a2/na3 a4/na5', 'b1 b2 b3 b4', 'c1 c2/nc3 c4 c5', 'h1 h2']
1026    Develop: '/sample-buildout/demo'
1027
1028Cleanup.
1029
1030    >>> os.remove(os.path.join(sample_buildout, 'base.cfg'))
1031    >>> os.remove(os.path.join(sample_buildout, 'extension1.cfg'))
1032    >>> os.remove(os.path.join(sample_buildout, 'extension2.cfg'))
1033
1034Multiple configuration files
1035----------------------------
1036
1037A configuration file can "extend" another configuration file.
1038Options are read from the other configuration file if they aren't
1039already defined by your configuration file.
1040
1041The configuration files your file extends can extend
1042other configuration files.  The same file may be
1043used more than once although, of course, cycles aren't allowed.
1044
1045To see how this works, we use an example:
1046
1047    >>> write(sample_buildout, 'buildout.cfg',
1048    ... """
1049    ... [buildout]
1050    ... extends = base.cfg
1051    ...
1052    ... [debug]
1053    ... op = buildout
1054    ... """)
1055
1056    >>> write(sample_buildout, 'base.cfg',
1057    ... """
1058    ... [buildout]
1059    ... develop = recipes
1060    ... parts = debug
1061    ...
1062    ... [debug]
1063    ... recipe = recipes:debug
1064    ... op = base
1065    ... """)
1066
1067    >>> print system(buildout),
1068    Develop: '/sample-buildout/recipes'
1069    Installing debug.
1070    op buildout
1071    recipe recipes:debug
1072
1073The example is pretty trivial, but the pattern it illustrates is
1074pretty common.  In a more practical example, the base buildout might
1075represent a product and the extending buildout might be a
1076customization.
1077
1078Here is a more elaborate example.
1079
1080    >>> other = tmpdir('other')
1081
1082    >>> write(sample_buildout, 'buildout.cfg',
1083    ... """
1084    ... [buildout]
1085    ... extends = b1.cfg b2.cfg %(b3)s
1086    ...
1087    ... [debug]
1088    ... op = buildout
1089    ... """ % dict(b3=os.path.join(other, 'b3.cfg')))
1090
1091    >>> write(sample_buildout, 'b1.cfg',
1092    ... """
1093    ... [buildout]
1094    ... extends = base.cfg
1095    ...
1096    ... [debug]
1097    ... op1 = b1 1
1098    ... op2 = b1 2
1099    ... """)
1100
1101    >>> write(sample_buildout, 'b2.cfg',
1102    ... """
1103    ... [buildout]
1104    ... extends = base.cfg
1105    ...
1106    ... [debug]
1107    ... op2 = b2 2
1108    ... op3 = b2 3
1109    ... """)
1110
1111    >>> write(other, 'b3.cfg',
1112    ... """
1113    ... [buildout]
1114    ... extends = b3base.cfg
1115    ...
1116    ... [debug]
1117    ... op4 = b3 4
1118    ... """)
1119
1120    >>> write(other, 'b3base.cfg',
1121    ... """
1122    ... [debug]
1123    ... op5 = b3base 5
1124    ... """)
1125
1126    >>> write(sample_buildout, 'base.cfg',
1127    ... """
1128    ... [buildout]
1129    ... develop = recipes
1130    ... parts = debug
1131    ...
1132    ... [debug]
1133    ... recipe = recipes:debug
1134    ... name = base
1135    ... """)
1136
1137    >>> print system(buildout),
1138    Develop: '/sample-buildout/recipes'
1139    Uninstalling debug.
1140    Installing debug.
1141    name base
1142    op buildout
1143    op1 b1 1
1144    op2 b2 2
1145    op3 b2 3
1146    op4 b3 4
1147    op5 b3base 5
1148    recipe recipes:debug
1149
1150There are several things to note about this example:
1151
1152- We can name multiple files in an extends option.
1153
1154- We can reference files recursively.
1155
1156- Relative file names in extended options are interpreted relative to
1157  the directory containing the referencing configuration file.
1158
1159Loading Configuration from URLs
1160-------------------------------
1161
1162Configuration files can be loaded from URLs.  To see how this works,
1163we'll set up a web server with some configuration files.
1164
1165    >>> server_data = tmpdir('server_data')
1166
1167    >>> write(server_data, "r1.cfg",
1168    ... """
1169    ... [debug]
1170    ... op1 = r1 1
1171    ... op2 = r1 2
1172    ... """)
1173
1174    >>> write(server_data, "r2.cfg",
1175    ... """
1176    ... [buildout]
1177    ... extends = r1.cfg
1178    ...
1179    ... [debug]
1180    ... op2 = r2 2
1181    ... op3 = r2 3
1182    ... """)
1183
1184    >>> server_url = start_server(server_data)
1185
1186    >>> write('client.cfg',
1187    ... """
1188    ... [buildout]
1189    ... develop = recipes
1190    ... parts = debug
1191    ... extends = %(url)s/r2.cfg
1192    ...
1193    ... [debug]
1194    ... recipe = recipes:debug
1195    ... name = base
1196    ... """ % dict(url=server_url))
1197
1198
1199    >>> print system(buildout+ ' -c client.cfg'),
1200    Develop: '/sample-buildout/recipes'
1201    Uninstalling debug.
1202    Installing debug.
1203    name base
1204    op1 r1 1
1205    op2 r2 2
1206    op3 r2 3
1207    recipe recipes:debug
1208
1209Here we specified a URL for the file we extended.  The file we
1210downloaded, itself referred to a file on the server using a relative
1211URL reference.  Relative references are interpreted relative to the
1212base URL when they appear in configuration files loaded via URL.
1213
1214We can also specify a URL as the configuration file to be used by a
1215buildout.
1216
1217    >>> os.remove('client.cfg')
1218    >>> write(server_data, 'remote.cfg',
1219    ... """
1220    ... [buildout]
1221    ... develop = recipes
1222    ... parts = debug
1223    ... extends = r2.cfg
1224    ...
1225    ... [debug]
1226    ... recipe = recipes:debug
1227    ... name = remote
1228    ... """)
1229
1230    >>> print system(buildout + ' -c ' + server_url + '/remote.cfg'),
1231    While:
1232      Initializing.
1233    Error: Missing option: buildout:directory
1234
1235Normally, the buildout directory defaults to directory
1236containing a configuration file.  This won't work for configuration
1237files loaded from URLs.  In this case, the buildout directory would
1238normally be defined on the command line:
1239
1240    >>> print system(buildout
1241    ...              + ' -c ' + server_url + '/remote.cfg'
1242    ...              + ' buildout:directory=' + sample_buildout
1243    ...              ),
1244    Develop: '/sample-buildout/recipes'
1245    Uninstalling debug.
1246    Installing debug.
1247    name remote
1248    op1 r1 1
1249    op2 r2 2
1250    op3 r2 3
1251    recipe recipes:debug
1252
1253User defaults
1254-------------
1255
1256If the file $HOME/.buildout/default.cfg, exists, it is read before
1257reading the configuration file.  ($HOME is the value of the HOME
1258environment variable. The '/' is replaced by the operating system file
1259delimiter.)
1260
1261    >>> old_home = os.environ['HOME']
1262    >>> home = tmpdir('home')
1263    >>> mkdir(home, '.buildout')
1264    >>> write(home, '.buildout', 'default.cfg',
1265    ... """
1266    ... [debug]
1267    ... op1 = 1
1268    ... op7 = 7
1269    ... """)
1270
1271    >>> os.environ['HOME'] = home
1272    >>> print system(buildout),
1273    Develop: '/sample-buildout/recipes'
1274    Uninstalling debug.
1275    Installing debug.
1276    name base
1277    op buildout
1278    op1 b1 1
1279    op2 b2 2
1280    op3 b2 3
1281    op4 b3 4
1282    op5 b3base 5
1283    op7 7
1284    recipe recipes:debug
1285
1286A buildout command-line argument, -U, can be used to suppress reading
1287user defaults:
1288
1289    >>> print system(buildout + ' -U'),
1290    Develop: '/sample-buildout/recipes'
1291    Uninstalling debug.
1292    Installing debug.
1293    name base
1294    op buildout
1295    op1 b1 1
1296    op2 b2 2
1297    op3 b2 3
1298    op4 b3 4
1299    op5 b3base 5
1300    recipe recipes:debug
1301
1302    >>> os.environ['HOME'] = old_home
1303
1304Log level
1305---------
1306
1307We can control the level of logging by specifying a log level in out
1308configuration file.  For example, so suppress info messages, we can
1309set the logging level to WARNING
1310
1311    >>> write(sample_buildout, 'buildout.cfg',
1312    ... """
1313    ... [buildout]
1314    ... log-level = WARNING
1315    ... extends = b1.cfg b2.cfg
1316    ... """)
1317
1318    >>> print system(buildout),
1319    name base
1320    op1 b1 1
1321    op2 b2 2
1322    op3 b2 3
1323    recipe recipes:debug
1324
1325Uninstall recipes
1326-----------------
1327
1328As we've seen, when parts are installed, buildout keeps track of files
1329and directories that they create. When the parts are uninstalled these
1330files and directories are deleted.
1331
1332Sometimes more clean up is needed. For example, a recipe might add a
1333system service by calling chkconfig --add during installation. Later
1334during uninstallation, chkconfig --del will need to be called to
1335remove the system service.
1336
1337In order to deal with these uninstallation issues, you can register
1338uninstall recipes. Uninstall recipes are registered using the
1339'zc.buildout.uninstall' entry point. Parts specify uninstall recipes
1340using the 'uninstall' option.
1341
1342In comparison to regular recipes, uninstall recipes are much
1343simpler. They are simply callable objects that accept the name of the
1344part to be uninstalled and the part's options dictionary. Uninstall
1345recipes don't have access to the part itself since it maybe not be
1346able to be instantiated at uninstallation time.
1347
1348Here's a recipe that simulates installation of a system service, along
1349with an uninstall recipe that simulates removing the service.
1350
1351    >>> write(sample_buildout, 'recipes', 'service.py',
1352    ... """
1353    ... class Service:
1354    ...
1355    ...     def __init__(self, buildout, name, options):
1356    ...         self.buildout = buildout
1357    ...         self.name = name
1358    ...         self.options = options
1359    ...
1360    ...     def install(self):
1361    ...         print "chkconfig --add %s" % self.options['script']
1362    ...         return ()
1363    ...
1364    ...     def update(self):
1365    ...         pass
1366    ...
1367    ...
1368    ... def uninstall_service(name, options):
1369    ...     print "chkconfig --del %s" % options['script']
1370    ... """)
1371
1372To use these recipes we must register them using entry points. Make
1373sure to use the same name for the recipe and uninstall recipe. This is
1374required to let buildout know which uninstall recipe goes with which
1375recipe.
1376
1377    >>> write(sample_buildout, 'recipes', 'setup.py',
1378    ... """
1379    ... from setuptools import setup
1380    ... entry_points = (
1381    ... '''
1382    ... [zc.buildout]
1383    ... mkdir = mkdir:Mkdir
1384    ... debug = debug:Debug
1385    ... service = service:Service
1386    ...
1387    ... [zc.buildout.uninstall]
1388    ... service = service:uninstall_service
1389    ... ''')
1390    ... setup(name="recipes", entry_points=entry_points)
1391    ... """)
1392
1393Here's how these recipes could be used in a buildout:
1394
1395    >>> write(sample_buildout, 'buildout.cfg',
1396    ... """
1397    ... [buildout]
1398    ... develop = recipes
1399    ... parts = service
1400    ...
1401    ... [service]
1402    ... recipe = recipes:service
1403    ... script = /path/to/script
1404    ... """)
1405
1406When the buildout is run the service will be installed
1407
1408    >>> print system(buildout)
1409    Develop: '/sample-buildout/recipes'
1410    Uninstalling debug.
1411    Installing service.
1412    chkconfig --add /path/to/script
1413    <BLANKLINE>
1414
1415The service has been installed. If the buildout is run again with no
1416changes, the service shouldn't be changed.
1417
1418    >>> print system(buildout)
1419    Develop: '/sample-buildout/recipes'
1420    Updating service.
1421    <BLANKLINE>
1422
1423Now we change the service part to trigger uninstallation and
1424re-installation.
1425
1426    >>> write(sample_buildout, 'buildout.cfg',
1427    ... """
1428    ... [buildout]
1429    ... develop = recipes
1430    ... parts = service
1431    ...
1432    ... [service]
1433    ... recipe = recipes:service
1434    ... script = /path/to/a/different/script
1435    ... """)
1436
1437    >>> print system(buildout)
1438    Develop: '/sample-buildout/recipes'
1439    Uninstalling service.
1440    Running uninstall recipe.
1441    chkconfig --del /path/to/script
1442    Installing service.
1443    chkconfig --add /path/to/a/different/script
1444    <BLANKLINE>
1445
1446Now we remove the service part, and add another part.
1447
1448    >>> write(sample_buildout, 'buildout.cfg',
1449    ... """
1450    ... [buildout]
1451    ... develop = recipes
1452    ... parts = debug
1453    ...
1454    ... [debug]
1455    ... recipe = recipes:debug
1456    ... """)
1457
1458    >>> print system(buildout)
1459    Develop: '/sample-buildout/recipes'
1460    Uninstalling service.
1461    Running uninstall recipe.
1462    chkconfig --del /path/to/a/different/script
1463    Installing debug.
1464    recipe recipes:debug
1465    <BLANKLINE>
1466
1467Uninstall recipes don't have to take care of removing all the files
1468and directories created by the part. This is still done automatically,
1469following the execution of the uninstall recipe. An upshot is that an
1470uninstallation recipe can access files and directories created by a
1471recipe before they are deleted.
1472
1473For example, here's an uninstallation recipe that simulates backing up
1474a directory before it is deleted. It is designed to work with the
1475mkdir recipe introduced earlier.
1476
1477    >>> write(sample_buildout, 'recipes', 'backup.py',
1478    ... """
1479    ... import os
1480    ... def backup_directory(name, options):
1481    ...     path = options['path']
1482    ...     size = len(os.listdir(path))
1483    ...     print "backing up directory %s of size %s" % (path, size)
1484    ... """)
1485
1486It must be registered with the zc.buildout.uninstall entry
1487point. Notice how it is given the name 'mkdir' to associate it with
1488the mkdir recipe.
1489
1490    >>> write(sample_buildout, 'recipes', 'setup.py',
1491    ... """
1492    ... from setuptools import setup
1493    ... entry_points = (
1494    ... '''
1495    ... [zc.buildout]
1496    ... mkdir = mkdir:Mkdir
1497    ... debug = debug:Debug
1498    ... service = service:Service
1499    ...
1500    ... [zc.buildout.uninstall]
1501    ... uninstall_service = service:uninstall_service
1502    ... mkdir = backup:backup_directory
1503    ... ''')
1504    ... setup(name="recipes", entry_points=entry_points)
1505    ... """)
1506
1507Now we can use it with a mkdir part.
1508
1509    >>> write(sample_buildout, 'buildout.cfg',
1510    ... """
1511    ... [buildout]
1512    ... develop = recipes
1513    ... parts = dir debug
1514    ...
1515    ... [dir]
1516    ... recipe = recipes:mkdir
1517    ... path = my_directory
1518    ...
1519    ... [debug]
1520    ... recipe = recipes:debug
1521    ... """)
1522
1523Run the buildout to install the part.
1524
1525    >>> print system(buildout)
1526    Develop: '/sample-buildout/recipes'
1527    Uninstalling debug.
1528    Installing dir.
1529    dir: Creating directory my_directory
1530    Installing debug.
1531    recipe recipes:debug
1532    <BLANKLINE>
1533
1534Now we remove the part from the configuration file.
1535
1536    >>> write(sample_buildout, 'buildout.cfg',
1537    ... """
1538    ... [buildout]
1539    ... develop = recipes
1540    ... parts = debug
1541    ...
1542    ... [debug]
1543    ... recipe = recipes:debug
1544    ... """)
1545
1546When the buildout is run the part is removed, and the uninstall recipe
1547is run before the directory is deleted.
1548
1549    >>> print system(buildout)
1550    Develop: '/sample-buildout/recipes'
1551    Uninstalling dir.
1552    Running uninstall recipe.
1553    backing up directory /sample-buildout/my_directory of size 0
1554    Updating debug.
1555    recipe recipes:debug
1556    <BLANKLINE>
1557
1558Now we will return the registration to normal for the benefit of the
1559rest of the examples.
1560
1561    >>> write(sample_buildout, 'recipes', 'setup.py',
1562    ... """
1563    ... from setuptools import setup
1564    ... entry_points = (
1565    ... '''
1566    ... [zc.buildout]
1567    ... mkdir = mkdir:Mkdir
1568    ... debug = debug:Debug
1569    ... ''')
1570    ... setup(name="recipes", entry_points=entry_points)
1571    ... """)
1572
1573
1574Command-line usage
1575------------------
1576
1577A number of arguments can be given on the buildout command line.  The
1578command usage is::
1579
1580  buildout [options and assignments] [command [command arguments]]
1581
1582The following options are supported:
1583
1584-h (or --help)
1585    Print basic usage information.  If this option is used, then all
1586    other options are ignored.
1587
1588-c filename
1589    The -c option can be used to specify a configuration file, rather than
1590    buildout.cfg in the current directory.
1591
1592
1593-t socket_timeout
1594
1595   Specify the socket timeout in seconds.
1596
1597-v
1598    Increment the verbosity by 10.  The verbosity is used to adjust
1599    the logging level.  The verbosity is subtracted from the numeric
1600    value of the log-level option specified in the configuration file.
1601
1602-q
1603    Decrement the verbosity by 10.
1604
1605-U
1606    Don't read user-default configuration.
1607
1608-o
1609    Run in off-line mode.  This is equivalent to the assignment
1610    buildout:offline=true.
1611
1612-O
1613    Run in non-off-line mode.  This is equivalent to the assignment
1614    buildout:offline=false.  This is the default buildout mode.  The
1615    -O option would normally be used to override a true offline
1616    setting in a configuration file.
1617
1618-n
1619    Run in newest mode.  This is equivalent to the assignment
1620    buildout:newest=true.  With this setting, which is the default,
1621    buildout will try to find the newest versions of distributions
1622    available that satisfy its requirements.
1623
1624-N
1625    Run in non-newest mode.  This is equivalent to the assignment
1626    buildout:newest=false.  With this setting, buildout will not seek
1627    new distributions if installed distributions satisfy it's
1628    requirements.
1629
1630Assignments are of the form::
1631
1632  section_name:option_name=value
1633
1634Options and assignments can be given in any order.
1635
1636Here's an example:
1637
1638    >>> write(sample_buildout, 'other.cfg',
1639    ... """
1640    ... [buildout]
1641    ... develop = recipes
1642    ... parts = debug
1643    ... installed = .other.cfg
1644    ... log-level = WARNING
1645    ...
1646    ... [debug]
1647    ... name = other
1648    ... recipe = recipes:debug
1649    ... """)
1650
1651Note that we used the installed buildout option to specify an
1652alternate file to store information about installed parts.
1653
1654    >>> print system(buildout+' -c other.cfg debug:op1=foo -v'),
1655    Develop: '/sample-buildout/recipes'
1656    Installing debug.
1657    name other
1658    op1 foo
1659    recipe recipes:debug
1660
1661Here we used the -c option to specify an alternate configuration file,
1662and the -v option to increase the level of logging from the default,
1663WARNING.
1664
1665Options can also be combined in the usual Unix way, as in:
1666
1667    >>> print system(buildout+' -vcother.cfg debug:op1=foo'),
1668    Develop: '/sample-buildout/recipes'
1669    Updating debug.
1670    name other
1671    op1 foo
1672    recipe recipes:debug
1673
1674Here we combined the -v and -c options with the configuration file
1675name.  Note that the -c option has to be last, because it takes an
1676argument.
1677
1678    >>> os.remove(os.path.join(sample_buildout, 'other.cfg'))
1679    >>> os.remove(os.path.join(sample_buildout, '.other.cfg'))
1680
1681The most commonly used command is 'install' and it takes a list of
1682parts to install. if any parts are specified, only those parts are
1683installed.  To illustrate this, we'll update our configuration and run
1684the buildout in the usual way:
1685
1686    >>> write(sample_buildout, 'buildout.cfg',
1687    ... """
1688    ... [buildout]
1689    ... develop = recipes
1690    ... parts = debug d1 d2 d3
1691    ...
1692    ... [d1]
1693    ... recipe = recipes:mkdir
1694    ... path = d1
1695    ...
1696    ... [d2]
1697    ... recipe = recipes:mkdir
1698    ... path = d2
1699    ...
1700    ... [d3]
1701    ... recipe = recipes:mkdir
1702    ... path = d3
1703    ...
1704    ... [debug]
1705    ... recipe = recipes:debug
1706    ... """)
1707
1708    >>> print system(buildout),
1709    Develop: '/sample-buildout/recipes'
1710    Uninstalling debug.
1711    Installing debug.
1712    recipe recipes:debug
1713    Installing d1.
1714    d1: Creating directory d1
1715    Installing d2.
1716    d2: Creating directory d2
1717    Installing d3.
1718    d3: Creating directory d3
1719
1720    >>> ls(sample_buildout)
1721    -  .installed.cfg
1722    -  b1.cfg
1723    -  b2.cfg
1724    -  base.cfg
1725    d  bin
1726    -  buildout.cfg
1727    d  d1
1728    d  d2
1729    d  d3
1730    d  demo
1731    d  develop-eggs
1732    d  eggs
1733    d  parts
1734    d  recipes
1735
1736    >>> cat(sample_buildout, '.installed.cfg')
1737    [buildout]
1738    installed_develop_eggs = /sample-buildout/develop-eggs/recipes.egg-link
1739    parts = debug d1 d2 d3
1740    <BLANKLINE>
1741    [debug]
1742    __buildout_installed__ =
1743    __buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
1744    recipe = recipes:debug
1745    <BLANKLINE>
1746    [d1]
1747    __buildout_installed__ = /sample-buildout/d1
1748    __buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
1749    path = /sample-buildout/d1
1750    recipe = recipes:mkdir
1751    <BLANKLINE>
1752    [d2]
1753    __buildout_installed__ = /sample-buildout/d2
1754    __buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
1755    path = /sample-buildout/d2
1756    recipe = recipes:mkdir
1757    <BLANKLINE>
1758    [d3]
1759    __buildout_installed__ = /sample-buildout/d3
1760    __buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
1761    path = /sample-buildout/d3
1762    recipe = recipes:mkdir
1763
1764Now we'll update our configuration file:
1765
1766    >>> write(sample_buildout, 'buildout.cfg',
1767    ... """
1768    ... [buildout]
1769    ... develop = recipes
1770    ... parts = debug d2 d3 d4
1771    ...
1772    ... [d2]
1773    ... recipe = recipes:mkdir
1774    ... path = data2
1775    ...
1776    ... [d3]
1777    ... recipe = recipes:mkdir
1778    ... path = data3
1779    ...
1780    ... [d4]
1781    ... recipe = recipes:mkdir
1782    ... path = ${d2:path}-extra
1783    ...
1784    ... [debug]
1785    ... recipe = recipes:debug
1786    ... x = 1
1787    ... """)
1788
1789and run the buildout specifying just d3 and d4:
1790
1791    >>> print system(buildout+' install d3 d4'),
1792    Develop: '/sample-buildout/recipes'
1793    Uninstalling d3.
1794    Installing d3.
1795    d3: Creating directory data3
1796    Installing d4.
1797    d4: Creating directory data2-extra
1798
1799    >>> ls(sample_buildout)
1800    -  .installed.cfg
1801    -  b1.cfg
1802    -  b2.cfg
1803    -  base.cfg
1804    d  bin
1805    -  buildout.cfg
1806    d  d1
1807    d  d2
1808    d  data2-extra
1809    d  data3
1810    d  demo
1811    d  develop-eggs
1812    d  eggs
1813    d  parts
1814    d  recipes
1815
1816Only the d3 and d4 recipes ran.  d3 was removed and data3 and data2-extra
1817were created.
1818
1819The .installed.cfg is only updated for the recipes that ran:
1820
1821    >>> cat(sample_buildout, '.installed.cfg')
1822    [buildout]
1823    installed_develop_eggs = /sample-buildout/develop-eggs/recipes.egg-link
1824    parts = debug d1 d2 d3 d4
1825    <BLANKLINE>
1826    [debug]
1827    __buildout_installed__ =
1828    __buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
1829    recipe = recipes:debug
1830    <BLANKLINE>
1831    [d1]
1832    __buildout_installed__ = /sample-buildout/d1
1833    __buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
1834    path = /sample-buildout/d1
1835    recipe = recipes:mkdir
1836    <BLANKLINE>
1837    [d2]
1838    __buildout_installed__ = /sample-buildout/d2
1839    __buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
1840    path = /sample-buildout/d2
1841    recipe = recipes:mkdir
1842    <BLANKLINE>
1843    [d3]
1844    __buildout_installed__ = /sample-buildout/data3
1845    __buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
1846    path = /sample-buildout/data3
1847    recipe = recipes:mkdir
1848    <BLANKLINE>
1849    [d4]
1850    __buildout_installed__ = /sample-buildout/data2-extra
1851    __buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
1852    path = /sample-buildout/data2-extra
1853    recipe = recipes:mkdir
1854
1855Note that the installed data for debug, d1, and d2 haven't changed,
1856because we didn't install those parts and that the d1 and d2
1857directories are still there.
1858
1859Now, if we run the buildout without the install command:
1860
1861    >>> print system(buildout),
1862    Develop: '/sample-buildout/recipes'
1863    Uninstalling d2.
1864    Uninstalling d1.
1865    Uninstalling debug.
1866    Installing debug.
1867    recipe recipes:debug
1868    x 1
1869    Installing d2.
1870    d2: Creating directory data2
1871    Updating d3.
1872    Updating d4.
1873
1874We see the output of the debug recipe and that data2 was created.  We
1875also see that d1 and d2 have gone away:
1876
1877    >>> ls(sample_buildout)
1878    -  .installed.cfg
1879    -  b1.cfg
1880    -  b2.cfg
1881    -  base.cfg
1882    d  bin
1883    -  buildout.cfg
1884    d  data2
1885    d  data2-extra
1886    d  data3
1887    d  demo
1888    d  develop-eggs
1889    d  eggs
1890    d  parts
1891    d  recipes
1892
1893Alternate directory and file locations
1894--------------------------------------
1895
1896The buildout normally puts the bin, eggs, and parts directories in the
1897directory in the directory containing the configuration file. You can
1898provide alternate locations, and even names for these directories.
1899
1900    >>> alt = tmpdir('sample-alt')
1901
1902    >>> write(sample_buildout, 'buildout.cfg',
1903    ... """
1904    ... [buildout]
1905    ... develop = recipes
1906    ... parts =
1907    ... develop-eggs-directory = %(developbasket)s
1908    ... eggs-directory = %(basket)s
1909    ... bin-directory = %(scripts)s
1910    ... parts-directory = %(work)s
1911    ... """ % dict(
1912    ...    developbasket = os.path.join(alt, 'developbasket'),
1913    ...    basket = os.path.join(alt, 'basket'),
1914    ...    scripts = os.path.join(alt, 'scripts'),
1915    ...    work = os.path.join(alt, 'work'),
1916    ... ))
1917
1918    >>> print system(buildout),
1919    Creating directory '/sample-alt/scripts'.
1920    Creating directory '/sample-alt/work'.
1921    Creating directory '/sample-alt/basket'.
1922    Creating directory '/sample-alt/developbasket'.
1923    Develop: '/sample-buildout/recipes'
1924    Uninstalling d4.
1925    Uninstalling d3.
1926    Uninstalling d2.
1927    Uninstalling debug.
1928
1929    >>> ls(alt)
1930    d  basket
1931    d  developbasket
1932    d  scripts
1933    d  work
1934
1935    >>> ls(alt, 'developbasket')
1936    -  recipes.egg-link
1937
1938You can also specify an alternate buildout directory:
1939
1940    >>> rmdir(alt)
1941    >>> alt = tmpdir('sample-alt')
1942
1943    >>> write(sample_buildout, 'buildout.cfg',
1944    ... """
1945    ... [buildout]
1946    ... directory = %(alt)s
1947    ... develop = %(recipes)s
1948    ... parts =
1949    ... """ % dict(
1950    ...    alt=alt,
1951    ...    recipes=os.path.join(sample_buildout, 'recipes'),
1952    ...    ))
1953
1954    >>> print system(buildout),
1955    Creating directory '/sample-alt/bin'.
1956    Creating directory '/sample-alt/parts'.
1957    Creating directory '/sample-alt/eggs'.
1958    Creating directory '/sample-alt/develop-eggs'.
1959    Develop: '/sample-buildout/recipes'
1960
1961    >>> ls(alt)
1962    -  .installed.cfg
1963    d  bin
1964    d  develop-eggs
1965    d  eggs
1966    d  parts
1967
1968    >>> ls(alt, 'develop-eggs')
1969    -  recipes.egg-link
1970
1971Logging control
1972---------------
1973
1974Three buildout options are used to control logging:
1975
1976log-level
1977   specifies the log level
1978
1979verbosity
1980   adjusts the log level
1981
1982log-format
1983   allows an alternate logging for mat to be specified
1984
1985We've already seen the log level and verbosity.  Let's look at an example
1986of changing the format:
1987
1988    >>> write(sample_buildout, 'buildout.cfg',
1989    ... """
1990    ... [buildout]
1991    ... develop = recipes
1992    ... parts =
1993    ... log-level = 25
1994    ... verbosity = 5
1995    ... log-format = %(levelname)s %(message)s
1996    ... """)
1997
1998Here, we've changed the format to include the log-level name, rather
1999than the logger name.
2000
2001We've also illustrated, with a contrived example, that the log level
2002can be a numeric value and that the verbosity can be specified in the
2003configuration file.  Because the verbosity is subtracted from the log
2004level, we get a final log level of 20, which is the INFO level.
2005
2006    >>> print system(buildout),
2007    INFO Develop: '/sample-buildout/recipes'
2008
2009Predefined buildout options
2010---------------------------
2011
2012Buildouts have a number of predefined options that recipes can use
2013and that users can override in their configuration files.  To see
2014these, we'll run a minimal buildout configuration with a debug logging
2015level.  One of the features of debug logging is that the configuration
2016database is shown.
2017
2018    >>> write(sample_buildout, 'buildout.cfg',
2019    ... """
2020    ... [buildout]
2021    ... parts =
2022    ... """)
2023
2024    >>> print system(buildout+' -vv'),
2025    Installing 'zc.buildout', 'setuptools'.
2026    We have a develop egg: zc.buildout 1.0.0.
2027    We have the best distribution that satisfies 'setuptools'.
2028    Picked: setuptools = 0.6
2029    <BLANKLINE>
2030    Configuration data:
2031    [buildout]
2032    bin-directory = /sample-buildout/bin
2033    develop-eggs-directory = /sample-buildout/develop-eggs
2034    directory = /sample-buildout
2035    eggs-directory = /sample-buildout/eggs
2036    executable = /usr/local/bin/python2.3
2037    installed = /sample-buildout/.installed.cfg
2038    log-format =
2039    log-level = INFO
2040    newest = true
2041    offline = false
2042    parts =
2043    parts-directory = /sample-buildout/parts
2044    python = buildout
2045    verbosity = 20
2046    <BLANKLINE>
2047
2048All of these options can be overridden by configuration files or by
2049command-line assignments.  We've discussed most of these options
2050already, but let's review them and touch on some we haven't discussed:
2051
2052bin-directory
2053   The directory path where scripts are written.  This can be a
2054   relative path, which is interpreted relative to the directory
2055   option.
2056
2057develop-eggs-directory
2058   The directory path where development egg links are created for software
2059   being created in the local project.  This can be a relative path,
2060   which is interpreted relative to the directory option.
2061
2062directory
2063   The buildout directory.  This is the base for other buildout file
2064   and directory locations, when relative locations are used.
2065
2066eggs-directory
2067   The directory path where downloaded eggs are put.  It is common to share
2068   this directory across buildouts. Eggs in this directory should
2069   *never* be modified.  This can be a relative path, which is
2070   interpreted relative to the directory option.
2071
2072executable
2073   The Python executable used to run the buildout.  See the python
2074   option below.
2075
2076installed
2077   The file path where information about the results of the previous
2078   buildout run is written.  This can be a relative path, which is
2079   interpreted relative to the directory option.  This file provides
2080   an inventory of installed parts with information needed to decide
2081   which if any parts need to be uninstalled.
2082
2083log-format
2084   The format used for logging messages.
2085
2086log-level
2087   The log level before verbosity adjustment
2088
2089parts
2090   A white space separated list of parts to be installed.
2091
2092parts-directory
2093   A working directory that parts can used to store data.
2094
2095python
2096   The name of a section containing information about the default
2097   Python interpreter.  Recipes that need a installation
2098   typically have options to tell them which Python installation to
2099   use.  By convention, if a section-specific option isn't used, the
2100   option is looked for in the buildout section.  The option must
2101   point to a section with an executable option giving the path to a
2102   Python executable.  By default, the buildout section defines the
2103   default Python as the Python used to run the buildout.
2104
2105verbosity
2106   A log-level adjustment.  Typically, this is set via the -q and -v
2107   command-line options.
2108
2109
2110Creating new buildouts and bootstrapping
2111----------------------------------------
2112
2113If zc.buildout is installed, you can use it to create a new buildout
2114with it's own local copies of zc.buildout and setuptools and with
2115local buildout scripts.
2116
2117    >>> sample_bootstrapped = tmpdir('sample-bootstrapped')
2118
2119    >>> print system(buildout
2120    ...              +' -c'+os.path.join(sample_bootstrapped, 'setup.cfg')
2121    ...              +' init'),
2122    Creating '/sample-bootstrapped/setup.cfg'.
2123    Creating directory '/sample-bootstrapped/bin'.
2124    Creating directory '/sample-bootstrapped/parts'.
2125    Creating directory '/sample-bootstrapped/eggs'.
2126    Creating directory '/sample-bootstrapped/develop-eggs'.
2127    Generated script '/sample-bootstrapped/bin/buildout'.
2128
2129Note that a basic setup.cfg was created for us.
2130
2131    >>> ls(sample_bootstrapped)
2132    d  bin
2133    d  develop-eggs
2134    d  eggs
2135    d  parts
2136    -  setup.cfg
2137
2138    >>> ls(sample_bootstrapped, 'bin')
2139    -  buildout
2140
2141    >>> _ = (ls(sample_bootstrapped, 'eggs'),
2142    ...      ls(sample_bootstrapped, 'develop-eggs'))
2143    -  setuptools-0.6-py2.3.egg
2144    -  zc.buildout-1.0-py2.3.egg
2145
2146(We list both the eggs and develop-eggs directories because the
2147buildout or setuptools egg could be installed in the develop-eggs
2148directory if the original buildout had develop eggs for either
2149buildout or setuptools.)
2150
2151Note that the buildout script was installed but not run.  To run
2152the buildout, we'd have to run the installed buildout script.
2153
2154If we have an existing buildout that already has a buildout.cfg, we'll
2155normally use the bootstrap command instead of init.  It will complain
2156if there isn't a configuration file:
2157
2158     >>> sample_bootstrapped2 = tmpdir('sample-bootstrapped2')
2159
2160     >>> print system(buildout
2161     ...              +' -c'+os.path.join(sample_bootstrapped2, 'setup.cfg')
2162     ...              +' bootstrap'),
2163     While:
2164       Initializing.
2165     Error: Couldn't open /sample-bootstrapped2/setup.cfg
2166
2167     >>> write(sample_bootstrapped2, 'setup.cfg',
2168     ... """
2169     ... [buildout]
2170     ... parts =
2171     ... """)
2172
2173    >>> print system(buildout
2174    ...              +' -c'+os.path.join(sample_bootstrapped2, 'setup.cfg')
2175    ...              +' bootstrap'),
2176    Creating directory '/sample-bootstrapped2/bin'.
2177    Creating directory '/sample-bootstrapped2/parts'.
2178    Creating directory '/sample-bootstrapped2/eggs'.
2179    Creating directory '/sample-bootstrapped2/develop-eggs'.
2180    Generated script '/sample-bootstrapped2/bin/buildout'.
2181
2182
2183Newest and Offline Modes
2184------------------------
2185
2186By default buildout and recipes will try to find the newest versions
2187of distributions needed to satisfy requirements.  This can be very
2188time consuming, especially when incrementally working on setting up a
2189buildout or working on a recipe.  The buildout newest option can be
2190used to to suppress this.  If the newest option is set to false, then
2191new distributions won't be sought if an installed distribution meets
2192requirements.  The newest option can be set to false using the -N
2193command-line option.
2194
2195The offline option goes a bit further.  If the buildout offline option
2196is given a value of "true", the buildout and recipes that are aware of
2197the option will avoid doing network access.  This is handy when
2198running the buildout when not connected to the internet.  It also
2199makes buildouts run much faster. This option is typically set using
2200the buildout -o option.
2201
2202Preferring Final Releases
2203-------------------------
2204
2205Currently, when searching for new releases, the newest available
2206release is used.  This isn't usually ideal, as you may get a
2207development release or alpha releases not ready to be widely used.
2208You can request that final releases be preferred using the prefer
2209final option in the buildout section::
2210
2211  [buildout]
2212  ...
2213  prefer-final = true
2214
2215When the prefer-final option is set to true, then when searching for
2216new releases, final releases are preferred.  If there are final
2217releases that satisfy distribution requirements, then those releases
2218are used even if newer non-final releases are available.  The buildout
2219prefer-final option can be used to override this behavior.
2220
2221In buildout version 2, final releases will be preferred by default.
2222You will then need to use a false value for prefer-final to get the
2223newest releases.
2224
2225Finding distributions
2226---------------------
2227
2228By default, buildout searches the Python Package Index when looking
2229for distributions. You can, instead, specify your own index to search
2230using the `index` option::
2231
2232  [buildout]
2233  ...
2234  index = http://index.example.com/
2235
2236This index, or the default of http://pypi.python.org/simple/ if no
2237index is specified, will always be searched for distributions unless
2238running buildout with options that prevent searching for
2239distributions. The latest version of the distribution that meets the
2240requirements of the buildout will always be used.
2241
2242You can also specify more locations to search for distributions using
2243the `find-links` option. All locations specified will be searched for
2244distributions along with the package index as described before.
2245
2246Locations can be urls::
2247
2248  [buildout]
2249  ...
2250  find-links = http://download.zope.org/distribution/
2251
2252They can also be directories on disk::
2253
2254  [buildout]
2255  ...
2256  find-links = /some/path
2257
2258Finally, they can also be direct paths to distributions::
2259
2260  [buildout]
2261  ...
2262  find-links = /some/path/someegg-1.0.0-py2.3.egg
2263
2264Any number of locations can be specified in the `find-links` option::
2265
2266  [buildout]
2267  ...
2268  find-links =
2269      http://download.zope.org/distribution/
2270      /some/otherpath
2271      /some/path/someegg-1.0.0-py2.3.egg
2272
2273Dependency links
2274----------------
2275
2276By default buildout will obey the setuptools dependency_links metadata
2277when it looks for dependencies. This behavior can be controlled with
2278the use-dependency-links buildout option::
2279
2280  [buildout]
2281  ...
2282  use-dependency-links = false
2283
2284The option defaults to true. If you set it to false, then dependency
2285links are only looked for in the locations specified by find-links.
2286
2287Controlling the installation database
2288-------------------------------------
2289
2290The buildout installed option is used to specify the file used to save
2291information on installed parts.  This option is initialized to
2292".installed.cfg", but it can be overridden in the configuration file
2293or on the command line:
2294
2295    >>> write('buildout.cfg',
2296    ... """
2297    ... [buildout]
2298    ... develop = recipes
2299    ... parts = debug
2300    ...
2301    ... [debug]
2302    ... recipe = recipes:debug
2303    ... """)
2304
2305    >>> print system(buildout+' buildout:installed=inst.cfg'),
2306    Develop: '/sample-buildout/recipes'
2307    Installing debug.
2308    recipe recipes:debug
2309
2310    >>> ls(sample_buildout)
2311    -  b1.cfg
2312    -  b2.cfg
2313    -  base.cfg
2314    d  bin
2315    -  buildout.cfg
2316    d  demo
2317    d  develop-eggs
2318    d  eggs
2319    -  inst.cfg
2320    d  parts
2321    d  recipes
2322
2323The installation database can be disabled by supplying an empty
2324buildout installed option:
2325
2326    >>> os.remove('inst.cfg')
2327    >>> print system(buildout+' buildout:installed='),
2328    Develop: '/sample-buildout/recipes'
2329    Installing debug.
2330    recipe recipes:debug
2331
2332    >>> ls(sample_buildout)
2333    -  b1.cfg
2334    -  b2.cfg
2335    -  base.cfg
2336    d  bin
2337    -  buildout.cfg
2338    d  demo
2339    d  develop-eggs
2340    d  eggs
2341    d  parts
2342    d  recipes
2343
2344
2345Note that there will be no installation database if there are no
2346parts:
2347
2348    >>> write('buildout.cfg',
2349    ... """
2350    ... [buildout]
2351    ... parts =
2352    ... """)
2353
2354    >>> print system(buildout+' buildout:installed=inst.cfg'),
2355
2356    >>> ls(sample_buildout)
2357    -  b1.cfg
2358    -  b2.cfg
2359    -  base.cfg
2360    d  bin
2361    -  buildout.cfg
2362    d  demo
2363    d  develop-eggs
2364    d  eggs
2365    d  parts
2366    d  recipes
2367
2368Extensions
2369----------
2370
2371An **experimental** feature allows code to be loaded and run after
2372configuration files have been read but before the buildout has begun
2373any processing.  The intent is to allow special plugins such as
2374urllib2 request handlers to be loaded.
2375
2376To load an extension, we use the extensions option and list one or
2377more distribution requirements, on separate lines.  The distributions
2378named will be loaded and any zc.buildout.extensions entry points found
2379will be called with the buildout as an argument.
2380
2381Let's create a sample extension in our sample buildout created in the
2382previous section:
2383
2384    >>> mkdir(sample_bootstrapped, 'demo')
2385
2386    >>> write(sample_bootstrapped, 'demo', 'demo.py',
2387    ... """
2388    ... def ext(buildout):
2389    ...     print 'ext', list(buildout)
2390    ... """)
2391
2392    >>> write(sample_bootstrapped, 'demo', 'setup.py',
2393    ... """
2394    ... from setuptools import setup
2395    ...
2396    ... setup(
2397    ...     name = "demo",
2398    ...     entry_points = {'zc.buildout.extension': ['ext = demo:ext']},
2399    ...     )
2400    ... """)
2401
2402Our extension just prints out the word 'demo', and lists the sections
2403found in the buildout passed to it.
2404
2405We'll update our buildout.cfg to list the demo directory as a develop
2406egg to be built:
2407
2408    >>> write(sample_bootstrapped, 'buildout.cfg',
2409    ... """
2410    ... [buildout]
2411    ... develop = demo
2412    ... parts =
2413    ... """)
2414
2415    >>> os.chdir(sample_bootstrapped)
2416    >>> print system(os.path.join(sample_bootstrapped, 'bin', 'buildout')),
2417    Develop: '/sample-bootstrapped/demo'
2418
2419Now we can add the extensions option.  We were a bit tricky and ran
2420the buildout once with the demo develop egg defined but without the
2421extension option.  This is because extensions are loaded before the
2422buildout creates develop eggs. We needed to use a separate buildout
2423run to create the develop egg.  Normally, when eggs are loaded from
2424the network, we wouldn't need to do anything special.
2425
2426    >>> write(sample_bootstrapped, 'buildout.cfg',
2427    ... """
2428    ... [buildout]
2429    ... develop = demo
2430    ... extensions = demo
2431    ... parts =
2432    ... """)
2433
2434We see that our extension is loaded and executed:
2435
2436    >>> print system(os.path.join(sample_bootstrapped, 'bin', 'buildout')),
2437    ext ['buildout']
2438    Develop: '/sample-bootstrapped/demo'
2439
2440Allow hosts
2441-----------
2442
2443On some environments the links visited by `zc.buildout` can be forbidden
2444by paranoiac firewalls. These URL might be on the chain of links
2445visited by `zc.buildout` wheter they are defined in the `find-links` option,
2446wheter they are defined by various eggs in their `url`, `download_url`,
2447`dependency_links` metadata.
2448
2449It is even harder to track that package_index works like a spider and
2450might visit links and go to other location.
2451
2452The `allow-hosts` option provides a way to prevent this, and
2453works exactly like the one provided in `easy_install`.
2454
2455You can provide a list of allowed host, together with wildcards::
2456
2457    [buildout]
2458    ...
2459
2460    allow-hosts =
2461        *.python.org
2462        example.com
2463
2464All urls that does not match these hosts will not be visited.
2465
2466.. [#future_recipe_methods] In the future, additional methods may be
2467       added. Older recipes with fewer methods will still be
2468       supported.
2469
2470.. [#packaging_info] If we wanted to create a distribution from this
2471       package, we would need specify much more information.  See the
2472       `setuptools documentation
2473       <http://peak.telecommunity.com/DevCenter/setuptools>`_.
Note: See TracBrowser for help on using the repository browser.