Commit e67d9ea8 authored by Jim Fulton's avatar Jim Fulton

Increased default buildout logging.

No longer generate "py-" scripts implicitly.  We no longer create one
for zc.buildout when bootstrapping.

Added an error-reporting API for use by recipes.

Added a help command-line option.

Fixed a bug in the way that recipe eggs were loaded.
parent 8090f07a
##############################################################################
# #
# Copyright (c) 2006 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Buildout package
$Id$
"""
class UserError(Exception):
"""Errors made by a user
"""
def __str__(self):
return " ".join(map(str, self))
...@@ -26,20 +26,18 @@ import sys ...@@ -26,20 +26,18 @@ import sys
import ConfigParser import ConfigParser
import pkg_resources import pkg_resources
import zc.buildout
import zc.buildout.easy_install import zc.buildout.easy_install
class UserError(Exception): pkg_resources_loc = pkg_resources.working_set.find(
"""Errors made by a user pkg_resources.Requirement.parse('setuptools')).location
"""
def __str__(self):
return " ".join(map(str, self))
class MissingOption(UserError, KeyError): class MissingOption(zc.buildout.UserError, KeyError):
"""A required option was missing """A required option was missing
""" """
class MissingSection(UserError, KeyError): class MissingSection(zc.buildout.UserError, KeyError):
"""A required section is missinh """A required section is missinh
""" """
...@@ -87,7 +85,7 @@ class Buildout(dict): ...@@ -87,7 +85,7 @@ class Buildout(dict):
'installed': '.installed.cfg', 'installed': '.installed.cfg',
'python': 'buildout', 'python': 'buildout',
'executable': sys.executable, 'executable': sys.executable,
'log-level': 'WARNING', 'log-level': 'INFO',
'log-format': '%(name)s: %(message)s', 'log-format': '%(name)s: %(message)s',
}) })
...@@ -146,7 +144,8 @@ class Buildout(dict): ...@@ -146,7 +144,8 @@ class Buildout(dict):
if r is not None: if r is not None:
return r return r
if key in seen: if key in seen:
raise UserError("Circular reference in substitutions.\n" raise zc.buildout.UserError(
"Circular reference in substitutions.\n"
"We're evaluating %s\nand are referencing: %s.\n" "We're evaluating %s\nand are referencing: %s.\n"
% (", ".join([":".join(k) for k in seen]), % (", ".join([":".join(k) for k in seen]),
":".join(key) ":".join(key)
...@@ -169,19 +168,21 @@ class Buildout(dict): ...@@ -169,19 +168,21 @@ class Buildout(dict):
s = tuple(ref[2:-1].split(':')) s = tuple(ref[2:-1].split(':'))
if not self._valid(ref): if not self._valid(ref):
if len(s) < 2: if len(s) < 2:
raise UserError("The substitution, %s,\n" raise zc.buildout.UserError("The substitution, %s,\n"
"doesn't contain a colon." "doesn't contain a colon."
% ref) % ref)
if len(s) > 2: if len(s) > 2:
raise UserError("The substitution, %s,\n" raise zc.buildout.UserError("The substitution, %s,\n"
"has too many colons." "has too many colons."
% ref) % ref)
if not self._simple(s[0]): if not self._simple(s[0]):
raise UserError("The section name in substitution, %s,\n" raise zc.buildout.UserError(
"The section name in substitution, %s,\n"
"has invalid characters." "has invalid characters."
% ref) % ref)
if not self._simple(s[1]): if not self._simple(s[1]):
raise UserError("The option name in substitution, %s,\n" raise zc.buildout.UserError(
"The option name in substitution, %s,\n"
"has invalid characters." "has invalid characters."
% ref) % ref)
...@@ -345,27 +346,38 @@ class Buildout(dict): ...@@ -345,27 +346,38 @@ class Buildout(dict):
""" """
develop = self['buildout'].get('develop') develop = self['buildout'].get('develop')
if develop: if develop:
env = dict(os.environ, PYTHONPATH=pkg_resources_loc)
here = os.getcwd() here = os.getcwd()
try: try:
for setup in develop.split(): for setup in develop.split():
setup = self._buildout_path(setup) setup = self._buildout_path(setup)
if os.path.isdir(setup): if os.path.isdir(setup):
setup = os.path.join(setup, 'setup.py') setup = os.path.join(setup, 'setup.py')
self._logger.info("Running %s -q develop ...", setup)
self._logger.info("Develop: %s", setup)
os.chdir(os.path.dirname(setup)) os.chdir(os.path.dirname(setup))
os.spawnle(
os.P_WAIT, sys.executable, sys.executable, args = [
zc.buildout.easy_install._safe_arg(setup), zc.buildout.easy_install._safe_arg(setup),
'-q', 'develop', '-m', '-x', '-N', '-q', 'develop', '-mxN',
'-f', zc.buildout.easy_install._safe_arg( '-f', zc.buildout.easy_install._safe_arg(
' '.join(self._links) ' '.join(self._links)
), ),
'-d', zc.buildout.easy_install._safe_arg( '-d', zc.buildout.easy_install._safe_arg(
self['buildout']['develop-eggs-directory'] self['buildout']['develop-eggs-directory']
), ),
{'PYTHONPATH': ]
os.path.dirname(pkg_resources.__file__)},
) if self._log_level <= logging.DEBUG:
if self._log_level == logging.DEBUG:
del args[1]
else:
args[1] == '-v'
self._logger.debug("in: %s\n%r",
os.path.dirname(setup), args)
args.append(env)
os.spawnle(os.P_WAIT, sys.executable, sys.executable, *args)
finally: finally:
os.chdir(here) os.chdir(here)
...@@ -386,27 +398,28 @@ class Buildout(dict): ...@@ -386,27 +398,28 @@ class Buildout(dict):
raise MissingSection("No section was specified for part", part) raise MissingSection("No section was specified for part", part)
recipe, entry = self._recipe(part, options) recipe, entry = self._recipe(part, options)
if recipe not in recipes_requirements:
recipes_requirements.append(recipe) recipes_requirements.append(recipe)
# Install the recipe distros # Install the recipe distros
offline = self['buildout'].get('offline', 'false') offline = self['buildout'].get('offline', 'false')
if offline not in ('true', 'false'): if offline not in ('true', 'false'):
self._error('Invalif value for offline option: %s', offline) self._error('Invalif value for offline option: %s', offline)
if offline == 'true':
ws = zc.buildout.easy_install.working_set( if offline == 'false':
recipes_requirements, sys.executable, dest = self['buildout']['eggs-directory']
[self['buildout']['eggs-directory'],
self['buildout']['develop-eggs-directory'],
],
)
else: else:
ws = zc.buildout.easy_install.install( dest = None
recipes_requirements, self['buildout']['eggs-directory'],
links=self._links, index=self['buildout'].get('index'),
path=[self['buildout']['develop-eggs-directory']])
# Add the distros to the working set ws = zc.buildout.easy_install.install(
pkg_resources.require(recipes_requirements) recipes_requirements, dest,
links=self._links,
index=self['buildout'].get('index'),
path=[self['buildout']['develop-eggs-directory'],
self['buildout']['eggs-directory'],
],
working_set=pkg_resources.working_set,
)
# instantiate the recipes # instantiate the recipes
for part in parts: for part in parts:
...@@ -517,6 +530,7 @@ class Buildout(dict): ...@@ -517,6 +530,7 @@ class Buildout(dict):
level -= verbosity level -= verbosity
root_logger.setLevel(level) root_logger.setLevel(level)
self._log_level = level
if level <= logging.DEBUG: if level <= logging.DEBUG:
sections = list(self) sections = list(self)
...@@ -528,8 +542,11 @@ class Buildout(dict): ...@@ -528,8 +542,11 @@ class Buildout(dict):
def _maybe_upgrade(self): def _maybe_upgrade(self):
# See if buildout or setuptools need to be upgraded. # See if buildout or setuptools need to be upgraded.
# If they do, do the upgrade and return true. # If they do, do the upgrade and restart the buildout process.
# Otherwise, return False.
if self['buildout'].get('offline') == 'true':
return # skip upgrade in offline mode:
ws = zc.buildout.easy_install.install( ws = zc.buildout.easy_install.install(
[ [
(spec + ' ' + self['buildout'].get(spec+'-version', '')).strip() (spec + ' ' + self['buildout'].get(spec+'-version', '')).strip()
...@@ -550,8 +567,8 @@ class Buildout(dict): ...@@ -550,8 +567,8 @@ class Buildout(dict):
if not upgraded: if not upgraded:
return return
self._logger.info("Upgraded: %s, restarting.", self._logger.info("Upgraded:\n %s;\nrestarting.",
", ".join([("%s version %s" ",\n ".join([("%s version %s"
% (dist.project_name, dist.version) % (dist.project_name, dist.version)
) )
for dist in upgraded for dist in upgraded
...@@ -626,7 +643,7 @@ def _open(base, filename, seen): ...@@ -626,7 +643,7 @@ def _open(base, filename, seen):
filename = os.path.join(base, filename) filename = os.path.join(base, filename)
if filename in seen: if filename in seen:
raise UserError("Recursive file include", seen, filename) raise zc.buildout.UserError("Recursive file include", seen, filename)
base = os.path.dirname(filename) base = os.path.dirname(filename)
seen.append(filename) seen.append(filename)
...@@ -694,6 +711,55 @@ def _error(*message): ...@@ -694,6 +711,55 @@ def _error(*message):
sys.stderr.write('Error: ' + ' '.join(message) +'\n') sys.stderr.write('Error: ' + ' '.join(message) +'\n')
sys.exit(1) sys.exit(1)
_usage = """\
Usage: buildout [options] [assignments] [command [command arguments]]
Options:
-h, --help
Print this message and exit.
-v
Increase the level of verbosity. This option can be used multiple times.
-q
Deccreaae the level of verbosity. This option can be used multiple times.
-c config_file
Specify the path to the buildout configuration file to be used.
This defaults to the file named"buildout.cfg" in the current
working directory.
Assignments are of the form: section:option=value and are used to
provide configuration options that override those givem in the
configuration file. For example, to run the buildout in offline mode,
use buildout:offline=true.
Options and assignments can be interspersed.
Commmonds:
install [parts]
Install parts. If no command arguments are given, then the parts
definition from the configuration file is used. Otherwise, the
arguments specify the parts to be installed.
bootstrap
Create a new buildout in the current working directory, copying
the buildout and setuptools eggs and, creating a basic directory
structure and a buildout-local buildout script.
"""
def _help():
print _usage
sys.exit(0)
def main(args=None): def main(args=None):
if args is None: if args is None:
args = sys.argv[1:] args = sys.argv[1:]
...@@ -705,11 +771,13 @@ def main(args=None): ...@@ -705,11 +771,13 @@ def main(args=None):
if args[0][0] == '-': if args[0][0] == '-':
op = orig_op = args.pop(0) op = orig_op = args.pop(0)
op = op[1:] op = op[1:]
while op and op[0] in 'vq': while op and op[0] in 'vqh':
if op[0] == 'v': if op[0] == 'v':
verbosity += 10 verbosity += 10
else: elif op[0] == 'q':
verbosity -= 10 verbosity -= 10
else:
_help()
op = op[1:] op = op[1:]
if op[:1] == 'c': if op[:1] == 'c':
...@@ -722,6 +790,8 @@ def main(args=None): ...@@ -722,6 +790,8 @@ def main(args=None):
else: else:
_error("No file name specified for option", orig_op) _error("No file name specified for option", orig_op)
elif op: elif op:
if orig_op == '--help':
_help()
_error("Invalid option", '-'+op[0]) _error("Invalid option", '-'+op[0])
elif '=' in args[0]: elif '=' in args[0]:
option, value = args.pop(0).split('=', 1) option, value = args.pop(0).split('=', 1)
...@@ -748,7 +818,7 @@ def main(args=None): ...@@ -748,7 +818,7 @@ def main(args=None):
try: try:
buildout = Buildout(config_file, options) buildout = Buildout(config_file, options)
getattr(buildout, command)(args) getattr(buildout, command)(args)
except UserError, v: except zc.buildout.UserError, v:
_error(str(v)) _error(str(v))
finally: finally:
......
...@@ -51,7 +51,6 @@ The bin directory contains scripts. ...@@ -51,7 +51,6 @@ The bin directory contains scripts.
>>> ls(sample_buildout, 'bin') >>> ls(sample_buildout, 'bin')
- buildout - buildout
- py-zc.buildout
>>> ls(sample_buildout, 'eggs') >>> ls(sample_buildout, 'eggs')
- setuptools-0.6-py2.4.egg - setuptools-0.6-py2.4.egg
...@@ -107,7 +106,7 @@ and then we'll create a source file for our mkdir recipe: ...@@ -107,7 +106,7 @@ and then we'll create a source file for our mkdir recipe:
>>> write(sample_buildout, 'recipes', 'mkdir.py', >>> write(sample_buildout, 'recipes', 'mkdir.py',
... """ ... """
... import logging, os ... import logging, os, zc.buildout
... ...
... class Mkdir: ... class Mkdir:
... ...
...@@ -119,6 +118,12 @@ and then we'll create a source file for our mkdir recipe: ...@@ -119,6 +118,12 @@ and then we'll create a source file for our mkdir recipe:
... buildout['buildout']['directory'], ... buildout['buildout']['directory'],
... options['path'], ... options['path'],
... ) ... )
... if not os.path.isdir(os.path.dirname(options['path'])):
... logging.getLogger(self.name).error(
... 'Cannot create %s. %s is not a directory.',
... options['path'], os.path.dirname(options['path']))
... raise zc.buildout.UserError('Invalid Path')
...
... ...
... def install(self): ... def install(self):
... path = self.options['path'] ... path = self.options['path']
...@@ -211,7 +216,6 @@ Now let's update our buildout.cfg: ...@@ -211,7 +216,6 @@ Now let's update our buildout.cfg:
... [buildout] ... [buildout]
... develop = recipes ... develop = recipes
... parts = data-dir ... parts = data-dir
... log-level = INFO
... ...
... [data-dir] ... [data-dir]
... recipe = recipes:mkdir ... recipe = recipes:mkdir
...@@ -239,14 +243,6 @@ Here we've named a part to be "built". We can use any name we want ...@@ -239,14 +243,6 @@ Here we've named a part to be "built". We can use any name we want
except that different part names must be unique and recipes will often except that different part names must be unique and recipes will often
use the part name to decide what to do. use the part name to decide what to do.
::
log-level = INFO
The default level is WARNING, which is fairly quite. In this example,
we set the level to INFO so we can see more details about what the
buildout and recipes are doing.
:: ::
[data-dir] [data-dir]
...@@ -266,7 +262,7 @@ buildout: ...@@ -266,7 +262,7 @@ buildout:
>>> os.chdir(sample_buildout) >>> os.chdir(sample_buildout)
>>> buildout = os.path.join(sample_buildout, 'bin', 'buildout') >>> buildout = os.path.join(sample_buildout, 'bin', 'buildout')
>>> print system(buildout), >>> print system(buildout),
buildout: Running /tmp/sample-buildout/recipes/setup.py -q develop ... buildout: Develop: /tmp/sample-buildout/recipes/setup.py
buildout: Installing data-dir buildout: Installing data-dir
data-dir: Creating directory mystuff data-dir: Creating directory mystuff
...@@ -307,7 +303,6 @@ we'll see that the directory gets removed and recreated: ...@@ -307,7 +303,6 @@ we'll see that the directory gets removed and recreated:
... [buildout] ... [buildout]
... develop = recipes ... develop = recipes
... parts = data-dir ... parts = data-dir
... log-level = INFO
... ...
... [data-dir] ... [data-dir]
... recipe = recipes:mkdir ... recipe = recipes:mkdir
...@@ -315,7 +310,7 @@ we'll see that the directory gets removed and recreated: ...@@ -315,7 +310,7 @@ we'll see that the directory gets removed and recreated:
... """) ... """)
>>> print system(buildout), >>> print system(buildout),
buildout: Running /tmp/sample-buildout/recipes/setup.py -q develop ... buildout: Develop: /tmp/sample-buildout/recipes/setup.py
buildout: Uninstalling data-dir buildout: Uninstalling data-dir
buildout: Installing data-dir buildout: Installing data-dir
data-dir: Creating directory mydata data-dir: Creating directory mydata
...@@ -330,6 +325,38 @@ we'll see that the directory gets removed and recreated: ...@@ -330,6 +325,38 @@ we'll see that the directory gets removed and recreated:
d parts d parts
d recipes d recipes
Error reporting
---------------
If a user makes an error, an error needs to be printed and work needs
to stop. This is accomplished by logging a detailed error message and
then raising a (or an instance of a subclass of a)
zc.buildout.UserError exception. Raising UserError causes the
buildout to print the error and exit without printing a traceback. In
the sample above, of someone gives a non-existant directory to create
the directory in:
>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... develop = recipes
... parts = data-dir
...
... [data-dir]
... recipe = recipes:mkdir
... path = /xxx/mydata
... """)
We'll get a user error, not a traceback.
>>> print system(buildout),
buildout: Develop: /private/tmp/tmp_I5pHasample-buildout/recipes/setup.py
data-dir: Cannot create /xxx/mydata. /xxx is not a directory.
Error: Invalid Path
Configuration file syntax Configuration file syntax
------------------------- -------------------------
...@@ -440,7 +467,7 @@ Now, if we run the buildout, we'll see the options with the values ...@@ -440,7 +467,7 @@ Now, if we run the buildout, we'll see the options with the values
substituted. substituted.
>>> print system(buildout), >>> print system(buildout),
buildout: Running /tmp/sample-buildout/recipes/setup.py -q develop ... buildout: Develop: /tmp/sample-buildout/recipes/setup.py
buildout: Uninstalling data-dir buildout: Uninstalling data-dir
buildout: Installing data-dir buildout: Installing data-dir
data-dir: Creating directory mydata data-dir: Creating directory mydata
...@@ -459,7 +486,7 @@ recipe, so it assumed it could and reinstalled mydata. If we rerun ...@@ -459,7 +486,7 @@ recipe, so it assumed it could and reinstalled mydata. If we rerun
the buildout: the buildout:
>>> print system(buildout), >>> print system(buildout),
buildout: Running /tmp/sample-buildout/recipes/setup.py -q develop ... buildout: Develop: /tmp/sample-buildout/recipes/setup.py
buildout: Installing data-dir buildout: Installing data-dir
buildout: Installing debug buildout: Installing debug
File 1 mydata/file File 1 mydata/file
...@@ -520,6 +547,10 @@ To see how this works, we use an example: ...@@ -520,6 +547,10 @@ To see how this works, we use an example:
... """) ... """)
>>> print system(buildout), >>> print system(buildout),
buildout: Develop: /sample-buildout/recipes/setup.py
buildout: Uninstalling debug
buildout: Uninstalling data-dir
buildout: Installing debug
op buildout op buildout
recipe recipes:debug recipe recipes:debug
...@@ -619,6 +650,9 @@ Here is a more elaborate example. ...@@ -619,6 +650,9 @@ Here is a more elaborate example.
... """) ... """)
>>> print system(buildout), >>> print system(buildout),
buildout: Develop: /sample-buildout/recipes/setup.py
buildout: Uninstalling debug
buildout: Installing debug
name ee name ee
op buildout op buildout
op1 e1 1 op1 e1 1
...@@ -666,6 +700,9 @@ delimiter.) ...@@ -666,6 +700,9 @@ delimiter.)
>>> os.environ['HOME'] = home >>> os.environ['HOME'] = home
>>> print system(buildout), >>> print system(buildout),
buildout: Develop: /sample-buildout/recipes/setup.py
buildout: Uninstalling debug
buildout: Installing debug
name ee name ee
op buildout op buildout
op1 e1 1 op1 e1 1
...@@ -679,13 +716,40 @@ delimiter.) ...@@ -679,13 +716,40 @@ delimiter.)
>>> del os.environ['HOME'] >>> del os.environ['HOME']
Log level
---------
We can control the level of logging by specifying a log level in out
configuration file. For example, so suppress info messages, we can
set the logging level to WARNING
>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... log-level = WARNING
... extends = b1.cfg b2.cfg
... extended-by = e1.cfg
... """)
>>> print system(buildout),
name e1
op1 e1 1
op2 b1 2
op3 b2 3
op4 b2 4
op5 b2 5
recipe recipes:debug
Command-line usage Command-line usage
------------------ ------------------
A number of arguments can be given on the buildout command line. The A number of arguments can be given on the buildout command line. The
command usage is:: command usage is::
buildout [-c file] [-q] [-v] [assignments] [command [command arguments]] buildout [-h] [-c file] [-q] [-v] [assignments] [command [command arguments]]
The -h (or --help) option causes basic usage information to be
printed. If this option is used, then all other options are ignored.
The -c option can be used to specify a configuration file, rather than The -c option can be used to specify a configuration file, rather than
buildout.cfg in the current directory. buildout.cfg in the current directory.
...@@ -709,6 +773,7 @@ Here's an example: ...@@ -709,6 +773,7 @@ Here's an example:
... develop = recipes ... develop = recipes
... parts = debug ... parts = debug
... installed = .other.cfg ... installed = .other.cfg
... log-level = WARNING
... ...
... [debug] ... [debug]
... name = other ... name = other
...@@ -719,7 +784,7 @@ Note that we used the installed buildout option to specify an ...@@ -719,7 +784,7 @@ Note that we used the installed buildout option to specify an
alternate file to store information about installed parts. alternate file to store information about installed parts.
>>> print system(buildout+' -c other.cfg debug:op1=foo -v'), >>> print system(buildout+' -c other.cfg debug:op1=foo -v'),
buildout: Running /tmp/sample-buildout/recipes/setup.py -q develop ... buildout: Develop: /tmp/sample-buildout/recipes/setup.py
buildout: Installing debug buildout: Installing debug
name other name other
op1 foo op1 foo
...@@ -732,7 +797,7 @@ WARNING. ...@@ -732,7 +797,7 @@ WARNING.
Options can also be combined in the usual Unix way, as in: Options can also be combined in the usual Unix way, as in:
>>> print system(buildout+' -vcother.cfg debug:op1=foo'), >>> print system(buildout+' -vcother.cfg debug:op1=foo'),
buildout: Running /tmp/sample-buildout/recipes/setup.py -q develop ... buildout: Develop: /tmp/sample-buildout/recipes/setup.py
buildout: Installing debug buildout: Installing debug
name other name other
op1 foo op1 foo
...@@ -773,8 +838,8 @@ the buildout in the usual way: ...@@ -773,8 +838,8 @@ the buildout in the usual way:
... recipe = recipes:debug ... recipe = recipes:debug
... """) ... """)
>>> print system(buildout+' -v'), >>> print system(buildout),
buildout: Running /sample-buildout/recipes/setup.py -q develop ... buildout: Develop: /sample-buildout/recipes/setup.py
buildout: Uninstalling debug buildout: Uninstalling debug
buildout: Installing debug buildout: Installing debug
recipe recipes:debug recipe recipes:debug
...@@ -855,8 +920,8 @@ Now we'll update our configuration file: ...@@ -855,8 +920,8 @@ Now we'll update our configuration file:
and run the buildout specifying just d3 and d4: and run the buildout specifying just d3 and d4:
>>> print system(buildout+' -v install d3 d4'), >>> print system(buildout+' install d3 d4'),
buildout: Running /sample-buildout/recipes/setup.py -q develop ... buildout: Develop: /sample-buildout/recipes/setup.py
buildout: Uninstalling d3 buildout: Uninstalling d3
buildout: Installing d3 buildout: Installing d3
d3: Creating directory data3 d3: Creating directory data3
...@@ -924,8 +989,8 @@ directories are still there. ...@@ -924,8 +989,8 @@ directories are still there.
Now, if we run the buildout without the install command: Now, if we run the buildout without the install command:
>>> print system(buildout+' -v'), >>> print system(buildout),
buildout: Running /sample-buildout/recipes/setup.py -q develop ... buildout: Develop: /sample-buildout/recipes/setup.py
buildout: Uninstalling d1 buildout: Uninstalling d1
buildout: Uninstalling d2 buildout: Uninstalling d2
buildout: Uninstalling debug buildout: Uninstalling debug
...@@ -981,12 +1046,12 @@ provide alternate locations, and even names for these directories. ...@@ -981,12 +1046,12 @@ provide alternate locations, and even names for these directories.
... work = os.path.join(alt, 'work'), ... work = os.path.join(alt, 'work'),
... )) ... ))
>>> print system(buildout+' -v'), >>> print system(buildout),
buildout: Creating directory /tmp/sample-alt/scripts buildout: Creating directory /tmp/sample-alt/scripts
buildout: Creating directory /tmp/sample-alt/work buildout: Creating directory /tmp/sample-alt/work
buildout: Creating directory /tmp/sample-alt/basket buildout: Creating directory /tmp/sample-alt/basket
buildout: Creating directory /sample-alt/developbasket buildout: Creating directory /sample-alt/developbasket
buildout: Running /tmp/sample-buildout/recipes/setup.py -q develop ... buildout: Develop: /tmp/sample-buildout/recipes/setup.py
buildout: Uninstalling d4 buildout: Uninstalling d4
buildout: Uninstalling d3 buildout: Uninstalling d3
buildout: Uninstalling d2 buildout: Uninstalling d2
...@@ -1016,12 +1081,12 @@ You can also specify an alternate buildout directory: ...@@ -1016,12 +1081,12 @@ You can also specify an alternate buildout directory:
... recipes=os.path.join(sample_buildout, 'recipes'), ... recipes=os.path.join(sample_buildout, 'recipes'),
... )) ... ))
>>> print system(buildout+' -v'), >>> print system(buildout),
buildout: Creating directory /tmp/sample-alt/bin buildout: Creating directory /tmp/sample-alt/bin
buildout: Creating directory /tmp/sample-alt/parts buildout: Creating directory /tmp/sample-alt/parts
buildout: Creating directory /tmp/sample-alt/eggs buildout: Creating directory /tmp/sample-alt/eggs
buildout: Creating directory /tmp/sample-alt/develop-eggs buildout: Creating directory /tmp/sample-alt/develop-eggs
buildout: Running /tmp/sample-buildout/recipes/setup.py -q develop ... buildout: Develop: /tmp/sample-buildout/recipes/setup.py
>>> ls(alt) >>> ls(alt)
- .installed.cfg - .installed.cfg
...@@ -1070,7 +1135,7 @@ configuration file. Because the verbosity is subtracted from the log ...@@ -1070,7 +1135,7 @@ configuration file. Because the verbosity is subtracted from the log
level, we get a final log level of 20, which is the INFO level. level, we get a final log level of 20, which is the INFO level.
>>> print system(buildout), >>> print system(buildout),
INFO Running /tmp/sample-buildout/recipes/setup.py -q develop ... INFO Develop: /tmp/sample-buildout/recipes/setup.py
Predefined buildout options Predefined buildout options
--------------------------- ---------------------------
...@@ -1087,7 +1152,7 @@ database is shown. ...@@ -1087,7 +1152,7 @@ database is shown.
... parts = ... parts =
... """) ... """)
>>> print system(buildout+' -vv'), >>> print system(buildout+' -v'),
Configuration data: Configuration data:
[buildout] [buildout]
bin-directory = /tmp/sample-buildout/bin bin-directory = /tmp/sample-buildout/bin
...@@ -1097,11 +1162,11 @@ database is shown. ...@@ -1097,11 +1162,11 @@ database is shown.
executable = /usr/local/bin/python2.3 executable = /usr/local/bin/python2.3
installed = /tmp/sample-buildout/.installed.cfg installed = /tmp/sample-buildout/.installed.cfg
log-format = %%(name)s: %%(message)s log-format = %%(name)s: %%(message)s
log-level = WARNING log-level = INFO
parts = parts =
parts-directory = /tmp/sample-buildout/parts parts-directory = /tmp/sample-buildout/parts
python = buildout python = buildout
verbosity = 20 verbosity = 10
<BLANKLINE> <BLANKLINE>
zc.buildout.easy_install: Installing ['zc.buildout', 'setuptools'] zc.buildout.easy_install: Installing ['zc.buildout', 'setuptools']
zc.buildout.easy_install: We have a develop egg for zc.buildout zc.buildout.easy_install: We have a develop egg for zc.buildout
...@@ -1183,6 +1248,10 @@ local buildout scripts. ...@@ -1183,6 +1248,10 @@ local buildout scripts.
... +' -c'+os.path.join(sample_bootstrapped, 'setup.cfg') ... +' -c'+os.path.join(sample_bootstrapped, 'setup.cfg')
... +' bootstrap'), ... +' bootstrap'),
Warning: creating /sample-bootstrapped/setup.cfg Warning: creating /sample-bootstrapped/setup.cfg
buildout: Creating directory /sample-bootstrapped/bin
buildout: Creating directory /sample-bootstrapped/parts
buildout: Creating directory /sample-bootstrapped/eggs
buildout: Creating directory /sample-bootstrapped/develop-eggs
Note that a basic setup.cfg was created for us. Note that a basic setup.cfg was created for us.
...@@ -1195,7 +1264,6 @@ Note that a basic setup.cfg was created for us. ...@@ -1195,7 +1264,6 @@ Note that a basic setup.cfg was created for us.
>>> ls(sample_bootstrapped, 'bin') >>> ls(sample_bootstrapped, 'bin')
- buildout - buildout
- py-zc.buildout
>>> ls(sample_bootstrapped, 'eggs') >>> ls(sample_bootstrapped, 'eggs')
- setuptools-0.6-py2.3.egg - setuptools-0.6-py2.3.egg
......
...@@ -205,15 +205,15 @@ def test_comparing_saved_options_with_funny_characters(): ...@@ -205,15 +205,15 @@ def test_comparing_saved_options_with_funny_characters():
>>> os.chdir(sample_buildout) >>> os.chdir(sample_buildout)
>>> buildout = os.path.join(sample_buildout, 'bin', 'buildout') >>> buildout = os.path.join(sample_buildout, 'bin', 'buildout')
>>> print system(buildout+' -v'), # doctest: +ELLIPSIS >>> print system(buildout), # doctest: +ELLIPSIS
buildout: Running ...setup.py -q develop ... buildout: Develop: ...setup.py
buildout: Installing debug buildout: Installing debug
If we run the buildout again, we shoudn't get a message about If we run the buildout again, we shoudn't get a message about
uninstalling anything because the configuration hasn't changed. uninstalling anything because the configuration hasn't changed.
>>> print system(buildout+' -v'), >>> print system(buildout), # doctest: +ELLIPSIS
buildout: Running setup.py -q develop ... buildout: Develop: ...setup.py
buildout: Installing debug buildout: Installing debug
""" """
...@@ -257,6 +257,101 @@ if os.path.exists(bootstrap_py): ...@@ -257,6 +257,101 @@ if os.path.exists(bootstrap_py):
""" """
def test_help():
"""
>>> print system(os.path.join(sample_buildout, 'bin', 'buildout')+' -h'),
Usage: buildout [options] [assignments] [command [command arguments]]
<BLANKLINE>
Options:
<BLANKLINE>
-h, --help
<BLANKLINE>
Print this message and exit.
<BLANKLINE>
-v
<BLANKLINE>
Increase the level of verbosity. This option can be used multiple times.
<BLANKLINE>
-q
<BLANKLINE>
Deccreaae the level of verbosity. This option can be used multiple times.
<BLANKLINE>
-c config_file
<BLANKLINE>
Specify the path to the buildout configuration file to be used.
This defaults to the file named"buildout.cfg" in the current
working directory.
<BLANKLINE>
Assignments are of the form: section:option=value and are used to
provide configuration options that override those givem in the
configuration file. For example, to run the buildout in offline mode,
use buildout:offline=true.
<BLANKLINE>
Options and assignments can be interspersed.
<BLANKLINE>
Commmonds:
<BLANKLINE>
install [parts]
<BLANKLINE>
Install parts. If no command arguments are given, then the parts
definition from the configuration file is used. Otherwise, the
arguments specify the parts to be installed.
<BLANKLINE>
bootstrap
<BLANKLINE>
Create a new buildout in the current working directory, copying
the buildout and setuptools eggs and, creating a basic directory
structure and a buildout-local buildout script.
<BLANKLINE>
<BLANKLINE>
>>> print system(os.path.join(sample_buildout, 'bin', 'buildout')
... +' --help'),
Usage: buildout [options] [assignments] [command [command arguments]]
<BLANKLINE>
Options:
<BLANKLINE>
-h, --help
<BLANKLINE>
Print this message and exit.
<BLANKLINE>
-v
<BLANKLINE>
Increase the level of verbosity. This option can be used multiple times.
<BLANKLINE>
-q
<BLANKLINE>
Deccreaae the level of verbosity. This option can be used multiple times.
<BLANKLINE>
-c config_file
<BLANKLINE>
Specify the path to the buildout configuration file to be used.
This defaults to the file named"buildout.cfg" in the current
working directory.
<BLANKLINE>
Assignments are of the form: section:option=value and are used to
provide configuration options that override those givem in the
configuration file. For example, to run the buildout in offline mode,
use buildout:offline=true.
<BLANKLINE>
Options and assignments can be interspersed.
<BLANKLINE>
Commmonds:
<BLANKLINE>
install [parts]
<BLANKLINE>
Install parts. If no command arguments are given, then the parts
definition from the configuration file is used. Otherwise, the
arguments specify the parts to be installed.
<BLANKLINE>
bootstrap
<BLANKLINE>
Create a new buildout in the current working directory, copying
the buildout and setuptools eggs and, creating a basic directory
structure and a buildout-local buildout script.
<BLANKLINE>
<BLANKLINE>
"""
def linkerSetUp(test): def linkerSetUp(test):
zc.buildout.testing.buildoutSetUp(test, clear_home=False) zc.buildout.testing.buildoutSetUp(test, clear_home=False)
...@@ -421,7 +516,7 @@ def test_suite(): ...@@ -421,7 +516,7 @@ def test_suite():
setUp=updateSetup, setUp=updateSetup,
tearDown=zc.buildout.testing.buildoutTearDown, tearDown=zc.buildout.testing.buildoutTearDown,
checker=renormalizing.RENormalizing([ checker=renormalizing.RENormalizing([
(re.compile('#!\S+python\S+'), '#!python'), (re.compile('#!\S+python\S*'), '#!python'),
(re.compile('\S+sample-(\w+)'), r'/sample-\1'), (re.compile('\S+sample-(\w+)'), r'/sample-\1'),
(re.compile('-py\d[.]\d.egg'), r'-py2.3.egg'), (re.compile('-py\d[.]\d.egg'), r'-py2.3.egg'),
]) ])
...@@ -441,7 +536,7 @@ def test_suite(): ...@@ -441,7 +536,7 @@ def test_suite():
% dict(sep=os_path_sep)), % dict(sep=os_path_sep)),
'/sample-eggs/'), '/sample-eggs/'),
(re.compile("([d-] ((ext)?demo(needed)?|other)" (re.compile("([d-] ((ext)?demo(needed)?|other)"
"-\d[.]\d-py)\d[.]\d(-[^. \t\n]+)?[.]egg"), "-\d[.]\d-py)\d[.]\d(-\S+)?[.]egg"),
'\\1V.V.egg'), '\\1V.V.egg'),
(re.compile('(\n?)- ([a-zA-Z_.-]+)-script.py\n- \\2.exe\n'), (re.compile('(\n?)- ([a-zA-Z_.-]+)-script.py\n- \\2.exe\n'),
'\\1- \\2\n'), '\\1- \\2\n'),
......
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