[Checkins] SVN: zc.buildout/trunk/ merge of svn+ssh://svn.zope.org/repos/main/zc.buildout/branches/gary-betafix r115885
Gary Poster
gary.poster at canonical.com
Mon Aug 23 11:04:24 EDT 2010
Log message for revision 115887:
merge of svn+ssh://svn.zope.org/repos/main/zc.buildout/branches/gary-betafix r115885
Changed:
_U zc.buildout/trunk/
U zc.buildout/trunk/CHANGES.txt
A zc.buildout/trunk/MANIFEST.in
A zc.buildout/trunk/SYSTEM_PYTHON_HELP.txt
D zc.buildout/trunk/bootstrap/bootstrap.py
A zc.buildout/trunk/bootstrap/bootstrap.py
D zc.buildout/trunk/bootstrap/newbootstrap.py
U zc.buildout/trunk/buildout.cfg
U zc.buildout/trunk/dev.py
U zc.buildout/trunk/setup.py
U zc.buildout/trunk/src/zc/buildout/allowhosts.txt
U zc.buildout/trunk/src/zc/buildout/bootstrap.txt
U zc.buildout/trunk/src/zc/buildout/buildout.py
U zc.buildout/trunk/src/zc/buildout/buildout.txt
U zc.buildout/trunk/src/zc/buildout/debugging.txt
U zc.buildout/trunk/src/zc/buildout/dependencylinks.txt
U zc.buildout/trunk/src/zc/buildout/easy_install.py
U zc.buildout/trunk/src/zc/buildout/easy_install.txt
U zc.buildout/trunk/src/zc/buildout/testing.py
U zc.buildout/trunk/src/zc/buildout/testing_bugfix.txt
U zc.buildout/trunk/src/zc/buildout/tests.py
U zc.buildout/trunk/src/zc/buildout/testselectingpython.py
U zc.buildout/trunk/src/zc/buildout/update.txt
A zc.buildout/trunk/src/zc/buildout/virtualenv.txt
U zc.buildout/trunk/z3c.recipe.scripts_/CHANGES.txt
A zc.buildout/trunk/z3c.recipe.scripts_/MANIFEST.in
U zc.buildout/trunk/z3c.recipe.scripts_/setup.py
U zc.buildout/trunk/z3c.recipe.scripts_/src/z3c/recipe/scripts/scripts.py
U zc.buildout/trunk/z3c.recipe.scripts_/src/z3c/recipe/scripts/tests.py
U zc.buildout/trunk/zc.recipe.egg_/CHANGES.txt
A zc.buildout/trunk/zc.recipe.egg_/MANIFEST.in
U zc.buildout/trunk/zc.recipe.egg_/setup.py
U zc.buildout/trunk/zc.recipe.egg_/src/zc/recipe/egg/egg.py
U zc.buildout/trunk/zc.recipe.egg_/src/zc/recipe/egg/tests.py
-=-
Property changes on: zc.buildout/trunk
___________________________________________________________________
Modified: svn:mergeinfo
- /zc.buildout/branches/gary-launchpad:111587
/zc.buildout/trunk:108946
+ /zc.buildout/branches/gary-launchpad:111587
/zc.buildout/branches/gary-betafix:115514,115815,115845-115847,115859
/zc.buildout/trunk:108946
Modified: svk:merge
- 62d5b8a3-27da-0310-9561-8e5933582275:/zc.buildout/branches/gary-launchpad:111587
62d5b8a3-27da-0310-9561-8e5933582275:/zc.buildout/trunk:108946
+ 62d5b8a3-27da-0310-9561-8e5933582275:/zc.buildout/branches/gary-betafix:115859
62d5b8a3-27da-0310-9561-8e5933582275:/zc.buildout/branches/gary-launchpad:111587
62d5b8a3-27da-0310-9561-8e5933582275:/zc.buildout/trunk:108946
Modified: zc.buildout/trunk/CHANGES.txt
===================================================================
--- zc.buildout/trunk/CHANGES.txt 2010-08-23 14:55:43 UTC (rev 115886)
+++ zc.buildout/trunk/CHANGES.txt 2010-08-23 15:04:24 UTC (rev 115887)
@@ -1,6 +1,42 @@
Change History
**************
+1.5.0 (unreleased)
+==================
+
+New features:
+
+- zc.buildout supports Python 2.7.
+
+- By default, Buildout and the bootstrap script now prefer final versions of
+ Buildout, recipes, and extensions. This can be changed by using the
+ --accept-buildout-test-releases flag (or -t for short) when calling
+ bootstrap. This will hopefully allow beta releases of these items to
+ be more easily and safely made in the future.
+
+ NOTE: dependencies of your own software are not affected by this new
+ behavior. Buildout continues to choose the newest available versions
+ of your dependencies regardless of whether they are final releases. To
+ prevent this, use the pre-existing switch ``prefer-final = true`` in
+ the [buildout] section of your configuration file (see
+ http://pypi.python.org/pypi/zc.buildout#preferring-final-releases) or
+ pin your versions using a versions section (see
+ http://pypi.python.org/pypi/zc.buildout#repeatable-buildouts-controlling-eggs-used).
+
+Bugs fixed:
+
+- You can now again use virtualenv with Buildout. The new features to let
+ buildout be used with a system Python are disabled in this configuration,
+ and the previous script generation behavior (1.4.3) is used, even if
+ the new function ``zc.buildout.easy_install.sitepackage_safe_scripts``
+ is used.
+
+1.5.0b2 (2010-04-29)
+====================
+
+This was a re-release of 1.4.3 in order to keep 1.5.0b1 release from hurting
+workflows that combined virtualenv with zc.buildout.
+
1.5.0b1 (2010-04-29)
====================
@@ -10,8 +46,13 @@
both from command line and from config files. (gotcha)
- Buildout can be safely used with a system Python (or any Python with code
- in site-packages), as long as you use the new z3c.recipe.scripts
- recipe to generate scripts and interpreters, rather than zc.recipe.egg.
+ in site-packages), as long as you use (1) A fresh checkout, (2) the
+ new bootstrap.py, and (3) recipes that use the new
+ ``zc.buildout.easy_install.sitepackage_safe_scripts`` function to generate
+ scripts and interpreters. Many recipes will need to be updated to use
+ this new function. The scripts and interpreters generated by
+ ``zc.recipe.egg`` will continue to use the older function, not safe
+ with system Pythons. Use the ``z3c.recipe.scripts`` as a replacement.
zc.recipe.egg is still a fully supported, and simpler, way of
generating scripts and interpreters if you are using a "clean" Python,
@@ -42,15 +83,15 @@
* The buildout script generated by bootstrap honors more of the settings
in the designated configuration file (e.g., buildout.cfg).
- * Correcly handle systems where pkg_resources is present but the rest of
+ * Correctly handle systems where pkg_resources is present but the rest of
setuptools is missing (like Ubuntu installs).
https://bugs.launchpad.net/zc.buildout/+bug/410528
- You can develop zc.buildout using Distribute instead of Setuptools. Use
the --distribute option on the dev.py script. (Releases should be tested
with both Distribute and Setuptools.) The tests for zc.buildout pass
- with Setuptools and Python 2.4, 2.5, and 2.6; and with Distribute and
- Python 2.5 and 2.6. Using zc.buildout with Distribute and Python 2.4
+ with Setuptools and Python 2.4, 2.5, 2.6, and 2.7; and with Distribute and
+ Python 2.5, 2.6, and 2.7. Using zc.buildout with Distribute and Python 2.4
is not recommended.
- The ``distribute-version`` now works in the [buildout] section, mirroring
Copied: zc.buildout/trunk/MANIFEST.in (from rev 115859, zc.buildout/branches/gary-betafix/MANIFEST.in)
===================================================================
--- zc.buildout/trunk/MANIFEST.in (rev 0)
+++ zc.buildout/trunk/MANIFEST.in 2010-08-23 15:04:24 UTC (rev 115887)
@@ -0,0 +1,3 @@
+include *.txt
+recursive-include src *.txt
+exclude MANIFEST.in buildout.cfg .bzrignore
Copied: zc.buildout/trunk/SYSTEM_PYTHON_HELP.txt (from rev 115859, zc.buildout/branches/gary-betafix/SYSTEM_PYTHON_HELP.txt)
===================================================================
--- zc.buildout/trunk/SYSTEM_PYTHON_HELP.txt (rev 0)
+++ zc.buildout/trunk/SYSTEM_PYTHON_HELP.txt 2010-08-23 15:04:24 UTC (rev 115887)
@@ -0,0 +1,226 @@
+System Python and zc.buildout 1.5
+*********************************
+
+The 1.5 line of zc.buildout introduced a number of changes.
+
+Problems
+========
+
+As usual, please send questions and comments to the `distutils SIG
+mailing list <mailto://distutils-sig@python.org>`_. Report bugs using
+the `zc.buildout Launchpad Bug Tracker
+<https://launchpad.net/zc.buildout/+bugs>`_.
+
+If problems are keeping you from your work, here's an easy way to
+revert to the old code temporarily: switch to a custom "emergency"
+bootstrap script, available from
+http://svn.zope.org/repos/main/zc.buildout/branches/1.4/bootstrap/bootstrap.py .
+
+This customized script will select zc.buildout 1.4.4 by default.
+zc.buildout 1.4.4 will not upgrade itself unless you explicitly specify
+a new version. It will also prefer older versions of zc.recipe.egg and
+some other common recipes. If you have trouble with other recipes,
+consider using a standard buildout "versions" section to specify older
+versions of these, as described in the Buildout documentation
+(http://pypi.python.org/pypi/zc.buildout#repeatable-buildouts-controlling-eggs-used).
+
+Working with a System Python
+============================
+
+While there are a number of new features available in zc.buildout 1.5,
+the biggest is that Buildout itself supports usage with a system Python.
+This can work if you follow a couple of simple rules.
+
+1. Use the new bootstrap.py (available from
+ svn://svn.zope.org/repos/main/zc.buildout/trunk/bootstrap/bootstrap.py).
+
+2. Use buildout recipes that have been upgraded to work with zc.buildout 1.5
+ and higher. Specifically, they should use
+ ``zc.buildout.easy_install.sitepackage_safe_scripts`` to generate
+ their scripts, if any, rather than ``zc.buildout.easy_install.scripts``.
+ See the `Recipes That Support a System Python`_ section below for more
+ details on recipes that are available as of this writing, and
+ `Updating Recipes to Support a System Python`_ for instructions on
+ how to update a recipe. Note that you should generally only need to
+ update recipes that generate scripts.
+
+It's important to note that recipes not upgraded for zc.buildout 1.5.0
+should continue to work--just not with a system Python.
+
+Using a system Python is inherently fragile. Using a clean,
+freshly-installed Python without customization in site-packages is more
+robust and repeatable. See some of the regression tests added to the
+1.5.0 line for the kinds of issues that you can encounter with a system
+Python, and see
+http://pypi.python.org/pypi/z3c.recipe.scripts#including-site-packages-and-sitecustomize
+for more discussion.
+
+However, using a system Python can be very convenient, and the
+zc.buildout code for this feature has been tested by many users already.
+Moreover, it has automated tests to exercise the problems that have been
+encountered and fixed.
+
+Recipes That Support a System Python
+====================================
+
+zc.recipe.egg continues to generate old-style scripts that are not safe
+for use with a system Python. This was done for backwards
+compatibility, because it is integral to so many buildouts and used as a
+dependency of so many other recipes.
+
+If you want to generate new-style scripts that do support system Python
+usage, use z3c.recipe.scripts instead
+(http://pypi.python.org/pypi/z3c.recipe.scripts). z3c.recipe.scripts has
+the same script and interpreter generation options as zc.recipe.egg,
+plus a few more for the new features mentioned above. In the simplest
+case, you should be able to simply change ``recipe = zc.recipe.egg`` to
+``recipe = z3c.recipe.scripts`` in the pertinent sections of your
+buildout configuration and your generated scripts will work with a system
+Python.
+
+This is the only updated recipe as of this writing. Others should be
+updated soon: see their change documents for details, or see `Updating
+Recipes to Support a System Python`_ for instructions on how to update
+recipes yourself.
+
+Templates for creating Python scripts with the z3c.recipe.filetemplate
+recipe can be easily changed to support a system Python.
+
+- If you don't care about supporting relative paths, simply using a
+ generated interpreter with the eggs you want should be sufficient, as
+ it was before. For instance, if the interpreter is named "py", use
+ ``#!${buildout:bin-directory/py}`` or ``#!/usr/bin/env
+ ${buildout:bin-directory/py}``).
+
+- If you do care about relative paths, (``relative-paths = true`` in
+ your buildout configuration), then z3c.recipe.scripts does require a
+ bit more changes, as is usual for the relative path support in that
+ package. First, use z3c.recipe.scripts to generate a script or
+ interpreter with the dependencies you want. This will create a
+ directory in ``parts`` that has a site.py and sitecustomize.py. Then,
+ begin your script as in the snippet below. The example assumes that
+ the z3c.recipe.scripts generated were from a Buildout configuration
+ section labeled "scripts": adjust accordingly.
+
+ ::
+
+ #!${buildout:executable} -S
+ ${python-relative-path-setup}
+ import sys
+ sys.path.insert(0, ${scripts:parts-directory|path-repr})
+ import site
+
+Updating Recipes to Support a System Python
+===========================================
+
+You should generally only need to update recipes that generate scripts.
+These recipes need to change from using ``zc.buildout.easy_install.scripts``
+to be using ``zc.buildout.easy_install.sitepackage_safe_scripts``.
+The signatures of the two functions are different. Please compare::
+
+ def scripts(
+ reqs, working_set, executable, dest,
+ scripts=None,
+ extra_paths=(),
+ arguments='',
+ interpreter=None,
+ initialization='',
+ relative_paths=False,
+ ):
+
+ def sitepackage_safe_scripts(
+ dest, working_set, executable, site_py_dest,
+ reqs=(),
+ scripts=None,
+ interpreter=None,
+ extra_paths=(),
+ initialization='',
+ include_site_packages=False,
+ exec_sitecustomize=False,
+ relative_paths=False,
+ script_arguments='',
+ script_initialization='',
+ ):
+
+In most cases, the arguments are merely reordered. The ``reqs``
+argument is no longer required in order to make it easier to generate an
+interpreter alone. The ``arguments`` argument was renamed to
+``script_arguments`` to clarify that it did not affect interpreter
+generation.
+
+The only new required argument is ``site_py_dest``. It must be the path
+to a directory in which the customized site.py and sitecustomize.py
+files will be written. A typical generation in a recipe will look like
+this.
+
+(In the recipe's __init__ method...)
+
+::
+
+ self.options = options
+ b_options = buildout['buildout']
+ options['parts-directory'] = os.path.join(
+ b_options['parts-directory'], self.name)
+
+(In the recipe's install method...)
+
+::
+
+ options = self.options
+ generated = []
+ if not os.path.exists(options['parts-directory']):
+ os.mkdir(options['parts-directory'])
+ generated.append(options['parts-directory'])
+
+Then ``options['parts-directory']`` can be used for the ``site_py_dest``
+value.
+
+If you want to support the other arguments (``include_site_packages``,
+``exec_sitecustomize``, ``script_initialization``, as well as the
+``allowed-eggs-from-site-packages`` option), you might want to look at
+some of the code in
+svn://svn.zope.org/repos/main/zc.buildout/trunk/z3c.recipe.scripts\_/src/z3c/recipe/scripts/scripts.py .
+You might even be able to adopt some of it by subclassing or delegating.
+The Scripts class in that file is the closest to what you might be used
+to from zc.recipe.egg.
+
+Important note for recipe authors: the code in recipes is *always run
+without access to the site-packages*. This is irrespective of the
+``include-site-packages`` option discussed elsewhere, which controls the
+software being built, but not the environment in which Buildout itself runs.
+
+virtualenv
+==========
+
+Using virtualenv (http://pypi.python.org/pypi/virtualenv) with the
+--no-site-packages option already provided a simple way of using a
+system Python. This is intended to continue to work, and some automated
+tests exist to demonstrate this.
+
+However, it is only supported to the degree that people have found it to
+work in the past. The existing Buildout tests for virtualenv are only
+for problems encountered previously. They are very far from
+comprehensive.
+
+Using Buildout with a system python has at least three advantages over
+using Buildout in conjunction with virtualenv. They may or may not be
+pertinent to your desired usage.
+
+- Unlike ``virtualenv --no-site-packages``, Buildout's support allows you
+ to choose to let packages from your system Python be available to your
+ software (see ``include-site-packages`` in
+ http://pypi.python.org/pypi/z3c.recipe.scripts).
+
+ You can even specify which eggs installed in your system Python can be
+ allowed to fulfill some of your packages' dependencies (see
+ ``allowed-eggs-from-site-packages`` in
+ http://pypi.python.org/pypi/z3c.recipe.scripts).
+
+ At the expense of some repeatability and platform dependency, this
+ flexibility means that, for instance, you can rely on
+ difficult-to-build eggs like lxml coming from your system Python.
+
+- Buildout's implementation has a full set of automated tests.
+
+- An integral Buildout implementation means fewer steps and fewer dependencies
+ to work with a system Python.
Deleted: zc.buildout/trunk/bootstrap/bootstrap.py
===================================================================
--- zc.buildout/trunk/bootstrap/bootstrap.py 2010-08-23 14:55:43 UTC (rev 115886)
+++ zc.buildout/trunk/bootstrap/bootstrap.py 2010-08-23 15:04:24 UTC (rev 115887)
@@ -1,116 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2006 Zope Foundation 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.
-#
-##############################################################################
-"""Bootstrap a buildout-based project
-
-Simply run this script in a directory containing a buildout.cfg.
-The script accepts buildout command-line options, so you can
-use the -c option to specify an alternate configuration file.
-"""
-
-import os, shutil, sys, tempfile, urllib2
-from optparse import OptionParser
-
-tmpeggs = tempfile.mkdtemp()
-
-is_jython = sys.platform.startswith('java')
-
-# parsing arguments
-parser = OptionParser()
-parser.add_option("-v", "--version", dest="version",
- help="use a specific zc.buildout version")
-parser.add_option("-d", "--distribute",
- action="store_true", dest="distribute", default=False,
- help="Use Distribute rather than Setuptools.")
-
-parser.add_option("-c", None, action="store", dest="config_file",
- help=("Specify the path to the buildout configuration "
- "file to be used."))
-
-options, args = parser.parse_args()
-
-# if -c was provided, we push it back into args for buildout' main function
-if options.config_file is not None:
- args += ['-c', options.config_file]
-
-if options.version is not None:
- VERSION = '==%s' % options.version
-else:
- VERSION = ''
-
-USE_DISTRIBUTE = options.distribute
-args = args + ['bootstrap']
-
-try:
- import pkg_resources
- import setuptools
- if not hasattr(pkg_resources, '_distribute'):
- raise ImportError
-except ImportError:
- ez = {}
- if USE_DISTRIBUTE:
- exec urllib2.urlopen('http://python-distribute.org/distribute_setup.py'
- ).read() in ez
- ez['use_setuptools'](to_dir=tmpeggs, download_delay=0, no_fake=True)
- else:
- exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
- ).read() in ez
- ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
-
- reload(sys.modules['pkg_resources'])
- import pkg_resources
-
-if sys.platform == 'win32':
- def quote(c):
- if ' ' in c:
- return '"%s"' % c # work around spawn lamosity on windows
- else:
- return c
-else:
- def quote (c):
- return c
-
-cmd = 'from setuptools.command.easy_install import main; main()'
-ws = pkg_resources.working_set
-
-if USE_DISTRIBUTE:
- requirement = 'distribute'
-else:
- requirement = 'setuptools'
-
-if is_jython:
- import subprocess
-
- assert subprocess.Popen([sys.executable] + ['-c', quote(cmd), '-mqNxd',
- quote(tmpeggs), 'zc.buildout' + VERSION],
- env=dict(os.environ,
- PYTHONPATH=
- ws.find(pkg_resources.Requirement.parse(requirement)).location
- ),
- ).wait() == 0
-
-else:
- assert os.spawnle(
- os.P_WAIT, sys.executable, quote (sys.executable),
- '-c', quote (cmd), '-mqNxd', quote (tmpeggs), 'zc.buildout' + VERSION,
- dict(os.environ,
- PYTHONPATH=
- ws.find(pkg_resources.Requirement.parse(requirement)).location
- ),
- ) == 0
-
-ws.add_entry(tmpeggs)
-ws.require('zc.buildout' + VERSION)
-import zc.buildout.buildout
-zc.buildout.buildout.main(args)
-shutil.rmtree(tmpeggs)
Copied: zc.buildout/trunk/bootstrap/bootstrap.py (from rev 115416, zc.buildout/trunk/bootstrap/newbootstrap.py)
===================================================================
--- zc.buildout/trunk/bootstrap/bootstrap.py (rev 0)
+++ zc.buildout/trunk/bootstrap/bootstrap.py 2010-08-23 15:04:24 UTC (rev 115887)
@@ -0,0 +1,258 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation 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.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+"""
+
+import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
+from optparse import OptionParser
+
+if sys.platform == 'win32':
+ def quote(c):
+ if ' ' in c:
+ return '"%s"' % c # work around spawn lamosity on windows
+ else:
+ return c
+else:
+ quote = str
+
+# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
+stdout, stderr = subprocess.Popen(
+ [sys.executable, '-Sc',
+ 'try:\n'
+ ' import ConfigParser\n'
+ 'except ImportError:\n'
+ ' print 1\n'
+ 'else:\n'
+ ' print 0\n'],
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+has_broken_dash_S = bool(int(stdout.strip()))
+
+# In order to be more robust in the face of system Pythons, we want to
+# run without site-packages loaded. This is somewhat tricky, in
+# particular because Python 2.6's distutils imports site, so starting
+# with the -S flag is not sufficient. However, we'll start with that:
+if not has_broken_dash_S and 'site' in sys.modules:
+ # We will restart with python -S.
+ args = sys.argv[:]
+ args[0:0] = [sys.executable, '-S']
+ args = map(quote, args)
+ os.execv(sys.executable, args)
+# Now we are running with -S. We'll get the clean sys.path, import site
+# because distutils will do it later, and then reset the path and clean
+# out any namespace packages from site-packages that might have been
+# loaded by .pth files.
+clean_path = sys.path[:]
+import site
+sys.path[:] = clean_path
+for k, v in sys.modules.items():
+ if (hasattr(v, '__path__') and
+ len(v.__path__)==1 and
+ not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
+ # This is a namespace package. Remove it.
+ sys.modules.pop(k)
+
+is_jython = sys.platform.startswith('java')
+
+setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
+distribute_source = 'http://python-distribute.org/distribute_setup.py'
+
+# parsing arguments
+def normalize_to_url(option, opt_str, value, parser):
+ if value:
+ if '://' not in value: # It doesn't smell like a URL.
+ value = 'file://%s' % (
+ urllib.pathname2url(
+ os.path.abspath(os.path.expanduser(value))),)
+ if opt_str == '--download-base' and not value.endswith('/'):
+ # Download base needs a trailing slash to make the world happy.
+ value += '/'
+ else:
+ value = None
+ name = opt_str[2:].replace('-', '_')
+ setattr(parser.values, name, value)
+
+usage = '''\
+[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
+
+Bootstraps a buildout-based project.
+
+Simply run this script in a directory containing a buildout.cfg, using the
+Python that you want bin/buildout to use.
+
+Note that by using --setup-source and --download-base to point to
+local resources, you can keep this script from going over the network.
+'''
+
+parser = OptionParser(usage=usage)
+parser.add_option("-v", "--version", dest="version",
+ help="use a specific zc.buildout version")
+parser.add_option("-d", "--distribute",
+ action="store_true", dest="use_distribute", default=False,
+ help="Use Distribute rather than Setuptools.")
+parser.add_option("--setup-source", action="callback", dest="setup_source",
+ callback=normalize_to_url, nargs=1, type="string",
+ help=("Specify a URL or file location for the setup file. "
+ "If you use Setuptools, this will default to " +
+ setuptools_source + "; if you use Distribute, this "
+ "will default to " + distribute_source +"."))
+parser.add_option("--download-base", action="callback", dest="download_base",
+ callback=normalize_to_url, nargs=1, type="string",
+ help=("Specify a URL or directory for downloading "
+ "zc.buildout and either Setuptools or Distribute. "
+ "Defaults to PyPI."))
+parser.add_option("--eggs",
+ help=("Specify a directory for storing eggs. Defaults to "
+ "a temporary directory that is deleted when the "
+ "bootstrap script completes."))
+parser.add_option("-t", "--accept-buildout-test-releases",
+ dest='accept_buildout_test_releases',
+ action="store_true", default=False,
+ help=("Normally, if you do not specify a --version, the "
+ "bootstrap script and buildout gets the newest "
+ "*final* versions of zc.buildout and its recipes and "
+ "extensions for you. If you use this flag, "
+ "bootstrap and buildout will get the newest releases "
+ "even if they are alphas or betas."))
+parser.add_option("-c", None, action="store", dest="config_file",
+ help=("Specify the path to the buildout configuration "
+ "file to be used."))
+
+options, args = parser.parse_args()
+
+# if -c was provided, we push it back into args for buildout's main function
+if options.config_file is not None:
+ args += ['-c', options.config_file]
+
+if options.eggs:
+ eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
+else:
+ eggs_dir = tempfile.mkdtemp()
+
+if options.setup_source is None:
+ if options.use_distribute:
+ options.setup_source = distribute_source
+ else:
+ options.setup_source = setuptools_source
+
+if options.accept_buildout_test_releases:
+ args.append('buildout:accept-buildout-test-releases=true')
+args.append('bootstrap')
+
+try:
+ import pkg_resources
+ import setuptools # A flag. Sometimes pkg_resources is installed alone.
+ if not hasattr(pkg_resources, '_distribute'):
+ raise ImportError
+except ImportError:
+ ez_code = urllib2.urlopen(
+ options.setup_source).read().replace('\r\n', '\n')
+ ez = {}
+ exec ez_code in ez
+ setup_args = dict(to_dir=eggs_dir, download_delay=0)
+ if options.download_base:
+ setup_args['download_base'] = options.download_base
+ if options.use_distribute:
+ setup_args['no_fake'] = True
+ ez['use_setuptools'](**setup_args)
+ reload(sys.modules['pkg_resources'])
+ import pkg_resources
+ # This does not (always?) update the default working set. We will
+ # do it.
+ for path in sys.path:
+ if path not in pkg_resources.working_set.entries:
+ pkg_resources.working_set.add_entry(path)
+
+cmd = [quote(sys.executable),
+ '-c',
+ quote('from setuptools.command.easy_install import main; main()'),
+ '-mqNxd',
+ quote(eggs_dir)]
+
+if not has_broken_dash_S:
+ cmd.insert(1, '-S')
+
+find_links = options.download_base
+if not find_links:
+ find_links = os.environ.get('bootstrap-testing-find-links')
+if find_links:
+ cmd.extend(['-f', quote(find_links)])
+
+if options.use_distribute:
+ setup_requirement = 'distribute'
+else:
+ setup_requirement = 'setuptools'
+ws = pkg_resources.working_set
+setup_requirement_path = ws.find(
+ pkg_resources.Requirement.parse(setup_requirement)).location
+env = dict(
+ os.environ,
+ PYTHONPATH=setup_requirement_path)
+
+requirement = 'zc.buildout'
+version = options.version
+if version is None and not options.accept_buildout_test_releases:
+ # Figure out the most recent final version of zc.buildout.
+ import setuptools.package_index
+ _final_parts = '*final-', '*final'
+ def _final_version(parsed_version):
+ for part in parsed_version:
+ if (part[:1] == '*') and (part not in _final_parts):
+ return False
+ return True
+ index = setuptools.package_index.PackageIndex(
+ search_path=[setup_requirement_path])
+ if find_links:
+ index.add_find_links((find_links,))
+ req = pkg_resources.Requirement.parse(requirement)
+ if index.obtain(req) is not None:
+ best = []
+ bestv = None
+ for dist in index[req.project_name]:
+ distv = dist.parsed_version
+ if _final_version(distv):
+ if bestv is None or distv > bestv:
+ best = [dist]
+ bestv = distv
+ elif distv == bestv:
+ best.append(dist)
+ if best:
+ best.sort()
+ version = best[-1].version
+if version:
+ requirement = '=='.join((requirement, version))
+cmd.append(requirement)
+
+if is_jython:
+ import subprocess
+ exitcode = subprocess.Popen(cmd, env=env).wait()
+else: # Windows prefers this, apparently; otherwise we would prefer subprocess
+ exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
+if exitcode != 0:
+ sys.stdout.flush()
+ sys.stderr.flush()
+ print ("An error occurred when trying to install zc.buildout. "
+ "Look above this message for any errors that "
+ "were output by easy_install.")
+ sys.exit(exitcode)
+
+ws.add_entry(eggs_dir)
+ws.require(requirement)
+import zc.buildout.buildout
+zc.buildout.buildout.main(args)
+if not options.eggs: # clean up temporary egg directory
+ shutil.rmtree(eggs_dir)
Deleted: zc.buildout/trunk/bootstrap/newbootstrap.py
===================================================================
--- zc.buildout/trunk/bootstrap/newbootstrap.py 2010-08-23 14:55:43 UTC (rev 115886)
+++ zc.buildout/trunk/bootstrap/newbootstrap.py 2010-08-23 15:04:24 UTC (rev 115887)
@@ -1,200 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2006 Zope Foundation 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.
-#
-##############################################################################
-"""Bootstrap a buildout-based project
-
-Simply run this script in a directory containing a buildout.cfg.
-The script accepts buildout command-line options, so you can
-use the -c option to specify an alternate configuration file.
-"""
-
-import os, shutil, sys, tempfile, textwrap, urllib, urllib2
-from optparse import OptionParser
-
-if sys.platform == 'win32':
- def quote(c):
- if ' ' in c:
- return '"%s"' % c # work around spawn lamosity on windows
- else:
- return c
-else:
- quote = str
-
-# In order to be more robust in the face of system Pythons, we want to
-# run without site-packages loaded. This is somewhat tricky, in
-# particular because Python 2.6's distutils imports site, so starting
-# with the -S flag is not sufficient. However, we'll start with that:
-if 'site' in sys.modules:
- # We will restart with python -S.
- args = sys.argv[:]
- args[0:0] = [sys.executable, '-S']
- args = map(quote, args)
- os.execv(sys.executable, args)
-# Now we are running with -S. We'll get the clean sys.path, import site
-# because distutils will do it later, and then reset the path and clean
-# out any namespace packages from site-packages that might have been
-# loaded by .pth files.
-clean_path = sys.path[:]
-import site
-sys.path[:] = clean_path
-for k, v in sys.modules.items():
- if (hasattr(v, '__path__') and
- len(v.__path__)==1 and
- not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
- # This is a namespace package. Remove it.
- sys.modules.pop(k)
-
-is_jython = sys.platform.startswith('java')
-
-setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
-distribute_source = 'http://python-distribute.org/distribute_setup.py'
-
-# parsing arguments
-def normalize_to_url(option, opt_str, value, parser):
- if value:
- if '://' not in value: # It doesn't smell like a URL.
- value = 'file://%s' % (
- urllib.pathname2url(
- os.path.abspath(os.path.expanduser(value))),)
- if opt_str == '--download-base' and not value.endswith('/'):
- # Download base needs a trailing slash to make the world happy.
- value += '/'
- else:
- value = None
- name = opt_str[2:].replace('-', '_')
- setattr(parser.values, name, value)
-
-usage = '''\
-[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
-
-Bootstraps a buildout-based project.
-
-Simply run this script in a directory containing a buildout.cfg, using the
-Python that you want bin/buildout to use.
-
-Note that by using --setup-source and --download-base to point to
-local resources, you can keep this script from going over the network.
-'''
-
-parser = OptionParser(usage=usage)
-parser.add_option("-v", "--version", dest="version",
- help="use a specific zc.buildout version")
-parser.add_option("-d", "--distribute",
- action="store_true", dest="use_distribute", default=False,
- help="Use Distribute rather than Setuptools.")
-parser.add_option("--setup-source", action="callback", dest="setup_source",
- callback=normalize_to_url, nargs=1, type="string",
- help=("Specify a URL or file location for the setup file. "
- "If you use Setuptools, this will default to " +
- setuptools_source + "; if you use Distribute, this "
- "will default to " + distribute_source +"."))
-parser.add_option("--download-base", action="callback", dest="download_base",
- callback=normalize_to_url, nargs=1, type="string",
- help=("Specify a URL or directory for downloading "
- "zc.buildout and either Setuptools or Distribute. "
- "Defaults to PyPI."))
-parser.add_option("--eggs",
- help=("Specify a directory for storing eggs. Defaults to "
- "a temporary directory that is deleted when the "
- "bootstrap script completes."))
-parser.add_option("-c", None, action="store", dest="config_file",
- help=("Specify the path to the buildout configuration "
- "file to be used."))
-
-options, args = parser.parse_args()
-
-# if -c was provided, we push it back into args for buildout's main function
-if options.config_file is not None:
- args += ['-c', options.config_file]
-
-if options.eggs:
- eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
-else:
- eggs_dir = tempfile.mkdtemp()
-
-if options.setup_source is None:
- if options.use_distribute:
- options.setup_source = distribute_source
- else:
- options.setup_source = setuptools_source
-
-args = args + ['bootstrap']
-
-
-try:
- import pkg_resources
- import setuptools # A flag. Sometimes pkg_resources is installed alone.
- if not hasattr(pkg_resources, '_distribute'):
- raise ImportError
-except ImportError:
- ez_code = urllib2.urlopen(
- options.setup_source).read().replace('\r\n', '\n')
- ez = {}
- exec ez_code in ez
- setup_args = dict(to_dir=eggs_dir, download_delay=0)
- if options.download_base:
- setup_args['download_base'] = options.download_base
- if options.use_distribute:
- setup_args['no_fake'] = True
- ez['use_setuptools'](**setup_args)
- reload(sys.modules['pkg_resources'])
- import pkg_resources
- # This does not (always?) update the default working set. We will
- # do it.
- for path in sys.path:
- if path not in pkg_resources.working_set.entries:
- pkg_resources.working_set.add_entry(path)
-
-cmd = [quote(sys.executable),
- '-c',
- quote('from setuptools.command.easy_install import main; main()'),
- '-mqNxd',
- quote(eggs_dir)]
-
-if options.download_base:
- cmd.extend(['-f', quote(options.download_base)])
-
-requirement = 'zc.buildout'
-if options.version:
- requirement = '=='.join((requirement, options.version))
-cmd.append(requirement)
-
-if options.use_distribute:
- setup_requirement = 'distribute'
-else:
- setup_requirement = 'setuptools'
-ws = pkg_resources.working_set
-env = dict(
- os.environ,
- PYTHONPATH=ws.find(
- pkg_resources.Requirement.parse(setup_requirement)).location)
-
-if is_jython:
- import subprocess
- exitcode = subprocess.Popen(cmd, env=env).wait()
-else: # Windows prefers this, apparently; otherwise we would prefer subprocess
- exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
-if exitcode != 0:
- sys.stdout.flush()
- sys.stderr.flush()
- print ("An error occurred when trying to install zc.buildout. "
- "Look above this message for any errors that "
- "were output by easy_install.")
- sys.exit(exitcode)
-
-ws.add_entry(eggs_dir)
-ws.require(requirement)
-import zc.buildout.buildout
-zc.buildout.buildout.main(args)
-if not options.eggs: # clean up temporary egg directory
- shutil.rmtree(eggs_dir)
Modified: zc.buildout/trunk/buildout.cfg
===================================================================
--- zc.buildout/trunk/buildout.cfg 2010-08-23 14:55:43 UTC (rev 115886)
+++ zc.buildout/trunk/buildout.cfg 2010-08-23 15:04:24 UTC (rev 115887)
@@ -11,16 +11,15 @@
[test]
recipe = zc.recipe.testrunner
eggs =
- zc.buildout
+ zc.buildout[test]
zc.recipe.egg
z3c.recipe.scripts
- zope.testing
# Tests that can be run wo a network
[oltest]
recipe = zc.recipe.testrunner
eggs =
- zc.buildout
+ zc.buildout[test]
zc.recipe.egg
z3c.recipe.scripts
defaults =
Modified: zc.buildout/trunk/dev.py
===================================================================
--- zc.buildout/trunk/dev.py 2010-08-23 14:55:43 UTC (rev 115886)
+++ zc.buildout/trunk/dev.py 2010-08-23 15:04:24 UTC (rev 115887)
@@ -19,7 +19,7 @@
$Id$
"""
-import os, shutil, sys, subprocess, urllib2
+import os, shutil, sys, subprocess, urllib2, subprocess
from optparse import OptionParser
if sys.platform == 'win32':
@@ -31,11 +31,15 @@
else:
quote = str
+# Detect https://bugs.launchpad.net/virtualenv/+bug/572545 .
+has_broken_dash_S = subprocess.call(
+ [sys.executable, '-Sc', 'import ConfigParser'])
+
# In order to be more robust in the face of system Pythons, we want to
# run without site-packages loaded. This is somewhat tricky, in
# particular because Python 2.6's distutils imports site, so starting
# with the -S flag is not sufficient. However, we'll start with that:
-if 'site' in sys.modules:
+if not has_broken_dash_S and 'site' in sys.modules:
# We will restart with python -S.
args = sys.argv[:]
args[0:0] = [sys.executable, '-S']
@@ -117,11 +121,15 @@
env = os.environ.copy() # Windows needs yet-to-be-determined values from this.
env['PYTHONPATH'] = os.path.dirname(pkg_resources.__file__)
-subprocess.Popen(
- [sys.executable] +
- ['setup.py', '-q', 'develop', '-m', '-x', '-d', 'develop-eggs'],
- env=env).wait()
+cmd = [sys.executable,
+ 'setup.py', '-q', 'develop', '-m', '-x', '-d', 'develop-eggs']
+
+if not has_broken_dash_S:
+ cmd.insert(1, '-S')
+
+subprocess.Popen(cmd, env=env).wait()
+
pkg_resources.working_set.add_entry('src')
import zc.buildout.easy_install
Modified: zc.buildout/trunk/setup.py
===================================================================
--- zc.buildout/trunk/setup.py 2010-08-23 14:55:43 UTC (rev 115886)
+++ zc.buildout/trunk/setup.py 2010-08-23 15:04:24 UTC (rev 115887)
@@ -12,7 +12,7 @@
#
##############################################################################
name = "zc.buildout"
-version = "1.5.0dev"
+version = "1.5.0"
import os
from setuptools import setup
@@ -23,6 +23,8 @@
long_description=(
read('README.txt')
+ '\n' +
+ read('SYSTEM_PYTHON_HELP.txt')
+ + '\n' +
'Detailed Documentation\n'
'**********************\n'
+ '\n' +
@@ -83,6 +85,7 @@
install_requires = 'setuptools',
include_package_data = True,
entry_points = entry_points,
+ extras_require = dict(test=['zope.testing']),
zip_safe=False,
classifiers = [
'Intended Audience :: Developers',
Modified: zc.buildout/trunk/src/zc/buildout/allowhosts.txt
===================================================================
--- zc.buildout/trunk/src/zc/buildout/allowhosts.txt 2010-08-23 14:55:43 UTC (rev 115886)
+++ zc.buildout/trunk/src/zc/buildout/allowhosts.txt 2010-08-23 15:04:24 UTC (rev 115887)
@@ -2,14 +2,14 @@
-----------
On some environments the links visited by `zc.buildout` can be forbidden
-by paranoiac firewalls. These URL might be on the chain of links
+by paranoiac firewalls. These URL might be on the chain of links
visited by `zc.buildout` whether they are defined in the `find-links` option
or by various eggs in their `url`, `download_url` and `dependency_links` metadata.
-It is even harder to track that package_index works like a spider and
+It is even harder to track that package_index works like a spider and
might visit links and go to other location.
-The `allow-hosts` option provides a way to prevent this, and
+The `allow-hosts` option provides a way to prevent this, and
works exactly like the one provided in `easy_install`
(see `easy_install allow-hosts option`_).
@@ -17,7 +17,7 @@
[buildout]
...
-
+
allow-hosts =
*.python.org
example.com
@@ -36,7 +36,7 @@
... zip_safe=True, version='1')
... ''')
-Now let's configure the buildout to use the develop egg,
+Now let's configure the buildout to use the develop egg,
together with some rules that disallow any website but PyPI and
local files::
@@ -55,14 +55,11 @@
Now we can run the buildout and make sure all attempts to dist.plone.org fails::
- >>> print system(buildout)
+ >>> print system(buildout) # doctest: +ELLIPSIS
Develop: '/sample-buildout/allowdemo'
- Installing eggs.
- <BLANKLINE>
+ ...
Link to http://dist.plone.org ***BLOCKED*** by --allow-hosts
- <BLANKLINE>
- Couldn't find index page for 'kss.core' (maybe misspelled?)
- Getting distribution for 'kss.core'.
+ ...
While:
Installing eggs.
Getting distribution for 'kss.core'.
@@ -91,14 +88,11 @@
Now we can run the buildout and make sure all attempts to dist.plone.org fails::
- >>> print system(buildout)
+ >>> print system(buildout) # doctest: +ELLIPSIS
Develop: '/sample-buildout/allowdemo'
- Installing eggs.
- <BLANKLINE>
+ ...
Link to http://dist.plone.org ***BLOCKED*** by --allow-hosts
- <BLANKLINE>
- Couldn't find index page for 'kss.core' (maybe misspelled?)
- Getting distribution for 'kss.core'.
+ ...
While:
Installing eggs.
Getting distribution for 'kss.core'.
@@ -115,7 +109,7 @@
... [buildout]
... parts=python
... foo = ${python:interpreter}
- ...
+ ...
... [python]
... recipe=zc.recipe.egg
... eggs=zc.buildout
Modified: zc.buildout/trunk/src/zc/buildout/bootstrap.txt
===================================================================
--- zc.buildout/trunk/src/zc/buildout/bootstrap.txt 2010-08-23 14:55:43 UTC (rev 115886)
+++ zc.buildout/trunk/src/zc/buildout/bootstrap.txt 2010-08-23 15:04:24 UTC (rev 115887)
@@ -47,16 +47,116 @@
X...
d zc.buildout-...egg
+The buildout script it has generated is a new-style script, using a
+customized site.py.
+
+ >>> buildout_script = join(sample_buildout, 'bin', 'buildout')
+ >>> if sys.platform.startswith('win'):
+ ... buildout_script += '-script.py'
+ >>> print open(buildout_script).read() # doctest: +ELLIPSIS
+ #...
+ <BLANKLINE>
+ import sys
+ sys.path[0:0] = [
+ '/sample/parts/buildout',
+ ]
+ <BLANKLINE>
+ <BLANKLINE>
+ import os
+ path = sys.path[0]
+ if os.environ.get('PYTHONPATH'):
+ path = os.pathsep.join([path, os.environ['PYTHONPATH']])
+ os.environ['PYTHONPATH'] = path
+ import site # imports custom buildout-generated site.py
+ <BLANKLINE>
+ import zc.buildout.buildout
+ <BLANKLINE>
+ if __name__ == '__main__':
+ zc.buildout.buildout.main()
+ <BLANKLINE>
+
+The bootstrap process prefers final versions of zc.buildout, so it has
+selected the (generated-locally) 99.99 egg rather than the also-available
+100.0b1 egg. We can see that in the buildout script's site.py.
+
+ >>> buildout_site_py = join(
+ ... sample_buildout, 'parts', 'buildout', 'site.py')
+ >>> print open(buildout_site_py).read() # doctest: +ELLIPSIS
+ "...
+ buildout_paths = [
+ '/sample/eggs/setuptools-...egg',
+ '/sample/eggs/zc.buildout-99.99-pyN.N.egg'
+ ]
+ ...
+
+If you want to accept early releases of zc.buildout, you either need to
+specify an explicit version (using --version here and specifying the
+version in the buildout configuration file using the
+``buildout-version`` option or the ``versions`` option) or specify that you
+accept early releases by using ``--accept-buildout-test-releases`` on the
+bootstrap script.
+
+Here's an example.
+
+ >>> ignored = system(
+ ... zc.buildout.easy_install._safe_arg(sys.executable)+' '+
+ ... 'bootstrap.py --accept-buildout-test-releases')
+ >>> print open(buildout_site_py).read() # doctest: +ELLIPSIS
+ "...
+ buildout_paths = [
+ '/sample/eggs/setuptools-...egg',
+ '/sample/eggs/zc.buildout-100.0b1-pyN.N.egg'
+ ]
+ ...
+
+Notice we are now using zc.buildout 100.0b1, a non-final release.
+
+The buildout script remembers the decision to accept early releases, and
+alerts the user.
+
+ >>> print system(join('bin', 'buildout')),
+ ... # doctest: +NORMALIZE_WHITESPACE
+ NOTE: Accepting early releases of build system packages. Rerun bootstrap
+ without --accept-buildout-test-releases (-t) to return to default
+ behavior.
+
+This is accomplished within the script itself.
+
+ >>> print open(buildout_script).read() # doctest: +ELLIPSIS
+ #...
+ sys.argv.insert(1, 'buildout:accept-buildout-test-releases=true')
+ print ('NOTE: Accepting early releases of build system packages. Rerun '
+ 'bootstrap without --accept-buildout-test-releases (-t) to return to '
+ 'default behavior.')
+ ...
+
+As the note says, to undo, you just need to re-run bootstrap without
+--accept-buildout-test-releases.
+
+ >>> ignored = system(
+ ... zc.buildout.easy_install._safe_arg(sys.executable)+' '+
+ ... 'bootstrap.py')
+ >>> print open(buildout_site_py).read() # doctest: +ELLIPSIS
+ "...
+ buildout_paths = [
+ '/sample/eggs/setuptools-...egg',
+ '/sample/eggs/zc.buildout-99.99-pyN.N.egg'
+ ]
+ ...
+ >>> ('buildout:accept-buildout-test-releases=true' in
+ ... open(buildout_script).read())
+ False
+
Now we will try the `--version` option, which lets you define a version for
`zc.buildout`. If not provided, bootstrap will look for the latest one.
Let's try with an unknown version::
- >>> print 'X'; print system(
+ >>> print 'XX'; print system(
... zc.buildout.easy_install._safe_arg(sys.executable)+' '+
... 'bootstrap.py --version UNKNOWN'); print 'X' # doctest: +ELLIPSIS
...
- X
+ X...
No local packages or download links found for zc.buildout==UNKNOWN...
...
@@ -71,11 +171,9 @@
<BLANKLINE>
X
-Let's make sure the generated `buildout` script uses it::
+Versions older than 1.5.0 put their egg dependencies in the ``buildout`` script.
+Let's make sure it was generated as we expect::
- >>> buildout_script = join(sample_buildout, 'bin', 'buildout')
- >>> if sys.platform.startswith('win'):
- ... buildout_script += '-script.py'
>>> print open(buildout_script).read() # doctest: +ELLIPSIS
#...
<BLANKLINE>
@@ -102,7 +200,7 @@
<BLANKLINE>
X
-Let's make sure the generated `buildout` script uses it::
+Let's make sure the generated ``buildout`` script uses it::
>>> print open(buildout_script).read() # doctest: +ELLIPSIS
#...
@@ -119,7 +217,7 @@
zc.buildout.buildout.main()
<BLANKLINE>
-`zc.buildout` now can also run with `Distribute` with the `--distribute`
+``zc.buildout`` now can also run with `Distribute` with the `--distribute`
option::
>>> print 'X'; print system(
@@ -128,27 +226,18 @@
...
X
...
- Generated script '/sample/bin/buildout'.
- <BLANKLINE>
+ Generated script '/sample/bin/buildout'...
X
-Let's make sure the generated `buildout` script uses it::
+Let's make sure the generated ``site.py`` uses it::
+ >>> print open(buildout_site_py).read() # doctest: +ELLIPSIS
+ "...
+ buildout_paths = [
+ '/sample/eggs/distribute-...egg',
+ '/sample/eggs/zc.buildout-99.99-pyN.N.egg'
+ ]
+ ...
- >>> print open(buildout_script).read() # doctest: +ELLIPSIS
- #...
- <BLANKLINE>
- import sys
- sys.path[0:0] = [
- '/sample/eggs/distribute-...egg',
- '/sample/eggs/zc.buildout-...egg',
- ]
- <BLANKLINE>
- import zc.buildout.buildout
- <BLANKLINE>
- if __name__ == '__main__':
- zc.buildout.buildout.main()
- <BLANKLINE>
-
Make sure both options can be used together::
>>> print 'X'; print system(
@@ -158,12 +247,11 @@
...
X
...
- Generated script '/sample/bin/buildout'.
- <BLANKLINE>
+ Generated script '/sample/bin/buildout'...
X
-Let's make sure the generated `buildout` script uses ``Distribute`` *and*
-``zc.buildout-1.2.1``::
+Let's make sure the old-style generated ``buildout`` script uses
+``Distribute`` *and* ``zc.buildout-1.2.1``::
>>> print open(buildout_script).read() # doctest: +ELLIPSIS
#...
@@ -192,22 +280,80 @@
...
X
...
- Generated script '/sample/bin/buildout'.
- <BLANKLINE>
+ Generated script '/sample/bin/buildout'...
X
+You can specify a location of ez_setup.py or distribute_setup, so you
+can rely on a local or remote location. We'll write our own ez_setup.py
+that we will also use to test some other bootstrap options.
+
+ >>> write('ez_setup.py', '''\
+ ... def use_setuptools(**kwargs):
+ ... import sys, pprint
+ ... pprint.pprint(kwargs, width=40)
+ ... sys.exit()
+ ... ''')
+ >>> print system(
+ ... zc.buildout.easy_install._safe_arg(sys.executable)+' '+
+ ... 'bootstrap.py --setup-source=./ez_setup.py')
+ ... # doctest: +ELLIPSIS
+ {'download_delay': 0,
+ 'to_dir': '...'}
+ <BLANKLINE>
+
+You can also pass a download-cache, and a place in which eggs should be stored
+(they are normally stored in a temporary directory).
+
+ >>> print system(
+ ... zc.buildout.easy_install._safe_arg(sys.executable)+' '+
+ ... 'bootstrap.py --setup-source=./ez_setup.py '+
+ ... '--download-base=./download-cache --eggs=eggs')
+ ... # doctest: +ELLIPSIS
+ {'download_base': '/sample/download-cache/',
+ 'download_delay': 0,
+ 'to_dir': '/sample/eggs'}
+ <BLANKLINE>
+
Here's the entire help text.
>>> print system(
... zc.buildout.easy_install._safe_arg(sys.executable)+' '+
... 'bootstrap.py --help'),
... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
- Usage: bootstrap.py [options]
+ Usage: [DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
<BLANKLINE>
+ Bootstraps a buildout-based project.
+ <BLANKLINE>
+ Simply run this script in a directory containing a buildout.cfg, using the
+ Python that you want bin/buildout to use.
+ <BLANKLINE>
+ Note that by using --setup-source and --download-base to point to
+ local resources, you can keep this script from going over the network.
+ <BLANKLINE>
+ <BLANKLINE>
Options:
-h, --help show this help message and exit
-v VERSION, --version=VERSION
use a specific zc.buildout version
-d, --distribute Use Distribute rather than Setuptools.
+ --setup-source=SETUP_SOURCE
+ Specify a URL or file location for the setup file. If
+ you use Setuptools, this will default to
+ http://peak.telecommunity.com/dist/ez_setup.py; if you
+ use Distribute, this will default to http://python-
+ distribute.org/distribute_setup.py.
+ --download-base=DOWNLOAD_BASE
+ Specify a URL or directory for downloading zc.buildout
+ and either Setuptools or Distribute. Defaults to PyPI.
+ --eggs=EGGS Specify a directory for storing eggs. Defaults to a
+ temporary directory that is deleted when the bootstrap
+ script completes.
+ -t, --accept-buildout-test-releases
+ Normally, if you do not specify a --version, the
+ bootstrap script and buildout gets the newest *final*
+ versions of zc.buildout and its recipes and extensions
+ for you. If you use this flag, bootstrap and buildout
+ will get the newest releases even if they are alphas
+ or betas.
-c CONFIG_FILE Specify the path to the buildout configuration file to
be used.
Modified: zc.buildout/trunk/src/zc/buildout/buildout.py
===================================================================
--- zc.buildout/trunk/src/zc/buildout/buildout.py 2010-08-23 14:55:43 UTC (rev 115886)
+++ zc.buildout/trunk/src/zc/buildout/buildout.py 2010-08-23 15:04:24 UTC (rev 115887)
@@ -34,6 +34,7 @@
import sys
import tempfile
import UserDict
+import warnings
import zc.buildout
import zc.buildout.download
import zc.buildout.easy_install
@@ -51,6 +52,9 @@
if is_jython:
import subprocess
+_sys_executable_has_broken_dash_S = (
+ zc.buildout.easy_install._has_broken_dash_S(sys.executable))
+
class MissingOption(zc.buildout.UserError, KeyError):
"""A required option was missing.
"""
@@ -112,6 +116,7 @@
return data
_buildout_default_options = _annotate_section({
+ 'accept-buildout-test-releases': 'false',
'allow-hosts': '*',
'allow-picked-versions': 'true',
'bin-directory': 'bin',
@@ -230,6 +235,8 @@
self._logger = logging.getLogger('zc.buildout')
self.offline = (buildout_section['offline'] == 'true')
self.newest = (buildout_section['newest'] == 'true')
+ self.accept_buildout_test_releases = (
+ buildout_section['accept-buildout-test-releases'] == 'true')
##################################################################
## WARNING!!!
@@ -263,42 +270,26 @@
self._setup_logging()
- offline = options['offline']
- if offline not in ('true', 'false'):
- self._error('Invalid value for offline option: %s', offline)
- self.offline = (offline == 'true')
-
- if self.offline:
- newest = options['newest'] = 'false'
- else:
- newest = options['newest']
- if newest not in ('true', 'false'):
- self._error('Invalid value for newest option: %s', newest)
- self.newest = (newest == 'true')
-
versions = options.get('versions')
if versions:
zc.buildout.easy_install.default_versions(dict(self[versions]))
- prefer_final = options['prefer-final']
- if prefer_final not in ('true', 'false'):
- self._error('Invalid value for prefer-final option: %s',
- prefer_final)
- zc.buildout.easy_install.prefer_final(prefer_final=='true')
- use_dependency_links = options['use-dependency-links']
- if use_dependency_links not in ('true', 'false'):
- self._error('Invalid value for use-dependency-links option: %s',
- use_dependency_links)
+ self.offline = options.get_bool('offline')
+ if self.offline:
+ options['newest'] = 'false'
+ self.newest = options.get_bool('newest')
+ zc.buildout.easy_install.prefer_final(
+ options.get_bool('prefer-final'))
+ self.accept_buildout_test_releases = options.get_bool(
+ 'accept-buildout-test-releases')
zc.buildout.easy_install.use_dependency_links(
- use_dependency_links == 'true')
-
- allow_picked_versions = options['allow-picked-versions']
- if allow_picked_versions not in ('true', 'false'):
- self._error('Invalid value for allow-picked-versions option: %s',
- allow_picked_versions)
+ options.get_bool('use-dependency-links'))
zc.buildout.easy_install.allow_picked_versions(
- allow_picked_versions == 'true')
+ options.get_bool('allow-picked-versions'))
+ zc.buildout.easy_install.install_from_cache(
+ options.get_bool('install-from-cache'))
+ zc.buildout.easy_install.always_unzip(options.get_bool('unzip'))
download_cache = options.get('download-cache')
if download_cache:
@@ -315,19 +306,6 @@
zc.buildout.easy_install.download_cache(download_cache)
- install_from_cache = options['install-from-cache']
- if install_from_cache not in ('true', 'false'):
- self._error('Invalid value for install-from-cache option: %s',
- install_from_cache)
- zc.buildout.easy_install.install_from_cache(
- install_from_cache=='true')
-
- always_unzip = options['unzip']
- if always_unzip not in ('true', 'false'):
- self._error('Invalid value for unzip option: %s',
- always_unzip)
- zc.buildout.easy_install.always_unzip(always_unzip=='true')
-
# "Use" each of the defaults so they aren't reported as unused options.
for name in _buildout_default_options:
options[name]
@@ -359,7 +337,8 @@
distributions, options['executable'],
[options['develop-eggs-directory'],
options['eggs-directory']],
- include_site_packages=False,
+ include_site_packages=_sys_executable_has_broken_dash_S,
+ prefer_final=not self.accept_buildout_test_releases,
)
else:
ws = zc.buildout.easy_install.install(
@@ -370,7 +349,8 @@
path=[options['develop-eggs-directory']],
newest=self.newest,
allow_hosts=self._allow_hosts,
- include_site_packages=False,
+ include_site_packages=_sys_executable_has_broken_dash_S,
+ prefer_final=not self.accept_buildout_test_releases,
)
# Now copy buildout and setuptools eggs, and record destination eggs:
@@ -393,7 +373,9 @@
else:
shutil.copy2(dist.location, dest)
- # Create buildout script
+ # Create buildout script.
+ # Ideally the (possibly) new version of buildout would get a
+ # chance to write the script. Not sure how to do that.
ws = pkg_resources.WorkingSet(entries)
ws.require('zc.buildout')
partsdir = os.path.join(options['parts-directory'], 'buildout')
@@ -406,9 +388,19 @@
else:
assert relative_paths == 'false'
relative_paths = ''
+ if (self.accept_buildout_test_releases and
+ self._annotated['buildout']['accept-buildout-test-releases'][1] ==
+ 'COMMAND_LINE_VALUE'):
+ # Bootstrap was called with '--accept-buildout-test-releases'.
+ # Continue to honor that setting.
+ script_initialization = _early_release_initialization_code
+ else:
+ script_initialization = ''
zc.buildout.easy_install.sitepackage_safe_scripts(
options['bin-directory'], ws, options['executable'], partsdir,
- reqs=['zc.buildout'], relative_paths=relative_paths)
+ reqs=['zc.buildout'], relative_paths=relative_paths,
+ include_site_packages=_sys_executable_has_broken_dash_S,
+ script_initialization=script_initialization,)
init = bootstrap
@@ -422,7 +414,7 @@
# for eggs:
sys.path.insert(0, self['buildout']['develop-eggs-directory'])
- # Check for updates. This could cause the process to be rstarted
+ # Check for updates. This could cause the process to be restarted.
self._maybe_upgrade()
# load installed data
@@ -475,7 +467,7 @@
# compute new part recipe signatures
self._compute_part_signatures(install_parts)
- # uninstall parts that are no-longer used or who's configs
+ # uninstall parts that are no-longer used or whose configs
# have changed
for part in reversed(installed_parts):
if part in install_parts:
@@ -621,11 +613,11 @@
f.close()
def _uninstall_part(self, part, installed_part_options):
- # ununstall part
+ # uninstall part
__doing__ = 'Uninstalling %s.', part
self._logger.info(*__doing__)
- # run uinstall recipe
+ # run uninstall recipe
recipe, entry = _recipe(installed_part_options[part])
try:
uninstaller = _install_and_load(
@@ -854,7 +846,8 @@
index = options.get('index'),
path = [options['develop-eggs-directory']],
allow_hosts = self._allow_hosts,
- include_site_packages=False
+ include_site_packages=_sys_executable_has_broken_dash_S,
+ prefer_final=not self.accept_buildout_test_releases,
)
upgraded = []
@@ -902,15 +895,27 @@
# the new dist is different, so we've upgraded.
# Update the scripts and return True
+ # Ideally the new version of buildout would get a chance to write the
+ # script. Not sure how to do that.
partsdir = os.path.join(options['parts-directory'], 'buildout')
if os.path.exists(partsdir):
# This is primarily for unit tests, in which .py files change too
# fast for Python to know to regenerate the .pyc/.pyo files.
shutil.rmtree(partsdir)
os.mkdir(partsdir)
+ if (self.accept_buildout_test_releases and
+ self._annotated['buildout']['accept-buildout-test-releases'][1] ==
+ 'COMMAND_LINE_VALUE'):
+ # Bootstrap was called with '--accept-buildout-test-releases'.
+ # Continue to honor that setting.
+ script_initialization = _early_release_initialization_code
+ else:
+ script_initialization = ''
zc.buildout.easy_install.sitepackage_safe_scripts(
options['bin-directory'], ws, sys.executable, partsdir,
- reqs=['zc.buildout'])
+ reqs=['zc.buildout'],
+ include_site_packages=_sys_executable_has_broken_dash_S,
+ script_initialization=script_initialization)
# Restart
args = map(zc.buildout.easy_install._safe_arg, sys.argv)
@@ -951,7 +956,8 @@
links = self['buildout'].get('find-links', '').split(),
index = self['buildout'].get('index'),
newest=self.newest, allow_hosts=self._allow_hosts,
- include_site_packages=False)
+ include_site_packages=_sys_executable_has_broken_dash_S,
+ prefer_final=not self.accept_buildout_test_releases)
# Clear cache because extensions might now let us read pages we
# couldn't read before.
@@ -982,6 +988,7 @@
setup = os.path.abspath(setup)
fd, tsetup = tempfile.mkstemp()
+ exe = zc.buildout.easy_install._safe_arg(sys.executable)
try:
os.write(fd, zc.buildout.easy_install.runsetup_template % dict(
setuptools=pkg_resources_loc,
@@ -995,14 +1002,10 @@
for a in args:
arg_list.append(zc.buildout.easy_install._safe_arg(a))
- subprocess.Popen(
- [zc.buildout.easy_install._safe_arg(sys.executable)]
- + list(tsetup)
- + arg_list
- ).wait()
+ subprocess.Popen([exe] + list(tsetup) + arg_list).wait()
else:
- os.spawnl(os.P_WAIT, sys.executable, zc.buildout.easy_install._safe_arg (sys.executable), tsetup,
+ os.spawnl(os.P_WAIT, sys.executable, exe, tsetup,
*[zc.buildout.easy_install._safe_arg(a)
for a in args])
finally:
@@ -1069,8 +1072,8 @@
working_set=pkg_resources.working_set,
newest=buildout.newest,
allow_hosts=buildout._allow_hosts,
- include_site_packages=False,
- )
+ include_site_packages=_sys_executable_has_broken_dash_S,
+ prefer_final=not buildout.accept_buildout_test_releases)
__doing__ = 'Loading %s recipe entry %s:%s.', group, spec, entry
return pkg_resources.load_entry_point(
@@ -1083,6 +1086,7 @@
group, entry, spec, v)
raise
+
class Options(UserDict.DictMixin):
def __init__(self, buildout, section, data):
@@ -1292,6 +1296,32 @@
self.name)
return self._created
+ def query_bool(self, name, default=None):
+ """Given a name, return a boolean value for that name.
+
+ ``default``, if given, should be 'true', 'false', or None.
+ """
+ if default is not None:
+ value = self.setdefault(name, default=default)
+ else:
+ value = self.get(name)
+ if value is None:
+ return value
+ return _convert_bool(name, value)
+
+ def get_bool(self, name):
+ """Given a name, return a boolean value for that name.
+ """
+ return _convert_bool(name, self[name])
+
+
+def _convert_bool(name, value):
+ if value not in ('true', 'false'):
+ raise zc.buildout.UserError(
+ 'Invalid value for %s option: %s' % (name, value))
+ else:
+ return value == 'true'
+
_spacey_nl = re.compile('[ \t\r\f\v]*\n[ \t\r\f\v\n]*'
'|'
'^[ \t\r\f\v]+'
@@ -1514,6 +1544,13 @@
% (section, ' '.join(map(repr, unused)))
)
+_early_release_initialization_code = """\
+sys.argv.insert(1, 'buildout:accept-buildout-test-releases=true')
+print ('NOTE: Accepting early releases of build system packages. Rerun '
+ 'bootstrap without --accept-buildout-test-releases (-t) to return to '
+ 'default behavior.')
+"""
+
_usage = """\
Usage: buildout [options] [assignments] [command [command arguments]]
@@ -1577,6 +1614,11 @@
will be started. This is especially useful for debuging recipe
problems.
+ -s
+
+ Squelch warnings about using an executable with a broken -S
+ implementation.
+
Assignments are of the form: section:option=value and are used to
provide configuration options that override those given in the
configuration file. For example, to run the buildout in offline mode,
@@ -1642,11 +1684,12 @@
windows_restart = False
user_defaults = True
debug = False
+ ignore_broken_dash_s = False
while args:
if args[0][0] == '-':
op = orig_op = args.pop(0)
op = op[1:]
- while op and op[0] in 'vqhWUoOnNDA':
+ while op and op[0] in 'vqhWUoOnNDAs':
if op[0] == 'v':
verbosity += 10
elif op[0] == 'q':
@@ -1665,6 +1708,8 @@
options.append(('buildout', 'newest', 'false'))
elif op[0] == 'D':
debug = True
+ elif op[0] == 's':
+ ignore_broken_dash_s = True
else:
_help()
op = op[1:]
@@ -1708,6 +1753,17 @@
# The rest should be commands, so we'll stop here
break
+ if verbosity < 0 or ignore_broken_dash_s:
+ broken_dash_S_filter_action = 'ignore'
+ elif verbosity == 0: # This is the default.
+ broken_dash_S_filter_action = 'once'
+ else:
+ broken_dash_S_filter_action = 'default'
+ warnings.filterwarnings(
+ broken_dash_S_filter_action,
+ re.escape(
+ zc.buildout.easy_install.BROKEN_DASH_S_WARNING),
+ UserWarning)
if verbosity:
options.append(('buildout', 'verbosity', str(verbosity)))
Modified: zc.buildout/trunk/src/zc/buildout/buildout.txt
===================================================================
--- zc.buildout/trunk/src/zc/buildout/buildout.txt 2010-08-23 14:55:43 UTC (rev 115886)
+++ zc.buildout/trunk/src/zc/buildout/buildout.txt 2010-08-23 15:04:24 UTC (rev 115887)
@@ -729,6 +729,8 @@
==================
<BLANKLINE>
[buildout]
+ accept-buildout-test-releases= false
+ DEFAULT_VALUE
allow-hosts= *
DEFAULT_VALUE
allow-picked-versions= true
@@ -2227,6 +2229,7 @@
<BLANKLINE>
Configuration data:
[buildout]
+ accept-buildout-test-releases = false
allow-hosts = *
allow-picked-versions = true
bin-directory = /sample-buildout/bin
@@ -2484,26 +2487,34 @@
Preferring Final Releases
-------------------------
-Currently, when searching for new releases, the newest available
-release is used. This isn't usually ideal, as you may get a
-development release or alpha releases not ready to be widely used.
-You can request that final releases be preferred using the prefer
-final option in the buildout section::
+Currently, when searching for new releases of your project's
+dependencies, the newest available release is used. This isn't usually
+ideal, as you may get a development release or alpha releases not ready
+to be widely used. You can request that final releases be preferred
+using the ``prefer-final`` option in the buildout section::
[buildout]
...
prefer-final = true
-When the prefer-final option is set to true, then when searching for
+When the ``prefer-final`` option is set to true, then when searching for
new releases, final releases are preferred. If there are final
releases that satisfy distribution requirements, then those releases
-are used even if newer non-final releases are available. The buildout
-prefer-final option can be used to override this behavior.
+are used even if newer non-final releases are available.
-In buildout version 2, final releases will be preferred by default.
-You will then need to use a false value for prefer-final to get the
-newest releases.
+In buildout version 2, all final releases will be preferred by
+default--that is ``prefer-final`` will also default to 'true'. You will
+then need to use a 'false' value for ``prefer-final`` to get the newest
+releases.
+A separate option controls the behavior of the build system itself.
+When buildout looks for recipes, extensions, and for updates to itself,
+it does prefer final releases by default, as of the 1.5.0 release. The
+``accept-buildout-test-releases`` option will let you override this behavior.
+However, it is typically changed by the --accept-buildout-test-releases
+option to the bootstrap script, since bootstrapping is the first step to
+selecting a buildout.
+
Finding distributions
---------------------
Modified: zc.buildout/trunk/src/zc/buildout/debugging.txt
===================================================================
--- zc.buildout/trunk/src/zc/buildout/debugging.txt 2010-08-23 14:55:43 UTC (rev 115886)
+++ zc.buildout/trunk/src/zc/buildout/debugging.txt 2010-08-23 15:04:24 UTC (rev 115887)
@@ -5,12 +5,12 @@
always obvious why. Errors can occur due to problems in user input or
due to bugs in zc.buildout or recipes. When an error occurs, Python's
post-mortem debugger can be used to inspect the state of the buildout
-or recipe code were there error occurred. To enable this, use the -D
+or recipe code where the error occurred. To enable this, use the -D
option to the buildout. Let's create a recipe that has a bug:
>>> mkdir(sample_buildout, 'recipes')
- >>> write(sample_buildout, 'recipes', 'mkdir.py',
+ >>> write(sample_buildout, 'recipes', 'mkdir.py',
... """
... import os, zc.buildout
...
@@ -35,7 +35,7 @@
>>> write(sample_buildout, 'recipes', 'setup.py',
... """
... from setuptools import setup
- ...
+ ...
... setup(name = "recipes",
... entry_points = {'zc.buildout': ['mkdir = mkdir:Mkdir']},
... )
Modified: zc.buildout/trunk/src/zc/buildout/dependencylinks.txt
===================================================================
--- zc.buildout/trunk/src/zc/buildout/dependencylinks.txt 2010-08-23 14:55:43 UTC (rev 115886)
+++ zc.buildout/trunk/src/zc/buildout/dependencylinks.txt 2010-08-23 15:04:24 UTC (rev 115887)
@@ -20,7 +20,7 @@
Turn on logging on this server so that we can see when eggs are pulled
from it.
-
+
>>> get(link_server2 + 'enable_server_logging')
GET 200 /enable_server_logging
''
@@ -83,10 +83,9 @@
... for egg in glob(join(sample_buildout, 'eggs', 'demoneeded*.egg')):
... remove(sample_buildout, 'eggs', egg)
>>> remove_demoneeded_egg()
- >>> print system(buildout)
+ >>> print system(buildout) # doctest: +ELLIPSIS
Develop: '/sample-buildout/depdemo'
- Updating eggs.
- Couldn't find index page for 'demoneeded' (maybe misspelled?)
+ ...
Getting distribution for 'demoneeded'.
While:
Updating eggs.
Modified: zc.buildout/trunk/src/zc/buildout/easy_install.py
===================================================================
--- zc.buildout/trunk/src/zc/buildout/easy_install.py 2010-08-23 14:55:43 UTC (rev 115886)
+++ zc.buildout/trunk/src/zc/buildout/easy_install.py 2010-08-23 15:04:24 UTC (rev 115887)
@@ -33,6 +33,7 @@
import subprocess
import sys
import tempfile
+import warnings
import zc.buildout
import zipimport
@@ -54,11 +55,22 @@
is_distribute = (
pkg_resources.Requirement.parse('setuptools').key=='distribute')
+BROKEN_DASH_S_WARNING = (
+ 'Buildout has been asked to exclude or limit site-packages so that '
+ 'builds can be repeatable when using a system Python. However, '
+ 'the chosen Python executable has a broken implementation of -S (see '
+ 'https://bugs.launchpad.net/virtualenv/+bug/572545 for an example '
+ "problem) and this breaks buildout's ability to isolate site-packages. "
+ "If the executable already has a clean site-packages (e.g., "
+ "using virtualenv's ``--no-site-packages`` option) you may be getting "
+ 'equivalent repeatability. To silence this warning, use the -s argument '
+ 'to the buildout script. Alternatively, use a Python executable with a '
+ 'working -S (such as a standard Python binary).')
+
if is_jython:
import java.lang.System
jython_os_name = (java.lang.System.getProperties()['os.name']).lower()
-
setuptools_loc = pkg_resources.working_set.find(
pkg_resources.Requirement.parse('setuptools')
).location
@@ -71,6 +83,25 @@
if os.path.normpath(setuptools_loc) != os.path.normpath(buildout_loc):
buildout_and_setuptools_path.append(buildout_loc)
+def _has_broken_dash_S(executable):
+ """Detect https://bugs.launchpad.net/virtualenv/+bug/572545 ."""
+ # The first attempt here was to simply have the executable attempt to import
+ # ConfigParser and return the return code. That worked except for tests on
+ # Windows, where the return code was wrong for the fake Python executable
+ # generated by the virtualenv.txt test, apparently because setuptools' .exe
+ # file does not pass the -script.py's returncode back properly, at least in
+ # some circumstances. Therefore...print statements.
+ stdout, stderr = subprocess.Popen(
+ [executable, '-Sc',
+ 'try:\n'
+ ' import ConfigParser\n'
+ 'except ImportError:\n'
+ ' print 1\n'
+ 'else:\n'
+ ' print 0\n'],
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+ return bool(int(stdout.strip()))
+
def _get_system_paths(executable):
"""Return lists of standard lib and site paths for executable.
"""
@@ -124,7 +155,8 @@
return (stdlib, site_paths)
def _get_version_info(executable):
- cmd = [executable, '-Sc', 'import sys; print repr(sys.version_info)']
+ cmd = [executable, '-Sc',
+ 'import sys; print(repr(tuple(x for x in sys.version_info)))']
_proc = subprocess.Popen(
cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = _proc.communicate();
@@ -210,10 +242,10 @@
_safe_arg = str
# The following string is used to run easy_install in
-# Installer._call_easy_install. It is started with python -S (that is,
-# don't import site at start). That flag, and all of the code in this
-# snippet above the last two lines, exist to work around a relatively rare
-# problem. If
+# Installer._call_easy_install. It is usually started with python -S
+# (that is, don't import site at start). That flag, and all of the code
+# in this snippet above the last two lines, exist to work around a
+# relatively rare problem. If
#
# - your buildout configuration is trying to install a package that is within
# a namespace package, and
@@ -239,7 +271,7 @@
# for another description of the problem). Simply starting Python with
# -S addresses the problem in Python 2.4 and 2.5, but Python 2.6's
# distutils imports a value from the site module, so we unfortunately
-# have to do more drastic surgery in the _easy_install_cmd code below.
+# have to do more drastic surgery in the _easy_install_preface code below.
#
# Here's an example of the .pth files created by setuptools when using that
# flag:
@@ -265,17 +297,16 @@
# unnecessary for site.py to preprocess these packages, so it should be
# fine, as far as can be guessed as of this writing.) Finally, it
# imports easy_install and runs it.
-
-_easy_install_cmd = _safe_arg('''\
+_easy_install_preface = '''\
import sys,os;\
p = sys.path[:];\
import site;\
sys.path[:] = p;\
[sys.modules.pop(k) for k, v in sys.modules.items()\
if hasattr(v, '__path__') and len(v.__path__)==1 and\
- not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))];\
-from setuptools.command.easy_install import main;\
-main()''')
+ not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))];'''
+_easy_install_cmd = (
+ 'from setuptools.command.easy_install import main;main()')
class Installer:
@@ -302,7 +333,8 @@
use_dependency_links=None,
allow_hosts=('*',),
include_site_packages=None,
- allowed_eggs_from_site_packages=None
+ allowed_eggs_from_site_packages=None,
+ prefer_final=None,
):
self._dest = dest
self._allow_hosts = allow_hosts
@@ -316,12 +348,15 @@
if use_dependency_links is not None:
self._use_dependency_links = use_dependency_links
+ if prefer_final is not None:
+ self._prefer_final = prefer_final
self._links = links = list(_fix_file_links(links))
if self._download_cache and (self._download_cache not in links):
links.insert(0, self._download_cache)
self._index_url = index
self._executable = executable
+ self._has_broken_dash_S = _has_broken_dash_S(self._executable)
if always_unzip is not None:
self._always_unzip = always_unzip
path = (path and path[:] or [])
@@ -330,6 +365,17 @@
if allowed_eggs_from_site_packages is not None:
self._allowed_eggs_from_site_packages = tuple(
allowed_eggs_from_site_packages)
+ if self._has_broken_dash_S:
+ if (not self._include_site_packages or
+ self._allowed_eggs_from_site_packages != ('*',)):
+ # We can't do this if the executable has a broken -S.
+ warnings.warn(BROKEN_DASH_S_WARNING)
+ self._include_site_packages = True
+ self._allowed_eggs_from_site_packages = ('*',)
+ self._easy_install_cmd = _easy_install_cmd
+ else:
+ self._easy_install_cmd = _easy_install_preface + _easy_install_cmd
+ self._easy_install_cmd = _safe_arg(self._easy_install_cmd)
stdlib, self._site_packages = _get_system_paths(executable)
version_info = _get_version_info(executable)
if version_info == sys.version_info:
@@ -488,7 +534,9 @@
try:
path = setuptools_loc
- args = ('-Sc', _easy_install_cmd, '-mUNxd', _safe_arg(tmp))
+ args = ('-c', self._easy_install_cmd, '-mUNxd', _safe_arg(tmp))
+ if not self._has_broken_dash_S:
+ args = ('-S',) + args
if self._always_unzip:
args += ('-Z', )
level = logger.getEffectiveLevel()
@@ -785,7 +833,7 @@
def _maybe_add_setuptools(self, ws, dist):
if dist.has_metadata('namespace_packages.txt'):
for r in dist.requires():
- if r.project_name == 'setuptools':
+ if r.project_name in ('setuptools', 'distribute'):
break
else:
# We have a namespace package but no requirement for setuptools
@@ -873,7 +921,13 @@
dist = best[req.key] = env.best_match(req, ws)
except pkg_resources.VersionConflict, err:
raise VersionConflict(err, ws)
- if dist is None:
+ if dist is None or (
+ dist.location in self._site_packages and not
+ self.allow_site_package_egg(dist.project_name)):
+ # If we didn't find a distribution in the
+ # environment, or what we found is from site
+ # packages and not allowed to be there, try
+ # again.
if destination:
logger.debug('Getting required %r', str(req))
else:
@@ -1020,13 +1074,14 @@
executable=sys.executable, always_unzip=None,
path=None, working_set=None, newest=True, versions=None,
use_dependency_links=None, allow_hosts=('*',),
- include_site_packages=None, allowed_eggs_from_site_packages=None):
- installer = Installer(dest, links, index, executable, always_unzip, path,
- newest, versions, use_dependency_links,
- allow_hosts=allow_hosts,
- include_site_packages=include_site_packages,
- allowed_eggs_from_site_packages=
- allowed_eggs_from_site_packages)
+ include_site_packages=None, allowed_eggs_from_site_packages=None,
+ prefer_final=None):
+ installer = Installer(
+ dest, links, index, executable, always_unzip, path, newest,
+ versions, use_dependency_links, allow_hosts=allow_hosts,
+ include_site_packages=include_site_packages,
+ allowed_eggs_from_site_packages=allowed_eggs_from_site_packages,
+ prefer_final=prefer_final)
return installer.install(specs, working_set)
@@ -1035,11 +1090,11 @@
executable=sys.executable,
path=None, newest=True, versions=None, allow_hosts=('*',),
include_site_packages=None, allowed_eggs_from_site_packages=None):
- installer = Installer(dest, links, index, executable, True, path, newest,
- versions, allow_hosts=allow_hosts,
- include_site_packages=include_site_packages,
- allowed_eggs_from_site_packages=
- allowed_eggs_from_site_packages)
+ installer = Installer(
+ dest, links, index, executable, True, path, newest, versions,
+ allow_hosts=allow_hosts,
+ include_site_packages=include_site_packages,
+ allowed_eggs_from_site_packages=allowed_eggs_from_site_packages)
return installer.build(spec, build_ext)
@@ -1135,23 +1190,25 @@
[f() for f in undo]
def working_set(specs, executable, path, include_site_packages=None,
- allowed_eggs_from_site_packages=None):
+ allowed_eggs_from_site_packages=None, prefer_final=None):
return install(
specs, None, executable=executable, path=path,
include_site_packages=include_site_packages,
- allowed_eggs_from_site_packages=allowed_eggs_from_site_packages)
+ allowed_eggs_from_site_packages=allowed_eggs_from_site_packages,
+ prefer_final=prefer_final)
############################################################################
# Script generation functions
-def scripts(reqs, working_set, executable, dest,
- scripts=None,
- extra_paths=(),
- arguments='',
- interpreter=None,
- initialization='',
- relative_paths=False,
- ):
+def scripts(
+ reqs, working_set, executable, dest,
+ scripts=None,
+ extra_paths=(),
+ arguments='',
+ interpreter=None,
+ initialization='',
+ relative_paths=False,
+ ):
"""Generate scripts and/or an interpreter.
See sitepackage_safe_scripts for a version that can be used with a Python
@@ -1171,11 +1228,24 @@
_pyscript(spath, sname, executable, rpsetup))
return generated
+# We need to give an alternate name to the ``scripts`` function so that it
+# can be referenced within sitepackage_safe_scripts, which uses ``scripts``
+# as an argument name.
+_original_scripts_function = scripts
+
def sitepackage_safe_scripts(
dest, working_set, executable, site_py_dest,
- reqs=(), scripts=None, interpreter=None, extra_paths=(),
- initialization='', include_site_packages=False, exec_sitecustomize=False,
- relative_paths=False, script_arguments='', script_initialization=''):
+ reqs=(),
+ scripts=None,
+ interpreter=None,
+ extra_paths=(),
+ initialization='',
+ include_site_packages=False,
+ exec_sitecustomize=False,
+ relative_paths=False,
+ script_arguments='',
+ script_initialization='',
+ ):
"""Generate scripts and/or an interpreter from a system Python.
This accomplishes the same job as the ``scripts`` function, above,
@@ -1183,6 +1253,12 @@
Python site packages, if desired, and choosing to execute the Python's
sitecustomize.
"""
+ if _has_broken_dash_S(executable):
+ if not include_site_packages:
+ warnings.warn(BROKEN_DASH_S_WARNING)
+ return _original_scripts_function(
+ reqs, working_set, executable, dest, scripts, extra_paths,
+ script_arguments, interpreter, initialization, relative_paths)
generated = []
generated.append(_generate_sitecustomize(
site_py_dest, executable, initialization, exec_sitecustomize))
@@ -1491,7 +1567,7 @@
cmd = [executable, "-Sc",
"import imp; "
"fp, path, desc = imp.find_module(%r); "
- "fp.close; "
+ "fp.close(); "
"print path" % (name,)]
env = os.environ.copy()
# We need to make sure that PYTHONPATH, which will often be set to
@@ -1548,15 +1624,15 @@
"""
path = _get_path(working_set, extra_paths)
site_path = os.path.join(dest, 'site.py')
- egg_path_string, preamble = _relative_path_and_setup(
- site_path, path, relative_paths, indent_level=2, omit_os_import=True)
- if preamble:
- preamble = '\n'.join(
- [(line and ' %s' % (line,) or line)
- for line in preamble.split('\n')])
- original_path_setup = ''
+ original_path_setup = preamble = ''
if include_site_packages:
stdlib, site_paths = _get_system_paths(executable)
+ # We want to make sure that paths from site-packages, such as those
+ # allowed by allowed_eggs_from_site_packages, always come last, or
+ # else site-packages paths may include packages that mask the eggs we
+ # really want.
+ path = [p for p in path if p not in site_paths]
+ # Now we set up the code we need.
original_path_setup = original_path_snippet % (
_format_paths((repr(p) for p in site_paths), 2),)
distribution = working_set.find(
@@ -1570,10 +1646,19 @@
relative_paths)
else:
location = repr(distribution.location)
- preamble += namespace_include_site_packages_setup % (location,)
+ preamble = namespace_include_site_packages_setup % (location,)
original_path_setup = (
addsitedir_namespace_originalpackages_snippet +
original_path_setup)
+ else:
+ preamble = '\n setuptools_path = None'
+ egg_path_string, relative_preamble = _relative_path_and_setup(
+ site_path, path, relative_paths, indent_level=2, omit_os_import=True)
+ if relative_preamble:
+ relative_preamble = '\n'.join(
+ [(line and ' %s' % (line,) or line)
+ for line in relative_preamble.split('\n')])
+ preamble = relative_preamble + preamble
addsitepackages_marker = 'def addsitepackages('
enableusersite_marker = 'ENABLE_USER_SITE = '
successful_rewrite = False
@@ -1616,7 +1701,8 @@
%s
]
for path in original_paths:
- addsitedir(path, known_paths)'''
+ if path == setuptools_path or path not in known_paths:
+ addsitedir(path, known_paths)'''
addsitepackages_script = '''\
def addsitepackages(known_paths):
Modified: zc.buildout/trunk/src/zc/buildout/easy_install.txt
===================================================================
--- zc.buildout/trunk/src/zc/buildout/easy_install.txt 2010-08-23 14:55:43 UTC (rev 115886)
+++ zc.buildout/trunk/src/zc/buildout/easy_install.txt 2010-08-23 15:04:24 UTC (rev 115887)
@@ -1277,6 +1277,7 @@
"""Add site packages, as determined by zc.buildout.
<BLANKLINE>
See original_addsitepackages, below, for the original version."""
+ setuptools_path = None
buildout_paths = [
'/interpreter/eggs/demo-0.3-pyN.N.egg',
'/interpreter/eggs/demoneeded-1.1-pyN.N.egg'
@@ -1291,7 +1292,8 @@
...
]
for path in original_paths:
- addsitedir(path, known_paths)
+ if path == setuptools_path or path not in known_paths:
+ addsitedir(path, known_paths)
return known_paths
<BLANKLINE>
def original_addsitepackages(known_paths):...
@@ -1368,7 +1370,8 @@
...
]
for path in original_paths:
- addsitedir(path, known_paths)
+ if path == setuptools_path or path not in known_paths:
+ addsitedir(path, known_paths)
return known_paths
<BLANKLINE>
def original_addsitepackages(known_paths):...
@@ -1432,7 +1435,8 @@
...
]
for path in original_paths:
- addsitedir(path, known_paths)
+ if path == setuptools_path or path not in known_paths:
+ addsitedir(path, known_paths)
return known_paths
<BLANKLINE>
def original_addsitepackages(known_paths):...
Modified: zc.buildout/trunk/src/zc/buildout/testing.py
===================================================================
--- zc.buildout/trunk/src/zc/buildout/testing.py 2010-08-23 14:55:43 UTC (rev 115886)
+++ zc.buildout/trunk/src/zc/buildout/testing.py 2010-08-23 15:04:24 UTC (rev 115887)
@@ -596,7 +596,7 @@
sep = re.escape(os.path.sep)
normalize_path = (
re.compile(
- r'''[^'" \t\n\r]+%(sep)s_[Tt][Ee][Ss][Tt]_%(sep)s([^"' \t\n\r]+)'''
+ r'''[^'" \t\n\r!]+%(sep)s_[Tt][Ee][Ss][Tt]_%(sep)s([^"' \t\n\r]+)'''
% dict(sep=sep)),
_normalize_path,
)
Modified: zc.buildout/trunk/src/zc/buildout/testing_bugfix.txt
===================================================================
--- zc.buildout/trunk/src/zc/buildout/testing_bugfix.txt 2010-08-23 14:55:43 UTC (rev 115886)
+++ zc.buildout/trunk/src/zc/buildout/testing_bugfix.txt 2010-08-23 15:04:24 UTC (rev 115887)
@@ -15,7 +15,7 @@
>>> len(logging.getLogger().handlers)
1
>>> logging.getLogger().handlers # doctest: +ELLIPSIS
- [<zope.testrunner.logsupport.NullHandler instance at ...>]
+ [<zope...testrunner.logsupport.NullHandler instance at ...>]
After calling it, a ``logging.StreamHandler`` was added:
@@ -27,7 +27,7 @@
>>> len(logging.getLogger().handlers)
2
>>> logging.getLogger().handlers # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
- [<zope.testrunner.logsupport.NullHandler instance at ...>,
+ [<zope...testrunner.logsupport.NullHandler instance at ...>,
<logging.StreamHandler instance at ...>]
But tear down removes the new logging handler:
@@ -36,4 +36,4 @@
>>> len(logging.getLogger().handlers)
1
>>> logging.getLogger().handlers # doctest: +ELLIPSIS
- [<zope.testrunner.logsupport.NullHandler instance at ...>]
+ [<zope...testrunner.logsupport.NullHandler instance at ...>]
Modified: zc.buildout/trunk/src/zc/buildout/tests.py
===================================================================
--- zc.buildout/trunk/src/zc/buildout/tests.py 2010-08-23 14:55:43 UTC (rev 115886)
+++ zc.buildout/trunk/src/zc/buildout/tests.py 2010-08-23 15:04:24 UTC (rev 115887)
@@ -2255,6 +2255,75 @@
"""
+def allowed_eggs_from_site_packages_dependencies_bugfix():
+ """
+If you specify that a package with a dependency may come from site-packages,
+that doesn't mean that the dependency may come from site-packages. This
+is a test for a bug fix to verify that this is true.
+
+ >>> py_path, site_packages_path = make_py()
+ >>> create_sample_sys_install(site_packages_path)
+ >>> interpreter_dir = tmpdir('interpreter')
+ >>> interpreter_parts_dir = os.path.join(
+ ... interpreter_dir, 'parts', 'interpreter')
+ >>> interpreter_bin_dir = os.path.join(interpreter_dir, 'bin')
+ >>> mkdir(interpreter_bin_dir)
+ >>> mkdir(interpreter_dir, 'eggs')
+ >>> mkdir(interpreter_dir, 'parts')
+ >>> mkdir(interpreter_parts_dir)
+ >>> ws = zc.buildout.easy_install.install(
+ ... ['demo'], join(interpreter_dir, 'eggs'), executable=py_path,
+ ... links=[link_server], index=link_server+'index/',
+ ... allowed_eggs_from_site_packages=['demo'])
+ >>> [dist.project_name for dist in ws]
+ ['demo', 'demoneeded']
+ >>> from pprint import pprint
+ >>> pprint([dist.location for dist in ws])
+ ['/executable_buildout/site-packages',
+ '/interpreter/eggs/demoneeded-1.1-pyN.N.egg']
+
+ """
+
+def allowed_eggs_from_site_packages_bug_592524():
+ """
+When we use allowed_eggs_from_site_packages, we need to make sure that the
+site-packages paths are not inserted with the normal egg paths. They already
+included at the end, and including them along with the normal egg paths will
+possibly mask subsequent egg paths. This affects interpreters and scripts
+generated by sitepackage_safe_scripts.
+
+Our "py_path" has the "demoneeded" and "demo" packages available.
+
+ >>> py_path, site_packages_path = make_py()
+ >>> create_sample_sys_install(site_packages_path)
+ >>> interpreter_dir = tmpdir('interpreter')
+ >>> interpreter_parts_dir = os.path.join(
+ ... interpreter_dir, 'parts', 'interpreter')
+ >>> interpreter_bin_dir = os.path.join(interpreter_dir, 'bin')
+ >>> mkdir(interpreter_bin_dir)
+ >>> mkdir(interpreter_dir, 'eggs')
+ >>> mkdir(interpreter_dir, 'parts')
+ >>> mkdir(interpreter_parts_dir)
+ >>> ws = zc.buildout.easy_install.install(
+ ... ['demo', 'other'], join(interpreter_dir, 'eggs'), executable=py_path,
+ ... links=[link_server], index=link_server+'index/',
+ ... allowed_eggs_from_site_packages=['demo'])
+ >>> generated = zc.buildout.easy_install.sitepackage_safe_scripts(
+ ... interpreter_bin_dir, ws, py_path, interpreter_parts_dir,
+ ... interpreter='py', include_site_packages=True)
+
+Now we will look at the paths in the site.py we generated. Notice that the
+site-packages are at the end. They were not before this bugfix.
+
+ >>> test = 'import pprint, sys; pprint.pprint(sys.path[-4:])'
+ >>> print call_py(join(interpreter_bin_dir, 'py'), test)
+ ['/interpreter/eggs/other-1.0-pyN.N.egg',
+ '/interpreter/eggs/demoneeded-1.1-pyN.N.egg',
+ '/executable_buildout/eggs/setuptools-0.0-pyN.N.egg',
+ '/executable_buildout/site-packages']
+ <BLANKLINE>
+ """
+
def subprocesses_have_same_environment_by_default():
"""
The scripts generated by sitepackage_safe_scripts set the PYTHONPATH so that,
@@ -3057,6 +3126,107 @@
"""
+def buildout_prefer_final_build_system_option():
+ """
+The accept-buildout-test-releases buildout option can be used for overriding
+the default preference for final distributions for recipes, buildout
+extensions, and buildout itself. It is usually controlled via the bootstrap
+script rather than in the configuration file, but we will test the machinery
+using the file.
+
+Set up. This creates sdists for demorecipe 1.0 and 1.1b1, and for
+demoextension 1.0 and 1.1b1.
+
+ >>> create_sample_recipe_sdists(sample_eggs)
+ >>> create_sample_extension_sdists(sample_eggs)
+
+The default is accept-buildout-test-releases = false:
+
+ >>> write('buildout.cfg',
+ ... '''
+ ... [buildout]
+ ... parts = demo
+ ... find-links = %(link_server)s
+ ... extensions = demoextension
+ ...
+ ... [demo]
+ ... recipe = demorecipe
+ ... ''' % globals())
+
+ >>> print system(buildout+' -v'), # doctest: +ELLIPSIS
+ Installing ...
+ Picked: demoextension = 1.0
+ ...
+ Picked: demorecipe = 1.0
+ ...
+
+Here we see that the final versions of demorecipe and demoextension were used.
+
+We get the same behavior if we explicitly state that
+accept-buildout-test-releases = false.
+
+ >>> write('buildout.cfg',
+ ... '''
+ ... [buildout]
+ ... parts = demo
+ ... find-links = %(link_server)s
+ ... extensions = demoextension
+ ... accept-buildout-test-releases = false
+ ...
+ ... [demo]
+ ... recipe = demorecipe
+ ... ''' % globals())
+
+ >>> print system(buildout+' -v'), # doctest: +ELLIPSIS
+ Installing ...
+ Picked: demoextension = 1.0
+ ...
+ Picked: demorecipe = 1.0
+ ...
+
+If we specify accept-buildout-test-releases = true, we'll get the newest
+distributions in the build system:
+
+ >>> write('buildout.cfg',
+ ... '''
+ ... [buildout]
+ ... parts = demo
+ ... find-links = %(link_server)s
+ ... extensions = demoextension
+ ... accept-buildout-test-releases = true
+ ...
+ ... [demo]
+ ... recipe = demorecipe
+ ... ''' % globals())
+
+ >>> print system(buildout+' -v'), # doctest: +ELLIPSIS
+ Installing ...
+ Picked: demoextension = 1.1b1
+ ...
+ Picked: demorecipe = 1.1b1
+ ...
+
+We get an error if we specify anything but true or false:
+
+ >>> write('buildout.cfg',
+ ... '''
+ ... [buildout]
+ ... parts = demo
+ ... find-links = %(link_server)s
+ ... extensions = demoextension
+ ... accept-buildout-test-releases = no
+ ...
+ ... [demo]
+ ... recipe = demorecipe
+ ... ''' % globals())
+
+ >>> print system(buildout+' -v'), # doctest: +ELLIPSIS
+ While:
+ Initializing.
+ Error: Invalid value for accept-buildout-test-releases option: no
+
+ """
+
def develop_with_modules():
"""
Distribution setup scripts can import modules in the distribution directory:
@@ -3423,6 +3593,68 @@
finally:
shutil.rmtree(tmp)
+def create_sample_extension_sdists(dest):
+ from zc.buildout.testing import write, mkdir
+ name = 'demoextension'
+ for version in ('1.0', '1.1b1'):
+ tmp = tempfile.mkdtemp()
+ try:
+ write(tmp, 'README.txt', '')
+ write(tmp, name + '.py',
+ "def ext(buildout):\n"
+ " pass\n"
+ "def unload(buildout):\n"
+ " pass\n"
+ % locals())
+ write(tmp, 'setup.py',
+ "from setuptools import setup\n"
+ "setup(\n"
+ " name = %(name)r,\n"
+ " py_modules = [%(name)r],\n"
+ " entry_points = {\n"
+ " 'zc.buildout.extension': "
+ "['ext = %(name)s:ext'],\n"
+ " 'zc.buildout.unloadextension': "
+ "['ext = %(name)s:unload'],\n"
+ " },\n"
+ " zip_safe=True, version=%(version)r,\n"
+ " author='bob', url='bob', author_email='bob')\n"
+ % locals())
+ zc.buildout.testing.sdist(tmp, dest)
+ finally:
+ shutil.rmtree(tmp)
+
+def create_sample_recipe_sdists(dest):
+ from zc.buildout.testing import write, mkdir
+ name = 'demorecipe'
+ for version in ('1.0', '1.1b1'):
+ tmp = tempfile.mkdtemp()
+ try:
+ write(tmp, 'README.txt', '')
+ write(tmp, name + '.py',
+ "import logging, os, zc.buildout\n"
+ "class Demorecipe:\n"
+ " def __init__(self, buildout, name, options):\n"
+ " self.name, self.options = name, options\n"
+ " def install(self):\n"
+ " return ()\n"
+ " def update(self):\n"
+ " pass\n"
+ % locals())
+ write(tmp, 'setup.py',
+ "from setuptools import setup\n"
+ "setup(\n"
+ " name = %(name)r,\n"
+ " py_modules = [%(name)r],\n"
+ " entry_points = {'zc.buildout': "
+ "['default = %(name)s:Demorecipe']},\n"
+ " zip_safe=True, version=%(version)r,\n"
+ " author='bob', url='bob', author_email='bob')\n"
+ % locals())
+ zc.buildout.testing.sdist(tmp, dest)
+ finally:
+ shutil.rmtree(tmp)
+
def _write_eggrecipedemoneeded(tmp, minor_version, suffix=''):
from zc.buildout.testing import write
write(tmp, 'README.txt', '')
@@ -3570,37 +3802,33 @@
egg_parse = re.compile('([0-9a-zA-Z_.]+)-([0-9a-zA-Z_.]+)-py(\d[.]\d).egg$'
).match
-def makeNewRelease(project, ws, dest):
+def makeNewRelease(project, ws, dest, version='99.99'):
dist = ws.find(pkg_resources.Requirement.parse(project))
eggname, oldver, pyver = egg_parse(
os.path.basename(dist.location)
).groups()
- dest = os.path.join(dest, "%s-99.99-py%s.egg" % (eggname, pyver))
+ dest = os.path.join(dest, "%s-%s-py%s.egg" % (eggname, version, pyver))
if os.path.isfile(dist.location):
shutil.copy(dist.location, dest)
zip = zipfile.ZipFile(dest, 'a')
zip.writestr(
'EGG-INFO/PKG-INFO',
zip.read('EGG-INFO/PKG-INFO').replace("Version: %s" % oldver,
- "Version: 99.99")
+ "Version: %s" % version)
)
zip.close()
else:
shutil.copytree(dist.location, dest)
info_path = os.path.join(dest, 'EGG-INFO', 'PKG-INFO')
info = open(info_path).read().replace("Version: %s" % oldver,
- "Version: 99.99")
+ "Version: %s" % version)
open(info_path, 'w').write(info)
-
-def updateSetup(test):
- zc.buildout.testing.buildoutSetUp(test)
- new_releases = test.globs['tmpdir']('new_releases')
- test.globs['new_releases'] = new_releases
+def getWorkingSetWithBuildoutEgg(test):
sample_buildout = test.globs['sample_buildout']
eggs = os.path.join(sample_buildout, 'eggs')
- # If the zc.buildout dist is a develo dist, convert it to a
+ # If the zc.buildout dist is a develop dist, convert it to a
# regular egg in the sample buildout
req = pkg_resources.Requirement.parse('zc.buildout')
dist = pkg_resources.working_set.find(req)
@@ -3630,9 +3858,16 @@
os.path.join(sample_buildout, 'bin'))
else:
ws = pkg_resources.working_set
+ return ws
+def updateSetup(test):
+ zc.buildout.testing.buildoutSetUp(test)
+ new_releases = test.globs['tmpdir']('new_releases')
+ test.globs['new_releases'] = new_releases
+ ws = getWorkingSetWithBuildoutEgg(test)
# now let's make the new releases
makeNewRelease('zc.buildout', ws, new_releases)
+ makeNewRelease('zc.buildout', ws, new_releases, '100.0b1')
os.mkdir(os.path.join(new_releases, 'zc.buildout'))
if zc.buildout.easy_install.is_distribute:
makeNewRelease('distribute', ws, new_releases)
@@ -3641,6 +3876,13 @@
makeNewRelease('setuptools', ws, new_releases)
os.mkdir(os.path.join(new_releases, 'setuptools'))
+def bootstrapSetup(test):
+ easy_install_SetUp(test)
+ sample_eggs = test.globs['sample_eggs']
+ ws = getWorkingSetWithBuildoutEgg(test)
+ makeNewRelease('zc.buildout', ws, sample_eggs)
+ makeNewRelease('zc.buildout', ws, sample_eggs, '100.0b1')
+ os.environ['bootstrap-testing-find-links'] = test.globs['link_server']
normalize_bang = (
re.compile(re.escape('#!'+
@@ -3648,6 +3890,19 @@
'#!/usr/local/bin/python2.4',
)
+hide_distribute_additions = (re.compile('install_dir .+\n'), '')
+hide_zip_safe_message = (
+ # This comes in a different place in the output in Python 2.7. It's not
+ # important to our tests. Hide it.
+ re.compile(
+ '((?<=\n)\n)?zip_safe flag not set; analyzing archive contents...\n'),
+ '')
+hide_first_index_page_message = (
+ # This comes in a different place in the output in Python 2.7. It's not
+ # important to our tests. Hide it.
+ re.compile(
+ "Couldn't find index page for '[^']+' \(maybe misspelled\?\)\n"),
+ '')
def test_suite():
test_suite = [
doctest.DocFileSuite(
@@ -3655,44 +3910,47 @@
setUp=zc.buildout.testing.buildoutSetUp,
tearDown=zc.buildout.testing.buildoutTearDown,
checker=renormalizing.RENormalizing([
- zc.buildout.testing.normalize_path,
- zc.buildout.testing.normalize_endings,
- zc.buildout.testing.normalize_script,
- zc.buildout.testing.normalize_egg_py,
- (re.compile('__buildout_signature__ = recipes-\S+'),
- '__buildout_signature__ = recipes-SSSSSSSSSSS'),
- (re.compile('executable = [\S ]+python\S*', re.I),
- 'executable = python'),
- (re.compile('[-d] (setuptools|distribute)-\S+[.]egg'),
- 'setuptools.egg'),
- (re.compile('zc.buildout(-\S+)?[.]egg(-link)?'),
- 'zc.buildout.egg'),
- (re.compile('creating \S*setup.cfg'), 'creating setup.cfg'),
- (re.compile('hello\%ssetup' % os.path.sep), 'hello/setup'),
- (re.compile('Picked: (\S+) = \S+'),
- 'Picked: \\1 = V.V'),
- (re.compile(r'We have a develop egg: zc.buildout (\S+)'),
- 'We have a develop egg: zc.buildout X.X.'),
- (re.compile(r'\\[\\]?'), '/'),
- (re.compile('WindowsError'), 'OSError'),
- (re.compile(r'\[Error \d+\] Cannot create a file '
- r'when that file already exists: '),
- '[Errno 17] File exists: '
- ),
- (re.compile('distribute'), 'setuptools'),
- ])
+ zc.buildout.testing.normalize_path,
+ zc.buildout.testing.normalize_endings,
+ zc.buildout.testing.normalize_script,
+ zc.buildout.testing.normalize_egg_py,
+ zc.buildout.tests.hide_distribute_additions,
+ hide_zip_safe_message,
+ (re.compile('__buildout_signature__ = recipes-\S+'),
+ '__buildout_signature__ = recipes-SSSSSSSSSSS'),
+ (re.compile('executable = [\S ]+python\S*', re.I),
+ 'executable = python'),
+ (re.compile('[-d] (setuptools|distribute)-\S+[.]egg'),
+ 'setuptools.egg'),
+ (re.compile('zc.buildout(-\S+)?[.]egg(-link)?'),
+ 'zc.buildout.egg'),
+ (re.compile('creating \S*setup.cfg'), 'creating setup.cfg'),
+ (re.compile('hello\%ssetup' % os.path.sep), 'hello/setup'),
+ (re.compile('Picked: (\S+) = \S+'),
+ 'Picked: \\1 = V.V'),
+ (re.compile(r'We have a develop egg: zc.buildout (\S+)'),
+ 'We have a develop egg: zc.buildout X.X.'),
+ (re.compile(r'\\[\\]?'), '/'),
+ (re.compile('WindowsError'), 'OSError'),
+ (re.compile(r'\[Error \d+\] Cannot create a file '
+ r'when that file already exists: '),
+ '[Errno 17] File exists: '
+ ),
+ (re.compile('distribute'), 'setuptools'),
+ ])
),
doctest.DocFileSuite(
'debugging.txt',
setUp=zc.buildout.testing.buildoutSetUp,
tearDown=zc.buildout.testing.buildoutTearDown,
checker=renormalizing.RENormalizing([
- zc.buildout.testing.normalize_path,
- zc.buildout.testing.normalize_endings,
- (re.compile(r'\S+buildout.py'), 'buildout.py'),
- (re.compile(r'line \d+'), 'line NNN'),
- (re.compile(r'py\(\d+\)'), 'py(NNN)'),
- ])
+ zc.buildout.testing.normalize_path,
+ zc.buildout.testing.normalize_endings,
+ zc.buildout.tests.hide_distribute_additions,
+ (re.compile(r'\S+buildout.py'), 'buildout.py'),
+ (re.compile(r'line \d+'), 'line NNN'),
+ (re.compile(r'py\(\d+\)'), 'py(NNN)'),
+ ])
),
doctest.DocFileSuite(
@@ -3700,28 +3958,29 @@
setUp=updateSetup,
tearDown=zc.buildout.testing.buildoutTearDown,
checker=renormalizing.RENormalizing([
- zc.buildout.testing.normalize_path,
- zc.buildout.testing.normalize_endings,
- zc.buildout.testing.normalize_script,
- zc.buildout.testing.normalize_egg_py,
- normalize_bang,
- (re.compile('99[.]99'), 'NINETYNINE.NINETYNINE'),
- (re.compile('(zc.buildout|setuptools)-\d+[.]\d+\S*'
- '-py\d.\d.egg'),
- '\\1.egg'),
- (re.compile('distribute-\d+[.]\d+\S*'
- '-py\d.\d.egg'),
- 'setuptools.egg'),
- (re.compile('(zc.buildout|setuptools)( version)? \d+[.]\d+\S*'),
- '\\1 V.V'),
- (re.compile('distribute( version)? \d+[.]\d+\S*'),
- 'setuptools V.V'),
- (re.compile('[-d] (setuptools|distribute)'), '- setuptools'),
- (re.compile('distribute'), 'setuptools'),
- (re.compile("\nUnused options for buildout: "
- "'(distribute|setuptools)\-version'\."),
- '')
- ])
+ zc.buildout.testing.normalize_path,
+ zc.buildout.testing.normalize_endings,
+ zc.buildout.testing.normalize_script,
+ zc.buildout.testing.normalize_egg_py,
+ normalize_bang,
+ zc.buildout.tests.hide_distribute_additions,
+ (re.compile('99[.]99'), 'NINETYNINE.NINETYNINE'),
+ (re.compile('(zc.buildout|setuptools)-\d+[.]\d+\S*'
+ '-py\d.\d.egg'),
+ '\\1.egg'),
+ (re.compile('distribute-\d+[.]\d+\S*'
+ '-py\d.\d.egg'),
+ 'setuptools.egg'),
+ (re.compile('(zc.buildout|setuptools)( version)? \d+[.]\d+\S*'),
+ '\\1 V.V'),
+ (re.compile('distribute( version)? \d+[.]\d+\S*'),
+ 'setuptools V.V'),
+ (re.compile('[-d] (setuptools|distribute)'), '- setuptools'),
+ (re.compile('distribute'), 'setuptools'),
+ (re.compile("\nUnused options for buildout: "
+ "'(distribute|setuptools)\-version'\."),
+ '')
+ ])
),
doctest.DocFileSuite(
@@ -3730,28 +3989,30 @@
setUp=easy_install_SetUp,
tearDown=zc.buildout.testing.buildoutTearDown,
checker=renormalizing.RENormalizing([
- zc.buildout.testing.normalize_path,
- zc.buildout.testing.normalize_endings,
- zc.buildout.testing.normalize_script,
- zc.buildout.testing.normalize_egg_py,
- normalize_bang,
- (re.compile('extdemo[.]pyd'), 'extdemo.so'),
- (re.compile('[-d] (setuptools|distribute)-\S+[.]egg'),
- 'setuptools.egg'),
- (re.compile(r'\\[\\]?'), '/'),
- (re.compile(r'\#!\S+\bpython\S*'), '#!/usr/bin/python'),
- # Normalize generate_script's Windows interpreter to UNIX:
- (re.compile(r'\nimport subprocess\n'), '\n'),
- (re.compile('subprocess\\.call\\(argv, env=environ\\)'),
- 'os.execve(sys.executable, argv, environ)'),
- (re.compile('distribute'), 'setuptools'),
- # Distribute unzips eggs by default.
- (re.compile('\- demoneeded'), 'd demoneeded'),
- ]+(sys.version_info < (2, 5) and [
- (re.compile('.*No module named runpy.*', re.S), ''),
- (re.compile('.*usage: pdb.py scriptfile .*', re.S), ''),
- (re.compile('.*Error: what does not exist.*', re.S), ''),
- ] or [])),
+ zc.buildout.testing.normalize_path,
+ zc.buildout.testing.normalize_endings,
+ zc.buildout.testing.normalize_script,
+ zc.buildout.testing.normalize_egg_py,
+ normalize_bang,
+ hide_first_index_page_message,
+ zc.buildout.tests.hide_distribute_additions,
+ (re.compile('extdemo[.]pyd'), 'extdemo.so'),
+ (re.compile('[-d] (setuptools|distribute)-\S+[.]egg'),
+ 'setuptools.egg'),
+ (re.compile(r'\\[\\]?'), '/'),
+ (re.compile(r'\#!\S+\bpython\S*'), '#!/usr/bin/python'),
+ # Normalize generate_script's Windows interpreter to UNIX:
+ (re.compile(r'\nimport subprocess\n'), '\n'),
+ (re.compile('subprocess\\.call\\(argv, env=environ\\)'),
+ 'os.execve(sys.executable, argv, environ)'),
+ (re.compile('distribute'), 'setuptools'),
+ # Distribute unzips eggs by default.
+ (re.compile('\- demoneeded'), 'd demoneeded'),
+ ]+(sys.version_info < (2, 5) and [
+ (re.compile('.*No module named runpy.*', re.S), ''),
+ (re.compile('.*usage: pdb.py scriptfile .*', re.S), ''),
+ (re.compile('.*Error: what does not exist.*', re.S), ''),
+ ] or [])),
),
doctest.DocFileSuite(
@@ -3772,35 +4033,37 @@
setUp=easy_install_SetUp,
tearDown=zc.buildout.testing.buildoutTearDown,
checker=renormalizing.RENormalizing([
- zc.buildout.testing.normalize_path,
- zc.buildout.testing.normalize_endings,
- zc.buildout.testing.normalize_script,
- zc.buildout.testing.normalize_egg_py,
- (re.compile("buildout: Running \S*setup.py"),
- 'buildout: Running setup.py'),
- (re.compile('(setuptools|distribute)-\S+-'),
- 'setuptools.egg'),
- (re.compile('zc.buildout-\S+-'),
- 'zc.buildout.egg'),
- (re.compile('File "\S+one.py"'),
- 'File "one.py"'),
- (re.compile(r'We have a develop egg: (\S+) (\S+)'),
- r'We have a develop egg: \1 V'),
- (re.compile('Picked: (setuptools|distribute) = \S+'),
- 'Picked: setuptools = V'),
- (re.compile(r'\\[\\]?'), '/'),
- (re.compile(
- '-q develop -mxN -d "/sample-buildout/develop-eggs'),
- '-q develop -mxN -d /sample-buildout/develop-eggs'
- ),
- (re.compile(r'^[*]...'), '...'),
- # for bug_92891_bootstrap_crashes_with_egg_recipe_in_buildout_section
- (re.compile(r"Unused options for buildout: 'eggs' 'scripts'\."),
- "Unused options for buildout: 'scripts' 'eggs'."),
- (re.compile('distribute'), 'setuptools'),
- # Distribute unzips eggs by default.
- (re.compile('\- demoneeded'), 'd demoneeded'),
- ]),
+ zc.buildout.testing.normalize_path,
+ zc.buildout.testing.normalize_endings,
+ zc.buildout.testing.normalize_script,
+ zc.buildout.testing.normalize_egg_py,
+ zc.buildout.tests.hide_distribute_additions,
+ hide_first_index_page_message,
+ (re.compile("buildout: Running \S*setup.py"),
+ 'buildout: Running setup.py'),
+ (re.compile('(setuptools|distribute)-\S+-'),
+ 'setuptools.egg'),
+ (re.compile('zc.buildout-\S+-'),
+ 'zc.buildout.egg'),
+ (re.compile('File "\S+one.py"'),
+ 'File "one.py"'),
+ (re.compile(r'We have a develop egg: (\S+) (\S+)'),
+ r'We have a develop egg: \1 V'),
+ (re.compile('Picked: (setuptools|distribute) = \S+'),
+ 'Picked: setuptools = V'),
+ (re.compile(r'\\[\\]?'), '/'),
+ (re.compile(
+ '-q develop -mxN -d "/sample-buildout/develop-eggs'),
+ '-q develop -mxN -d /sample-buildout/develop-eggs'
+ ),
+ (re.compile(r'^[*]...'), '...'),
+ # for bug_92891_bootstrap_crashes_with_egg_recipe_in_buildout_section
+ (re.compile(r"Unused options for buildout: 'eggs' 'scripts'\."),
+ "Unused options for buildout: 'scripts' 'eggs'."),
+ (re.compile('distribute'), 'setuptools'),
+ # Distribute unzips eggs by default.
+ (re.compile('\- demoneeded'), 'd demoneeded'),
+ ]),
),
zc.buildout.testselectingpython.test_suite(),
zc.buildout.rmtree.test_suite(),
@@ -3809,31 +4072,42 @@
setUp=zc.buildout.testing.buildoutSetUp,
tearDown=zc.buildout.testing.buildoutTearDown,
checker=renormalizing.RENormalizing([
- zc.buildout.testing.normalize_path,
- zc.buildout.testing.normalize_endings,
- zc.buildout.testing.normalize_script,
- zc.buildout.testing.normalize_egg_py,
- (re.compile('__buildout_signature__ = recipes-\S+'),
- '__buildout_signature__ = recipes-SSSSSSSSSSS'),
- (re.compile('[-d] setuptools-\S+[.]egg'), 'setuptools.egg'),
- (re.compile('zc.buildout(-\S+)?[.]egg(-link)?'),
- 'zc.buildout.egg'),
- (re.compile('creating \S*setup.cfg'), 'creating setup.cfg'),
- (re.compile('hello\%ssetup' % os.path.sep), 'hello/setup'),
- (re.compile('Picked: (\S+) = \S+'),
- 'Picked: \\1 = V.V'),
- (re.compile(r'We have a develop egg: zc.buildout (\S+)'),
- 'We have a develop egg: zc.buildout X.X.'),
- (re.compile(r'\\[\\]?'), '/'),
- (re.compile('WindowsError'), 'OSError'),
- (re.compile(r'\[Error 17\] Cannot create a file '
- r'when that file already exists: '),
- '[Errno 17] File exists: '
- ),
- ])
+ zc.buildout.testing.normalize_path,
+ zc.buildout.testing.normalize_endings,
+ zc.buildout.testing.normalize_script,
+ zc.buildout.testing.normalize_egg_py,
+ zc.buildout.tests.hide_distribute_additions,
+ (re.compile('__buildout_signature__ = recipes-\S+'),
+ '__buildout_signature__ = recipes-SSSSSSSSSSS'),
+ (re.compile('[-d] setuptools-\S+[.]egg'), 'setuptools.egg'),
+ (re.compile('zc.buildout(-\S+)?[.]egg(-link)?'),
+ 'zc.buildout.egg'),
+ (re.compile('creating \S*setup.cfg'), 'creating setup.cfg'),
+ (re.compile('hello\%ssetup' % os.path.sep), 'hello/setup'),
+ (re.compile('Picked: (\S+) = \S+'),
+ 'Picked: \\1 = V.V'),
+ (re.compile(r'We have a develop egg: zc.buildout (\S+)'),
+ 'We have a develop egg: zc.buildout X.X.'),
+ (re.compile(r'\\[\\]?'), '/'),
+ (re.compile('WindowsError'), 'OSError'),
+ (re.compile(r'\[Error 17\] Cannot create a file '
+ r'when that file already exists: '),
+ '[Errno 17] File exists: '
+ ),
+ ])
),
doctest.DocFileSuite(
- 'testing_bugfix.txt'),
+ 'testing_bugfix.txt',
+ checker=renormalizing.RENormalizing([
+ # Python 2.7
+ (re.compile(
+ re.escape(
+ 'testrunner.logsupport.NullHandler instance at')),
+ 'testrunner.logsupport.NullHandler object at'),
+ (re.compile(re.escape('logging.StreamHandler instance at')),
+ 'logging.StreamHandler object at'),
+ ])
+ ),
]
# adding bootstrap.txt doctest to the suite
@@ -3851,17 +4125,38 @@
if os.path.exists(bootstrap_py):
test_suite.append(doctest.DocFileSuite(
'bootstrap.txt',
+ setUp=bootstrapSetup,
+ tearDown=zc.buildout.testing.buildoutTearDown,
+ checker=renormalizing.RENormalizing([
+ zc.buildout.testing.normalize_path,
+ zc.buildout.testing.normalize_endings,
+ zc.buildout.testing.normalize_script,
+ zc.buildout.testing.normalize_egg_py,
+ normalize_bang,
+ (re.compile('Downloading.*setuptools.*egg\n'), ''),
+ (re.compile('options:'), 'Options:'),
+ (re.compile('usage:'), 'Usage:'),
+ ]),
+ ))
+ test_suite.append(doctest.DocFileSuite(
+ 'virtualenv.txt',
setUp=easy_install_SetUp,
tearDown=zc.buildout.testing.buildoutTearDown,
checker=renormalizing.RENormalizing([
- zc.buildout.testing.normalize_path,
- zc.buildout.testing.normalize_endings,
- zc.buildout.testing.normalize_script,
- normalize_bang,
- (re.compile('Downloading.*setuptools.*egg\n'), ''),
- (re.compile('options:'), 'Options:'),
- (re.compile('usage:'), 'Usage:'),
- ]),
+ zc.buildout.testing.normalize_path,
+ zc.buildout.testing.normalize_endings,
+ zc.buildout.testing.normalize_script,
+ zc.buildout.testing.normalize_egg_py,
+ zc.buildout.tests.hide_distribute_additions,
+ (re.compile('(setuptools|distribute)-\S+-'),
+ 'setuptools.egg'),
+ (re.compile('zc.buildout-\S+-'),
+ 'zc.buildout.egg'),
+ (re.compile(re.escape('#!"/executable_buildout/bin/py"')),
+ '#!/executable_buildout/bin/py'), # Windows.
+ (re.compile(re.escape('/broken_s/')),
+ '/broken_S/'), # Windows.
+ ]),
))
return unittest.TestSuite(test_suite)
Modified: zc.buildout/trunk/src/zc/buildout/update.txt
===================================================================
--- zc.buildout/trunk/src/zc/buildout/update.txt 2010-08-23 14:55:43 UTC (rev 115886)
+++ zc.buildout/trunk/src/zc/buildout/update.txt 2010-08-23 15:04:24 UTC (rev 115887)
@@ -3,13 +3,14 @@
When a buildout is run, one of the first steps performed is to check
for updates to either zc.buildout or setuptools. To demonstrate this,
-we've creates some "new releases" of buildout and setuptools in a
+we've created some "new releases" of buildout and setuptools in a
new_releases folder:
>>> ls(new_releases)
d setuptools
- setuptools-99.99-py2.4.egg
d zc.buildout
+ - zc.buildout-100.0b1-pyN.N.egg
- zc.buildout-99.99-py2.4.egg
Let's update the sample buildout.cfg to look in this area:
@@ -78,6 +79,13 @@
zc.buildout 99.99
setuptools 99.99
+Notice that, even though we have a newer beta version of zc.buildout
+available, the final "99.99" was selected. If you want to get non-final
+versions, specify a specific version in your buildout's versions
+section, you typically want to use the --accept-buildout-test-releases
+option to the bootstrap script, which internally uses the
+``accept-buildout-test-releases = true`` discussed below.
+
Our buildout script's site.py has been updated to use the new eggs:
>>> cat(sample_buildout, 'parts', 'buildout', 'site.py')
@@ -162,7 +170,7 @@
setuptools 0.6
We also won't upgrade if the buildout script being run isn't in the
-buildouts bin directory. To see this we'll create a new buildout
+buildout's bin directory. To see this we'll create a new buildout
directory:
>>> sample_buildout2 = tmpdir('sample_buildout2')
@@ -187,3 +195,57 @@
Not upgrading because not running a local buildout command.
>>> ls('bin')
+
+As mentioned above, the ``accept-buildout-test-releases = true`` means that
+newer non-final versions of these dependencies are preferred. Typically
+users are not expected to actually manipulate this value. Instead, the
+bootstrap script creates a buildout buildout script that passes in the
+value as a command line override. This then results in the buildout
+script being rewritten to remember the decision.
+
+We'll mimic this by passing the argument actually in the command line.
+
+ >>> cd(sample_buildout)
+ >>> write(sample_buildout, 'buildout.cfg',
+ ... """
+ ... [buildout]
+ ... find-links = %(new_releases)s
+ ... index = %(new_releases)s
+ ... parts = show-versions
+ ... develop = showversions
+ ...
+ ... [show-versions]
+ ... recipe = showversions
+ ... """ % dict(new_releases=new_releases))
+
+ >>> print system(buildout +
+ ... ' buildout:accept-buildout-test-releases=true'),
+ ... # doctest: +NORMALIZE_WHITESPACE
+ Getting distribution for 'zc.buildout'.
+ Got zc.buildout 100.0b1.
+ Upgraded:
+ zc.buildout version 100.0b1,
+ setuptools version 99.99;
+ restarting.
+ Generated script '/sample-buildout/bin/buildout'.
+ NOTE: Accepting early releases of build system packages. Rerun bootstrap
+ without --accept-buildout-test-releases (-t) to return to default
+ behavior.
+ Develop: '/sample-buildout/showversions'
+ Updating show-versions.
+ zc.buildout 100.0b1
+ setuptools 99.99
+
+The buildout script shows the change.
+
+ >>> buildout_script = join(sample_buildout, 'bin', 'buildout')
+ >>> import sys
+ >>> if sys.platform.startswith('win'):
+ ... buildout_script += '-script.py'
+ >>> print open(buildout_script).read() # doctest: +ELLIPSIS
+ #...
+ sys.argv.insert(1, 'buildout:accept-buildout-test-releases=true')
+ print ('NOTE: Accepting early releases of build system packages. Rerun '
+ 'bootstrap without --accept-buildout-test-releases (-t) to return to '
+ 'default behavior.')
+ ...
Copied: zc.buildout/trunk/src/zc/buildout/virtualenv.txt (from rev 115859, zc.buildout/branches/gary-betafix/src/zc/buildout/virtualenv.txt)
===================================================================
--- zc.buildout/trunk/src/zc/buildout/virtualenv.txt (rev 0)
+++ zc.buildout/trunk/src/zc/buildout/virtualenv.txt 2010-08-23 15:04:24 UTC (rev 115887)
@@ -0,0 +1,259 @@
+Version 1.5.0 of buildout (and higher) provides the ability to use
+buildout directly with a system Python if you use z3c.recipe.scripts or
+other isolation-aware recipes that use the sitepackage_safe_scripts function.
+
+Some people use virtualenv to provide similar functionality.
+Unfortunately, a problem with the virtualenv executable as of this
+writing means that -S will not work properly with it (see
+https://bugs.launchpad.net/virtualenv/+bug/572545). This breaks
+buildout's approach to providing isolation.
+
+Because of this, if buildout detects an executable with a broken -S
+option, it will revert to its pre-1.5.0 behavior. If buildout has been
+asked to provide isolation, it will warn the user that isolation will
+not be provided by buildout, but proceed. This should give full
+backwards compatibility to virtualenv users.
+
+The only minor annoyance in the future may be recipes that explicitly
+use the new buildout functionality to provide isolation: as described
+above, the builds will proceed, but users will receive warnings that
+buildout is not providing isolation itself. The warnings themselves can
+be squelched when running bin/buildout with the ``-s`` option or with a
+lower verbosity than usual (e.g., one or more ``-q`` options).
+
+For tests, then, we can examine several things. We'll focus on four.
+
+- Running bootstrap with an executable broken in this way will not try to do
+ any -S tricks.
+
+- Running sitepackage_safe_scripts with a virtualenv will create an
+ old-style script. This will affect the bin/buildout script that is
+ created, for instance. If the sitepackage_safe_scripts function is asked
+ to provide isolation under these circumstances, it will warn that isolation
+ will not be available, but still create the desired script.
+
+- Using the easy_install Installer or install or build functions and trying
+ to request isolation will generate a warning and then the isolation request
+ will be ignored as it proceeds.
+
+- Passing -s (or -q) to the bin/buildout script will squelch warnings.
+
+Testing these involves first creating a Python that exhibits the same
+behavior as the problematic one we care about from virtualenv. Let's do that
+first.
+
+ >>> import os, sys
+ >>> from zc.buildout.easy_install import _safe_arg
+ >>> py_path, site_packages_path = make_py()
+ >>> if sys.platform == 'win32':
+ ... py_script_path = py_path + '-script.py'
+ ... else:
+ ... py_script_path = py_path
+ ...
+ >>> py_file = open(py_script_path)
+ >>> py_lines = py_file.readlines()
+ >>> py_file.close()
+ >>> py_file = open(py_script_path, 'w')
+ >>> extra = '''\
+ ... new_argv = argv[:1]
+ ... for ix, val in enumerate(argv[1:]):
+ ... if val.startswith('--'):
+ ... new_argv.append(val)
+ ... if val.startswith('-') and len(val) > 1:
+ ... if 'S' in val:
+ ... val = val.replace('S', '')
+ ... environ['BROKEN_DASH_S'] = 'Y'
+ ... if val != '-':
+ ... new_argv.append(val)
+ ... if 'c' in val:
+ ... new_argv.extend(argv[ix+2:])
+ ... break
+ ... else:
+ ... new_argv.extend(argv[ix+1:])
+ ... argv = new_argv
+ ... '''
+ >>> for line in py_lines:
+ ... py_file.write(line)
+ ... if line.startswith('environ = os.environ.copy()'):
+ ... py_file.write(extra)
+ ... print 'Rewritten.'
+ ...
+ Rewritten.
+ >>> py_file.close()
+ >>> sitecustomize_path = join(os.path.dirname(site_packages_path),
+ ... 'parts', 'py', 'sitecustomize.py')
+ >>> sitecustomize_file = open(sitecustomize_path, 'a')
+ >>> sitecustomize_file.write('''
+ ... import os, sys
+ ... sys.executable = %r
+ ... if 'BROKEN_DASH_S' in os.environ:
+ ... class ImportHook:
+ ... site = None
+ ...
+ ... @classmethod
+ ... def find_module(klass, fullname, path=None):
+ ... if klass.site is None and 'site' in sys.modules:
+ ... # Pop site out of sys.modules. This will be a
+ ... # close-enough approximation of site not being
+ ... # loaded for our tests--it lets us provoke the
+ ... # right errors when the fixes are absent, and
+ ... # works well enough when the fixes are present.
+ ... klass.site = sys.modules.pop('site')
+ ... if fullname == 'ConfigParser':
+ ... raise ImportError(fullname)
+ ... elif fullname == 'site':
+ ... # Keep the site module from being processed twice.
+ ... return klass
+ ...
+ ... @classmethod
+ ... def load_module(klass, fullname):
+ ... if fullname == 'site':
+ ... return klass.site
+ ... raise ImportError(fullname)
+ ...
+ ... sys.meta_path.append(ImportHook)
+ ... ''' % (py_path,))
+ >>> sitecustomize_file.close()
+ >>> print call_py(
+ ... _safe_arg(py_path),
+ ... "import ConfigParser")
+ <BLANKLINE>
+ >>> print 'X'; print call_py(
+ ... _safe_arg(py_path),
+ ... "import ConfigParser",
+ ... '-S') # doctest: +ELLIPSIS
+ X...Traceback (most recent call last):
+ ...
+ ImportError: No module named ConfigParser
+ <BLANKLINE>
+ >>> from zc.buildout.easy_install import _has_broken_dash_S
+ >>> _has_broken_dash_S(py_path)
+ True
+
+Well, that was ugly, but it seems to have done the trick. The
+executable represented by py_path has the same problematic
+characteristic as the virtualenv one: -S results in a Python that does
+not allow the import of some packages from the standard library. We'll
+test with this.
+
+First, let's try running bootstrap.
+
+ >>> from os.path import dirname, join
+ >>> import zc.buildout
+ >>> bootstrap_py = join(
+ ... dirname(
+ ... dirname(
+ ... dirname(
+ ... dirname(zc.buildout.__file__)
+ ... )
+ ... )
+ ... ),
+ ... 'bootstrap', 'bootstrap.py')
+ >>> broken_S_buildout = tmpdir('broken_S')
+ >>> os.chdir(broken_S_buildout)
+ >>> write('buildout.cfg',
+ ... '''
+ ... [buildout]
+ ... parts =
+ ... ''')
+ >>> write('bootstrap.py', open(bootstrap_py).read())
+ >>> print 'X'; print system(
+ ... _safe_arg(py_path)+' '+
+ ... 'bootstrap.py'); print 'X' # doctest: +ELLIPSIS
+ X...
+ Generated script '/broken_S/bin/buildout'.
+ ...
+
+If bootstrap didn't look out for a broken -S, that would have failed. Moreover,
+take a look at bin/buildout:
+
+ >>> cat('bin', 'buildout')
+ #!/executable_buildout/bin/py
+ <BLANKLINE>
+ import sys
+ sys.path[0:0] = [
+ '/broken_S/eggs/setuptools-0.0-pyN.N.egg',
+ '/broken_S/eggs/zc.buildout-0.0-pyN.N.egg',
+ ]
+ <BLANKLINE>
+ import zc.buildout.buildout
+ <BLANKLINE>
+ if __name__ == '__main__':
+ zc.buildout.buildout.main()
+
+That's the old-style buildout script: no changes for users with this issue.
+
+Of course, they don't get the new features either, presumably because
+they don't need or want them. This means that if they use a recipe that
+tries to use a new feature, the behavior needs to degrade gracefully.
+
+Here's an example. We'll switch to another buildout in which it is easier to
+use local dev versions of zc.buildout and z3c.recipe.scripts.
+
+ >>> os.chdir(dirname(dirname(buildout)))
+ >>> write('buildout.cfg',
+ ... '''
+ ... [buildout]
+ ... parts = eggs
+ ... find-links = %(link_server)s
+ ...
+ ... [primed_python]
+ ... executable = %(py_path)s
+ ...
+ ... [eggs]
+ ... recipe = z3c.recipe.scripts
+ ... python = primed_python
+ ... interpreter = py
+ ... eggs = demo
+ ... ''' % globals())
+
+ >>> print system(buildout) # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
+ Installing eggs.
+ Getting distribution for 'demo'.
+ Got demo 0.4c1.
+ Getting distribution for 'demoneeded'.
+ Got demoneeded 1.2c1.
+ Generated script '/sample-buildout/bin/demo'.
+ Generated interpreter '/sample-buildout/bin/py'.
+ ...UserWarning: Buildout has been asked to exclude or limit site-packages
+ so that builds can be repeatable when using a system Python. However,
+ the chosen Python executable has a broken implementation of -S (see
+ https://bugs.launchpad.net/virtualenv/+bug/572545 for an example
+ problem) and this breaks buildout's ability to isolate site-packages.
+ If the executable already has a clean site-packages (e.g., using
+ virtualenv's ``--no-site-packages`` option) you may be getting
+ equivalent repeatability. To silence this warning, use the -s argument
+ to the buildout script. Alternatively, use a Python executable with a
+ working -S (such as a standard Python binary).
+ warnings.warn(BROKEN_DASH_S_WARNING)
+ <BLANKLINE>
+
+So, it did what we asked as best it could, but gave a big warning. If
+you don't want those warnings for those particular recipes that use the
+new features, you can use the "-s" option to squelch the warnings.
+
+ >>> print system(buildout + ' -s')
+ Updating eggs.
+ <BLANKLINE>
+
+A lower verbosity (one or more -q options) also quiets the warning.
+
+ >>> print system(buildout + ' -q')
+ <BLANKLINE>
+
+Notice that, as we saw before with bin/buildout, the generated scripts
+are old-style, because the new-style feature gracefully degrades to the
+previous implementation when it encounters an executable with a broken
+dash-S.
+
+ >>> print 'X'; cat('bin', 'py') # doctest: +ELLIPSIS
+ X...
+ <BLANKLINE>
+ import sys
+ <BLANKLINE>
+ sys.path[0:0] = [
+ '/sample-buildout/eggs/demo-0.4c1-pyN.N.egg',
+ '/sample-buildout/eggs/demoneeded-1.2c1-pyN.N.egg',
+ ]
+ ...
+
Modified: zc.buildout/trunk/z3c.recipe.scripts_/CHANGES.txt
===================================================================
--- zc.buildout/trunk/z3c.recipe.scripts_/CHANGES.txt 2010-08-23 14:55:43 UTC (rev 115886)
+++ zc.buildout/trunk/z3c.recipe.scripts_/CHANGES.txt 2010-08-23 15:04:24 UTC (rev 115887)
@@ -1,6 +1,11 @@
Change History
**************
+1.0.0 (unreleased)
+==================
+
+(no significant changes)
+
1.0.0b1 (2010-04-29)
====================
Copied: zc.buildout/trunk/z3c.recipe.scripts_/MANIFEST.in (from rev 115859, zc.buildout/branches/gary-betafix/z3c.recipe.scripts_/MANIFEST.in)
===================================================================
--- zc.buildout/trunk/z3c.recipe.scripts_/MANIFEST.in (rev 0)
+++ zc.buildout/trunk/z3c.recipe.scripts_/MANIFEST.in 2010-08-23 15:04:24 UTC (rev 115887)
@@ -0,0 +1,3 @@
+include *.txt
+recursive-include src *.txt
+exclude MANIFEST.in buildout.cfg .bzrignore
Modified: zc.buildout/trunk/z3c.recipe.scripts_/setup.py
===================================================================
--- zc.buildout/trunk/z3c.recipe.scripts_/setup.py 2010-08-23 14:55:43 UTC (rev 115886)
+++ zc.buildout/trunk/z3c.recipe.scripts_/setup.py 2010-08-23 15:04:24 UTC (rev 115887)
@@ -12,11 +12,9 @@
#
##############################################################################
"""Setup for z3c.recipe.scripts package
-
-$Id: setup.py 106736 2009-12-18 02:33:08Z gary $
"""
-version = '1.0.0dev'
+version = '1.0.0'
import os
from setuptools import setup, find_packages
@@ -60,8 +58,8 @@
package_dir = {'':'src'},
namespace_packages = ['z3c', 'z3c.recipe'],
install_requires = [
- 'zc.buildout >=1.5.0dev',
- 'zc.recipe.egg >=1.2.3dev',
+ 'zc.buildout >=1.5.0',
+ 'zc.recipe.egg >=1.3.0',
'setuptools'],
tests_require = ['zope.testing'],
test_suite = name+'.tests.test_suite',
Modified: zc.buildout/trunk/z3c.recipe.scripts_/src/z3c/recipe/scripts/scripts.py
===================================================================
--- zc.buildout/trunk/z3c.recipe.scripts_/src/z3c/recipe/scripts/scripts.py 2010-08-23 14:55:43 UTC (rev 115886)
+++ zc.buildout/trunk/z3c.recipe.scripts_/src/z3c/recipe/scripts/scripts.py 2010-08-23 15:04:24 UTC (rev 115887)
@@ -35,23 +35,13 @@
'*')
self.allowed_eggs = tuple(name.strip() for name in value.split('\n'))
- value = options.setdefault(
+ self.include_site_packages = options.query_bool(
'include-site-packages',
- b_options.get('include-site-packages', 'false'))
- if value not in ('true', 'false'):
- raise zc.buildout.UserError(
- "Invalid value for include-site-packages option: %s" %
- (value,))
- self.include_site_packages = (value == 'true')
+ default=b_options.get('include-site-packages', 'false'))
- value = options.setdefault(
+ self.exec_sitecustomize = options.query_bool(
'exec-sitecustomize',
- b_options.get('exec-sitecustomize', 'false'))
- if value not in ('true', 'false'):
- raise zc.buildout.UserError(
- "Invalid value for exec-sitecustomize option: %s" %
- (value,))
- self.exec_sitecustomize = (value == 'true')
+ default=b_options.get('exec-sitecustomize', 'false'))
class Interpreter(Base):
Modified: zc.buildout/trunk/z3c.recipe.scripts_/src/z3c/recipe/scripts/tests.py
===================================================================
--- zc.buildout/trunk/z3c.recipe.scripts_/src/z3c/recipe/scripts/tests.py 2010-08-23 14:55:43 UTC (rev 115886)
+++ zc.buildout/trunk/z3c.recipe.scripts_/src/z3c/recipe/scripts/tests.py 2010-08-23 15:04:24 UTC (rev 115887)
@@ -416,24 +416,26 @@
'README.txt',
setUp=setUp, tearDown=zc.buildout.testing.buildoutTearDown,
checker=renormalizing.RENormalizing([
- zc.buildout.testing.normalize_path,
- zc.buildout.testing.normalize_endings,
- zc.buildout.testing.normalize_script,
- zc.buildout.testing.normalize_egg_py,
- zc.buildout.tests.normalize_bang,
- (re.compile(r'zc.buildout(-\S+)?[.]egg(-link)?'),
- 'zc.buildout.egg'),
- (re.compile('[-d] (setuptools|distribute)-[^-]+-'), 'setuptools-X-'),
- (re.compile(r'(setuptools|distribute)-[\w.]+-py'), 'setuptools-X-py'),
- (re.compile(r'eggs\\\\demo'), 'eggs/demo'),
- (re.compile(r'[a-zA-Z]:\\\\foo\\\\bar'), '/foo/bar'),
- (re.compile(r'\#!\S+\bpython\S*'), '#!/usr/bin/python'),
- # Normalize generate_script's Windows interpreter to UNIX:
- (re.compile(r'\nimport subprocess\n'), '\n'),
- (re.compile('subprocess\\.call\\(argv, env=environ\\)'),
- 'os.execve(sys.executable, argv, environ)'),
- (re.compile('distribute'), 'setuptools'),
- ])
+ zc.buildout.testing.normalize_path,
+ zc.buildout.testing.normalize_endings,
+ zc.buildout.testing.normalize_script,
+ zc.buildout.testing.normalize_egg_py,
+ zc.buildout.tests.normalize_bang,
+ zc.buildout.tests.hide_distribute_additions,
+ zc.buildout.tests.hide_first_index_page_message,
+ (re.compile(r'zc.buildout(-\S+)?[.]egg(-link)?'),
+ 'zc.buildout.egg'),
+ (re.compile('[-d] (setuptools|distribute)-[^-]+-'), 'setuptools-X-'),
+ (re.compile(r'(setuptools|distribute)-[\w.]+-py'), 'setuptools-X-py'),
+ (re.compile(r'eggs\\\\demo'), 'eggs/demo'),
+ (re.compile(r'[a-zA-Z]:\\\\foo\\\\bar'), '/foo/bar'),
+ (re.compile(r'\#!\S+\bpython\S*'), '#!/usr/bin/python'),
+ # Normalize generate_script's Windows interpreter to UNIX:
+ (re.compile(r'\nimport subprocess\n'), '\n'),
+ (re.compile('subprocess\\.call\\(argv, env=environ\\)'),
+ 'os.execve(sys.executable, argv, environ)'),
+ (re.compile('distribute'), 'setuptools'),
+ ])
),
doctest.DocTestSuite(
setUp=setUp,
@@ -442,6 +444,8 @@
zc.buildout.testing.normalize_path,
zc.buildout.testing.normalize_endings,
zc.buildout.testing.normalize_egg_py,
+ zc.buildout.tests.hide_distribute_additions,
+ zc.buildout.tests.hide_first_index_page_message,
(re.compile(r'[a-zA-Z]:\\\\foo\\\\bar'), '/foo/bar'),
]),
),
Modified: zc.buildout/trunk/zc.recipe.egg_/CHANGES.txt
===================================================================
--- zc.buildout/trunk/zc.recipe.egg_/CHANGES.txt 2010-08-23 14:55:43 UTC (rev 115886)
+++ zc.buildout/trunk/zc.recipe.egg_/CHANGES.txt 2010-08-23 15:04:24 UTC (rev 115887)
@@ -1,6 +1,12 @@
Change History
**************
+1.3.0 (unreleased)
+==================
+
+- Small further refactorings past 1.2.3b1 to be compatible with zc.buildout
+ 1.5.0.
+
1.2.3b1 (2010-04-29)
====================
Copied: zc.buildout/trunk/zc.recipe.egg_/MANIFEST.in (from rev 115859, zc.buildout/branches/gary-betafix/zc.recipe.egg_/MANIFEST.in)
===================================================================
--- zc.buildout/trunk/zc.recipe.egg_/MANIFEST.in (rev 0)
+++ zc.buildout/trunk/zc.recipe.egg_/MANIFEST.in 2010-08-23 15:04:24 UTC (rev 115887)
@@ -0,0 +1,3 @@
+include *.txt
+recursive-include src *.txt
+exclude MANIFEST.in buildout.cfg .bzrignore
Modified: zc.buildout/trunk/zc.recipe.egg_/setup.py
===================================================================
--- zc.buildout/trunk/zc.recipe.egg_/setup.py 2010-08-23 14:55:43 UTC (rev 115886)
+++ zc.buildout/trunk/zc.recipe.egg_/setup.py 2010-08-23 15:04:24 UTC (rev 115887)
@@ -12,11 +12,9 @@
#
##############################################################################
"""Setup for zc.recipe.egg package
-
-$Id$
"""
-version = '1.2.3dev'
+version = '1.3.0'
import os
from setuptools import setup, find_packages
@@ -66,7 +64,7 @@
package_dir = {'':'src'},
namespace_packages = ['zc', 'zc.recipe'],
install_requires = [
- 'zc.buildout >=1.5.0dev',
+ 'zc.buildout >=1.5.0',
'setuptools'],
tests_require = ['zope.testing'],
test_suite = name+'.tests.test_suite',
Modified: zc.buildout/trunk/zc.recipe.egg_/src/zc/recipe/egg/egg.py
===================================================================
--- zc.buildout/trunk/zc.recipe.egg_/src/zc/recipe/egg/egg.py 2010-08-23 14:55:43 UTC (rev 115886)
+++ zc.buildout/trunk/zc.recipe.egg_/src/zc/recipe/egg/egg.py 2010-08-23 15:04:24 UTC (rev 115887)
@@ -52,9 +52,6 @@
options['develop-eggs-directory'] = b_options['develop-eggs-directory']
options['_d'] = options['develop-eggs-directory'] # backward compat.
- # verify that this is None, 'true' or 'false'
- get_bool(options, 'unzip')
-
python = options.setdefault('python', b_options['python'])
options['executable'] = buildout[python]['executable']
@@ -84,7 +81,7 @@
else:
kw = {}
if 'unzip' in options:
- kw['always_unzip'] = get_bool(options, 'unzip')
+ kw['always_unzip'] = options.query_bool('unzip', None)
ws = zc.buildout.easy_install.install(
distributions, options['eggs-directory'],
links=self.links,
@@ -159,7 +156,7 @@
raise zc.buildout.UserError("Invalid entry point")
reqs.append(parsed.groups())
- if get_bool(options, 'dependent-scripts'):
+ if options.query_bool('dependent-scripts', 'false'):
# Generate scripts for all packages in the working set,
# except setuptools.
reqs = list(reqs)
@@ -192,17 +189,4 @@
relative_paths=self._relative_paths
)
-
-def get_bool(options, name, default=False):
- value = options.get(name)
- if not value:
- return default
- if value == 'true':
- return True
- elif value == 'false':
- return False
- else:
- raise zc.buildout.UserError(
- "Invalid value for %s option: %s" % (name, value))
-
Egg = Scripts
Modified: zc.buildout/trunk/zc.recipe.egg_/src/zc/recipe/egg/tests.py
===================================================================
--- zc.buildout/trunk/zc.recipe.egg_/src/zc/recipe/egg/tests.py 2010-08-23 14:55:43 UTC (rev 115886)
+++ zc.buildout/trunk/zc.recipe.egg_/src/zc/recipe/egg/tests.py 2010-08-23 15:04:24 UTC (rev 115887)
@@ -43,54 +43,58 @@
'README.txt',
setUp=setUp, tearDown=zc.buildout.testing.buildoutTearDown,
checker=renormalizing.RENormalizing([
- zc.buildout.testing.normalize_path,
- zc.buildout.testing.normalize_endings,
- zc.buildout.testing.normalize_script,
- zc.buildout.testing.normalize_egg_py,
- zc.buildout.tests.normalize_bang,
- (re.compile('zc.buildout(-\S+)?[.]egg(-link)?'),
- 'zc.buildout.egg'),
- (re.compile('[-d] (setuptools|distribute)-[^-]+-'),
- 'setuptools-X-'),
- (re.compile(r'eggs\\\\demo'), 'eggs/demo'),
- (re.compile(r'[a-zA-Z]:\\\\foo\\\\bar'), '/foo/bar'),
- # Distribute unzips eggs by default.
- (re.compile('\- demoneeded'), 'd demoneeded'),
- ])
+ zc.buildout.testing.normalize_path,
+ zc.buildout.testing.normalize_endings,
+ zc.buildout.testing.normalize_script,
+ zc.buildout.testing.normalize_egg_py,
+ zc.buildout.tests.normalize_bang,
+ zc.buildout.tests.hide_distribute_additions,
+ (re.compile('zc.buildout(-\S+)?[.]egg(-link)?'),
+ 'zc.buildout.egg'),
+ (re.compile('[-d] (setuptools|distribute)-[^-]+-'),
+ 'setuptools-X-'),
+ (re.compile(r'eggs\\\\demo'), 'eggs/demo'),
+ (re.compile(r'[a-zA-Z]:\\\\foo\\\\bar'), '/foo/bar'),
+ # Distribute unzips eggs by default.
+ (re.compile('\- demoneeded'), 'd demoneeded'),
+ ])
),
doctest.DocFileSuite(
'api.txt',
setUp=setUp, tearDown=zc.buildout.testing.buildoutTearDown,
checker=renormalizing.RENormalizing([
- zc.buildout.testing.normalize_path,
- zc.buildout.testing.normalize_endings,
- (re.compile('__buildout_signature__ = '
- 'sample-\S+\s+'
- 'zc.recipe.egg-\S+\s+'
- '(setuptools|distribute)-\S+\s+'
- 'zc.buildout-\S+\s*'
- ),
- '__buildout_signature__ = sample- zc.recipe.egg-\n'),
- (re.compile('executable = [\S ]+python\S*', re.I),
- 'executable = python'),
- (re.compile('find-links = http://localhost:\d+/'),
- 'find-links = http://localhost:8080/'),
- (re.compile('index = http://localhost:\d+/index'),
- 'index = http://localhost:8080/index'),
- ])
+ zc.buildout.testing.normalize_path,
+ zc.buildout.testing.normalize_endings,
+ zc.buildout.tests.hide_distribute_additions,
+ (re.compile('__buildout_signature__ = '
+ 'sample-\S+\s+'
+ 'zc.recipe.egg-\S+\s+'
+ '(setuptools|distribute)-\S+\s+'
+ 'zc.buildout-\S+\s*'
+ ),
+ '__buildout_signature__ = sample- zc.recipe.egg-\n'),
+ (re.compile('executable = [\S ]+python\S*', re.I),
+ 'executable = python'),
+ (re.compile('find-links = http://localhost:\d+/'),
+ 'find-links = http://localhost:8080/'),
+ (re.compile('index = http://localhost:\d+/index'),
+ 'index = http://localhost:8080/index'),
+ ])
),
doctest.DocFileSuite(
'custom.txt',
setUp=setUp, tearDown=zc.buildout.testing.buildoutTearDown,
checker=renormalizing.RENormalizing([
- zc.buildout.testing.normalize_path,
- zc.buildout.testing.normalize_endings,
- (re.compile("(d ((ext)?demo(needed)?|other)"
- "-\d[.]\d-py)\d[.]\d(-\S+)?[.]egg"),
- '\\1V.V.egg'),
- (re.compile('extdemo.c\n.+\\extdemo.exp\n'), ''),
- (re.compile('extdemo[.]pyd'), 'extdemo.so')
- ]),
+ zc.buildout.testing.normalize_path,
+ zc.buildout.testing.normalize_endings,
+ zc.buildout.tests.hide_distribute_additions,
+ zc.buildout.tests.hide_zip_safe_message,
+ (re.compile("(d ((ext)?demo(needed)?|other)"
+ "-\d[.]\d-py)\d[.]\d(-\S+)?[.]egg"),
+ '\\1V.V.egg'),
+ (re.compile('extdemo.c\n.+\\extdemo.exp\n'), ''),
+ (re.compile('extdemo[.]pyd'), 'extdemo.so')
+ ]),
),
))
@@ -104,21 +108,22 @@
setUp=setUpSelecting,
tearDown=zc.buildout.testing.buildoutTearDown,
checker=renormalizing.RENormalizing([
- zc.buildout.testing.normalize_path,
- zc.buildout.testing.normalize_endings,
- zc.buildout.testing.normalize_script,
- (re.compile('Got (setuptools|distribute) \S+'),
- 'Got setuptools V'),
- (re.compile('([d-] )?(setuptools|distribute)-\S+-py'),
- 'setuptools-V-py'),
- (re.compile('-py2[.][0-35-9][.]'), 'py2.5.'),
- (re.compile('zc.buildout-\S+[.]egg'),
- 'zc.buildout.egg'),
- (re.compile('zc.buildout[.]egg-link'),
- 'zc.buildout.egg'),
- # Distribute unzips eggs by default.
- (re.compile('\- demoneeded'), 'd demoneeded'),
- ]),
+ zc.buildout.testing.normalize_path,
+ zc.buildout.testing.normalize_endings,
+ zc.buildout.testing.normalize_script,
+ zc.buildout.tests.hide_distribute_additions,
+ (re.compile('Got (setuptools|distribute) \S+'),
+ 'Got setuptools V'),
+ (re.compile('([d-] )?(setuptools|distribute)-\S+-py'),
+ 'setuptools-V-py'),
+ (re.compile('-py2[.][0-35-9][.]'), 'py2.5.'),
+ (re.compile('zc.buildout-\S+[.]egg'),
+ 'zc.buildout.egg'),
+ (re.compile('zc.buildout[.]egg-link'),
+ 'zc.buildout.egg'),
+ # Distribute unzips eggs by default.
+ (re.compile('\- demoneeded'), 'd demoneeded'),
+ ]),
),
)
More information about the checkins
mailing list