Commit cd3eca20 authored by jim's avatar jim

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.


git-svn-id: http://svn.zope.org/repos/main/zc.buildout/trunk@69990 62d5b8a3-27da-0310-9561-8e5933582275
parent fb7cb086
##############################################################################
#
# 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
import ConfigParser
import pkg_resources
import zc.buildout
import zc.buildout.easy_install
class UserError(Exception):
"""Errors made by a user
"""
pkg_resources_loc = pkg_resources.working_set.find(
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
"""
class MissingSection(UserError, KeyError):
class MissingSection(zc.buildout.UserError, KeyError):
"""A required section is missinh
"""
......@@ -87,7 +85,7 @@ class Buildout(dict):
'installed': '.installed.cfg',
'python': 'buildout',
'executable': sys.executable,
'log-level': 'WARNING',
'log-level': 'INFO',
'log-format': '%(name)s: %(message)s',
})
......@@ -146,7 +144,8 @@ class Buildout(dict):
if r is not None:
return r
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"
% (", ".join([":".join(k) for k in seen]),
":".join(key)
......@@ -169,19 +168,21 @@ class Buildout(dict):
s = tuple(ref[2:-1].split(':'))
if not self._valid(ref):
if len(s) < 2:
raise UserError("The substitution, %s,\n"
raise zc.buildout.UserError("The substitution, %s,\n"
"doesn't contain a colon."
% ref)
if len(s) > 2:
raise UserError("The substitution, %s,\n"
raise zc.buildout.UserError("The substitution, %s,\n"
"has too many colons."
% ref)
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."
% ref)
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."
% ref)
......@@ -345,27 +346,38 @@ class Buildout(dict):
"""
develop = self['buildout'].get('develop')
if develop:
env = dict(os.environ, PYTHONPATH=pkg_resources_loc)
here = os.getcwd()
try:
for setup in develop.split():
setup = self._buildout_path(setup)
if os.path.isdir(setup):
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.spawnle(
os.P_WAIT, sys.executable, sys.executable,
args = [
zc.buildout.easy_install._safe_arg(setup),
'-q', 'develop', '-m', '-x', '-N',
'-q', 'develop', '-mxN',
'-f', zc.buildout.easy_install._safe_arg(
' '.join(self._links)
),
'-d', zc.buildout.easy_install._safe_arg(
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:
os.chdir(here)
......@@ -386,27 +398,28 @@ class Buildout(dict):
raise MissingSection("No section was specified for part", part)
recipe, entry = self._recipe(part, options)
if recipe not in recipes_requirements:
recipes_requirements.append(recipe)
# Install the recipe distros
offline = self['buildout'].get('offline', 'false')
if offline not in ('true', 'false'):
self._error('Invalif value for offline option: %s', offline)
if offline == 'true':
ws = zc.buildout.easy_install.working_set(
recipes_requirements, sys.executable,
[self['buildout']['eggs-directory'],
self['buildout']['develop-eggs-directory'],
],
)
if offline == 'false':
dest = self['buildout']['eggs-directory']
else:
ws = zc.buildout.easy_install.install(
recipes_requirements, self['buildout']['eggs-directory'],
links=self._links, index=self['buildout'].get('index'),
path=[self['buildout']['develop-eggs-directory']])
dest = None
# Add the distros to the working set
pkg_resources.require(recipes_requirements)
ws = zc.buildout.easy_install.install(
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
for part in parts:
......@@ -517,6 +530,7 @@ class Buildout(dict):
level -= verbosity
root_logger.setLevel(level)
self._log_level = level
if level <= logging.DEBUG:
sections = list(self)
......@@ -528,8 +542,11 @@ class Buildout(dict):
def _maybe_upgrade(self):
# See if buildout or setuptools need to be upgraded.
# If they do, do the upgrade and return true.
# Otherwise, return False.
# If they do, do the upgrade and restart the buildout process.
if self['buildout'].get('offline') == 'true':
return # skip upgrade in offline mode:
ws = zc.buildout.easy_install.install(
[
(spec + ' ' + self['buildout'].get(spec+'-version', '')).strip()
......@@ -550,8 +567,8 @@ class Buildout(dict):
if not upgraded:
return
self._logger.info("Upgraded: %s, restarting.",
", ".join([("%s version %s"
self._logger.info("Upgraded:\n %s;\nrestarting.",
",\n ".join([("%s version %s"
% (dist.project_name, dist.version)
)
for dist in upgraded
......@@ -626,7 +643,7 @@ def _open(base, filename, seen):
filename = os.path.join(base, filename)
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)
seen.append(filename)
......@@ -694,6 +711,55 @@ def _error(*message):
sys.stderr.write('Error: ' + ' '.join(message) +'\n')
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):
if args is None:
args = sys.argv[1:]
......@@ -705,11 +771,13 @@ def main(args=None):
if args[0][0] == '-':
op = orig_op = args.pop(0)
op = op[1:]
while op and op[0] in 'vq':
while op and op[0] in 'vqh':
if op[0] == 'v':
verbosity += 10
else:
elif op[0] == 'q':
verbosity -= 10
else:
_help()
op = op[1:]
if op[:1] == 'c':
......@@ -722,6 +790,8 @@ def main(args=None):
else:
_error("No file name specified for option", orig_op)
elif op:
if orig_op == '--help':
_help()
_error("Invalid option", '-'+op[0])
elif '=' in args[0]:
option, value = args.pop(0).split('=', 1)
......@@ -748,7 +818,7 @@ def main(args=None):
try:
buildout = Buildout(config_file, options)
getattr(buildout, command)(args)
except UserError, v:
except zc.buildout.UserError, v:
_error(str(v))
finally:
......
......@@ -51,7 +51,6 @@ The bin directory contains scripts.
>>> ls(sample_buildout, 'bin')
- buildout
- py-zc.buildout
>>> ls(sample_buildout, 'eggs')
- setuptools-0.6-py2.4.egg
......@@ -107,7 +106,7 @@ and then we'll create a source file for our mkdir recipe:
>>> write(sample_buildout, 'recipes', 'mkdir.py',
... """
... import logging, os
... import logging, os, zc.buildout
...
... class Mkdir:
...
......@@ -119,6 +118,12 @@ and then we'll create a source file for our mkdir recipe:
... buildout['buildout']['directory'],
... options['path'],
... )
... if not os.path.isdir(os.path.dirname(options['path'])):
... logging.getLogger(self.name).error(
... 'Cannot create %s. %s is not a directory.',
... options['path'], os.path.dirname(options['path']))
... raise zc.buildout.UserError('Invalid Path')
...
...
... def install(self):
... path = self.options['path']
......@@ -211,7 +216,6 @@ Now let's update our buildout.cfg:
... [buildout]
... develop = recipes
... parts = data-dir
... log-level = INFO
...
... [data-dir]
... recipe = recipes:mkdir
......@@ -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
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]
......@@ -266,7 +262,7 @@ buildout:
>>> os.chdir(sample_buildout)
>>> buildout = os.path.join(sample_buildout, 'bin', '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
data-dir: Creating directory mystuff
......@@ -307,7 +303,6 @@ we'll see that the directory gets removed and recreated:
... [buildout]
... develop = recipes
... parts = data-dir
... log-level = INFO
...
... [data-dir]
... recipe = recipes:mkdir
......@@ -315,7 +310,7 @@ we'll see that the directory gets removed and recreated:
... """)
>>> 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: Installing data-dir
data-dir: Creating directory mydata
......@@ -330,6 +325,38 @@ we'll see that the directory gets removed and recreated:
d parts
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
-------------------------
......@@ -440,7 +467,7 @@ Now, if we run the buildout, we'll see the options with the values
substituted.
>>> 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: Installing data-dir
data-dir: Creating directory mydata
......@@ -459,7 +486,7 @@ recipe, so it assumed it could and reinstalled mydata. If we rerun
the 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 debug
File 1 mydata/file
......@@ -520,6 +547,10 @@ To see how this works, we use an example:
... """)
>>> print system(buildout),
buildout: Develop: /sample-buildout/recipes/setup.py
buildout: Uninstalling debug
buildout: Uninstalling data-dir
buildout: Installing debug
op buildout
recipe recipes:debug
......@@ -619,6 +650,9 @@ Here is a more elaborate example.
... """)
>>> print system(buildout),
buildout: Develop: /sample-buildout/recipes/setup.py
buildout: Uninstalling debug
buildout: Installing debug
name ee
op buildout
op1 e1 1
......@@ -666,6 +700,9 @@ delimiter.)
>>> os.environ['HOME'] = home
>>> print system(buildout),
buildout: Develop: /sample-buildout/recipes/setup.py
buildout: Uninstalling debug
buildout: Installing debug
name ee
op buildout
op1 e1 1
......@@ -679,13 +716,40 @@ delimiter.)
>>> 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
------------------
A number of arguments can be given on the buildout command line. The
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
buildout.cfg in the current directory.
......@@ -709,6 +773,7 @@ Here's an example:
... develop = recipes
... parts = debug
... installed = .other.cfg
... log-level = WARNING
...
... [debug]
... name = other
......@@ -719,7 +784,7 @@ Note that we used the installed buildout option to specify an
alternate file to store information about installed parts.
>>> print system(buildout+' -c other.cfg debug:op1=foo -v'),
buildout: Running /tmp/sample-buildout/recipes/setup.py -q develop ...
buildout: Develop: /tmp/sample-buildout/recipes/setup.py
buildout: Installing debug
name other
op1 foo
......@@ -732,7 +797,7 @@ WARNING.
Options can also be combined in the usual Unix way, as in:
>>> 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
name other
op1 foo
......@@ -773,8 +838,8 @@ the buildout in the usual way:
... recipe = recipes:debug
... """)
>>> print system(buildout+' -v'),
buildout: Running /sample-buildout/recipes/setup.py -q develop ...
>>> print system(buildout),
buildout: Develop: /sample-buildout/recipes/setup.py
buildout: Uninstalling debug
buildout: Installing debug
recipe recipes:debug
......@@ -855,8 +920,8 @@ Now we'll update our configuration file:
and run the buildout specifying just d3 and d4:
>>> print system(buildout+' -v install d3 d4'),
buildout: Running /sample-buildout/recipes/setup.py -q develop ...
>>> print system(buildout+' install d3 d4'),
buildout: Develop: /sample-buildout/recipes/setup.py
buildout: Uninstalling d3
buildout: Installing d3
d3: Creating directory data3
......@@ -924,8 +989,8 @@ directories are still there.
Now, if we run the buildout without the install command:
>>> print system(buildout+' -v'),
buildout: Running /sample-buildout/recipes/setup.py -q develop ...
>>> print system(buildout),
buildout: Develop: /sample-buildout/recipes/setup.py
buildout: Uninstalling d1
buildout: Uninstalling d2
buildout: Uninstalling debug
......@@ -981,12 +1046,12 @@ provide alternate locations, and even names for these directories.
... 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/work
buildout: Creating directory /tmp/sample-alt/basket
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 d3
buildout: Uninstalling d2
......@@ -1016,12 +1081,12 @@ You can also specify an alternate buildout directory:
... 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/parts
buildout: Creating directory /tmp/sample-alt/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)
- .installed.cfg
......@@ -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.
>>> print system(buildout),
INFO Running /tmp/sample-buildout/recipes/setup.py -q develop ...
INFO Develop: /tmp/sample-buildout/recipes/setup.py
Predefined buildout options
---------------------------
......@@ -1087,7 +1152,7 @@ database is shown.
... parts =
... """)
>>> print system(buildout+' -vv'),
>>> print system(buildout+' -v'),
Configuration data:
[buildout]
bin-directory = /tmp/sample-buildout/bin
......@@ -1097,11 +1162,11 @@ database is shown.
executable = /usr/local/bin/python2.3
installed = /tmp/sample-buildout/.installed.cfg
log-format = %%(name)s: %%(message)s
log-level = WARNING
log-level = INFO
parts =
parts-directory = /tmp/sample-buildout/parts
python = buildout
verbosity = 20
verbosity = 10
<BLANKLINE>
zc.buildout.easy_install: Installing ['zc.buildout', 'setuptools']
zc.buildout.easy_install: We have a develop egg for zc.buildout
......@@ -1183,6 +1248,10 @@ local buildout scripts.
... +' -c'+os.path.join(sample_bootstrapped, 'setup.cfg')
... +' bootstrap'),
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.
......@@ -1195,7 +1264,6 @@ Note that a basic setup.cfg was created for us.
>>> ls(sample_bootstrapped, 'bin')
- buildout
- py-zc.buildout
>>> ls(sample_bootstrapped, 'eggs')
- setuptools-0.6-py2.3.egg
......
......@@ -205,15 +205,15 @@ def test_comparing_saved_options_with_funny_characters():
>>> os.chdir(sample_buildout)
>>> buildout = os.path.join(sample_buildout, 'bin', 'buildout')
>>> print system(buildout+' -v'), # doctest: +ELLIPSIS
buildout: Running ...setup.py -q develop ...
>>> print system(buildout), # doctest: +ELLIPSIS
buildout: Develop: ...setup.py
buildout: Installing debug
If we run the buildout again, we shoudn't get a message about
uninstalling anything because the configuration hasn't changed.
>>> print system(buildout+' -v'),
buildout: Running setup.py -q develop ...
>>> print system(buildout), # doctest: +ELLIPSIS
buildout: Develop: ...setup.py
buildout: Installing debug
"""
......@@ -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):
zc.buildout.testing.buildoutSetUp(test, clear_home=False)
......@@ -421,7 +516,7 @@ def test_suite():
setUp=updateSetup,
tearDown=zc.buildout.testing.buildoutTearDown,
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('-py\d[.]\d.egg'), r'-py2.3.egg'),
])
......@@ -441,7 +536,7 @@ def test_suite():
% dict(sep=os_path_sep)),
'/sample-eggs/'),
(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'),
(re.compile('(\n?)- ([a-zA-Z_.-]+)-script.py\n- \\2.exe\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