[Checkins] SVN: zc.buildout/branches/help-api/ merge from trunk

Godefroid Chapelle gotcha at bubblenet.be
Mon Jul 13 11:13:01 EDT 2009


Log message for revision 101852:
  merge from trunk

Changed:
  U   zc.buildout/branches/help-api/CHANGES.txt
  U   zc.buildout/branches/help-api/README.txt
  U   zc.buildout/branches/help-api/bootstrap/bootstrap.py
  U   zc.buildout/branches/help-api/setup.py
  A   zc.buildout/branches/help-api/src/zc/buildout/bootstrap.txt
  U   zc.buildout/branches/help-api/src/zc/buildout/buildout.py
  U   zc.buildout/branches/help-api/src/zc/buildout/buildout.txt
  U   zc.buildout/branches/help-api/src/zc/buildout/easy_install.py
  U   zc.buildout/branches/help-api/src/zc/buildout/easy_install.txt
  U   zc.buildout/branches/help-api/src/zc/buildout/testing.py
  A   zc.buildout/branches/help-api/src/zc/buildout/testing_bugfix.txt
  U   zc.buildout/branches/help-api/src/zc/buildout/tests.py
  U   zc.buildout/branches/help-api/zc.recipe.egg_/src/zc/recipe/egg/README.txt
  U   zc.buildout/branches/help-api/zc.recipe.egg_/src/zc/recipe/egg/tests.py

-=-
Modified: zc.buildout/branches/help-api/CHANGES.txt
===================================================================
--- zc.buildout/branches/help-api/CHANGES.txt	2009-07-13 15:12:48 UTC (rev 101851)
+++ zc.buildout/branches/help-api/CHANGES.txt	2009-07-13 15:13:00 UTC (rev 101852)
@@ -1,9 +1,27 @@
-Status
-******
-
 Change History
 **************
 
+1.3.0 (2009-06-22)
+==================
+
+- Better Windows compatibility in test infrastructure.
+
+- Now the bootstrap.py has an optional --version argument,
+  that can be used to force zc.buildout version to use.
+
+- ``zc.buildout.testing.buildoutSetUp`` installs a new handler in the
+  python root logging facility. This handler is now removed during
+  tear down as it might disturb other packages reusing buildout's
+  testing infrastructure.
+
+- fixed usage of 'relative_paths' keyword parameter on Windows
+
+- Added an unload entry point for extensions.
+
+- Fixed bug: when the relative paths option was used, relative paths
+  could be inserted into sys.path if a relative path was used to run
+  the generated script.
+
 1.2.1 (2009-03-18)
 ==================
 
@@ -83,8 +101,13 @@
 - added a test to verify against https://bugs.launchpad.net/zc.buildout/+bug/239212
   in allowhosts.txt (seletz)
 
+<<<<<<< HEAD:CHANGES.txt
 - further fixes for """AttributeError: Buildout instance has no 
   attribute '_logger'""" by providing reasonable defaults 
+=======
+- further fixes for """AttributeError: Buildout instance has no
+  attribute '_logger'""" by providing reasonable defaults
+>>>>>>> origin/l-trunk:CHANGES.txt
   within the Buildout constructor (related to the new 'allow-hosts' option)
   (patch by Gottfried Ganssauge) (ajung)
 
@@ -99,7 +122,11 @@
 
 - Added the `allow-hosts` option (tarek)
 
+<<<<<<< HEAD:CHANGES.txt
 - Quote the 'executable' argument when trying to detect the python 
+=======
+- Quote the 'executable' argument when trying to detect the python
+>>>>>>> origin/l-trunk:CHANGES.txt
   version using popen4. (sidnei)
 
 - Quote the 'spec' argument, as in the case of installing an egg from
@@ -110,7 +137,11 @@
 1.0.3 (2008-06-01)
 ==================
 
+<<<<<<< HEAD:CHANGES.txt
 - fix for """AttributeError: Buildout instance has no attribute '_logger'""" 
+=======
+- fix for """AttributeError: Buildout instance has no attribute '_logger'"""
+>>>>>>> origin/l-trunk:CHANGES.txt
   by providing reasonable defaults within the Buildout constructor.
   (patch by Gottfried Ganssauge) (ajung)
 
@@ -285,7 +316,7 @@
   are being added.
 
 - Changed the logging format to exclude the logger name for the
-  zc.buildout logger.  This reduces noise in the output.  
+  zc.buildout logger.  This reduces noise in the output.
 
 - Clean up lots of messages, adding missing periods and adding quotes around
   requirement strings and file paths.
@@ -295,7 +326,7 @@
 
 - 114614: Buildouts could take a very long time if there were
   dependency problems in large sets of pathologically interdependent
-  packages. 
+  packages.
 
 - 59270: Buggy recipes can cause failures in later recipes via chdir
 
@@ -339,7 +370,7 @@
   for distribution downloads.  The cache can be shared among buildouts
   to reduce network access and to support creating source
   distributions for applications allowing install without network
-  access. 
+  access.
 
 - Log scripts created, as suggested in:
   https://bugs.launchpad.net/zc.buildout/+bug/71353
@@ -423,7 +454,7 @@
   for this parameter and already installed eggs meet the given
   requirements, then no attempt will be made to search for newer
   distributions.
- 
+
 - The recipe-testing support setUp function now adds the name
   *buildout* to the test namespace with a value that is the path to
   the buildout script in the sample buildout.  This allows tests to
@@ -458,7 +489,7 @@
 Feature Changes
 ---------------
 
-- Added documentation for some previously undocumented features of the 
+- Added documentation for some previously undocumented features of the
   easy_install APIs.
 
 - By popular demand, added a -o command-line option that is a short
@@ -587,7 +618,7 @@
 ----------
 
 `67737 <https://launchpad.net/products/zc.buildout/+bug/67737>`_
-     Verbose and quite output options caused errors when the 
+     Verbose and quite output options caused errors when the
      develop buildout option was used to create develop eggs.
 
 `67871 <https://launchpad.net/products/zc.buildout/+bug/67871>`_
@@ -597,7 +628,7 @@
 `67873 <https://launchpad.net/products/zc.buildout/+bug/67873>`_
      There was an error in producing an error message when part names
      passed to the install command weren't included in the
-     configuration. 
+     configuration.
 
 1.0.0b10 (2006-10-16)
 =====================
@@ -608,12 +639,12 @@
 - Renamed the runsetup command to setup. (The old name still works.)
 
 - Added a recipe update method. Now install is only called when a part
-  is installed for the first time, or after an uninstall. Otherwise, 
+  is installed for the first time, or after an uninstall. Otherwise,
   update is called.  For backward compatibility, recipes that don't
   define update methiods are still supported.
 
-- If a distribution defines namespace packages but fails to declare 
-  setuptools as one of its dependencies, we now treat setuptools as an 
+- If a distribution defines namespace packages but fails to declare
+  setuptools as one of its dependencies, we now treat setuptools as an
   implicit dependency.  We generate a warning if the distribution
   is a develop egg.
 
@@ -707,7 +738,7 @@
 
 - No-longer generate a py_zc.buildout script.
 
-- Fixed some bugs in variable substitutions.  
+- Fixed some bugs in variable substitutions.
 
   The characters "-", "." and " ", weren't allowed in section or
   option names.

Modified: zc.buildout/branches/help-api/README.txt
===================================================================
--- zc.buildout/branches/help-api/README.txt	2009-07-13 15:12:48 UTC (rev 101851)
+++ zc.buildout/branches/help-api/README.txt	2009-07-13 15:13:00 UTC (rev 101852)
@@ -24,6 +24,9 @@
 
 To lean more about using buildouts, see `Detailed Documentation`_.
 
+To see screencasts, talks, useful links and more documentation, visit
+the `Buildout website <http://www.buildout.org>`_.
+
 Recipes
 *******
 
@@ -119,6 +122,11 @@
 
 This is probably the most common type of buildout.
 
+If I need to run a previous version of zc.buildout, I use the
+`--version` option of the buildout.py script::
+
+    $ python bootstrap.py --version 1.1.3
+    
 The `zc.buildout project <http://svn.zope.org/zc.buildout/trunk>`_
 is a slightly more complex example of this type of buildout.
 

Modified: zc.buildout/branches/help-api/bootstrap/bootstrap.py
===================================================================
--- zc.buildout/branches/help-api/bootstrap/bootstrap.py	2009-07-13 15:12:48 UTC (rev 101851)
+++ zc.buildout/branches/help-api/bootstrap/bootstrap.py	2009-07-13 15:13:00 UTC (rev 101852)
@@ -49,11 +49,18 @@
 cmd = 'from setuptools.command.easy_install import main; main()'
 ws  = pkg_resources.working_set
 
+if len(sys.argv) > 2 and sys.argv[1] == '--version':
+    VERSION = '==%s' % sys.argv[2]
+    args = sys.argv[3:] + ['bootstrap']
+else:
+    VERSION = ''
+    args = sys.argv[1:] + ['bootstrap']
+
 if is_jython:
     import subprocess
-    
-    assert subprocess.Popen([sys.executable] + ['-c', quote(cmd), '-mqNxd', 
-           quote(tmpeggs), 'zc.buildout'], 
+
+    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('setuptools')).location
@@ -63,7 +70,7 @@
 else:
     assert os.spawnle(
         os.P_WAIT, sys.executable, quote (sys.executable),
-        '-c', quote (cmd), '-mqNxd', quote (tmpeggs), 'zc.buildout',
+        '-c', quote (cmd), '-mqNxd', quote (tmpeggs), 'zc.buildout' + VERSION,
         dict(os.environ,
             PYTHONPATH=
             ws.find(pkg_resources.Requirement.parse('setuptools')).location
@@ -71,7 +78,7 @@
         ) == 0
 
 ws.add_entry(tmpeggs)
-ws.require('zc.buildout')
+ws.require('zc.buildout' + VERSION)
 import zc.buildout.buildout
-zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap'])
+zc.buildout.buildout.main(args)
 shutil.rmtree(tmpeggs)

Modified: zc.buildout/branches/help-api/setup.py
===================================================================
--- zc.buildout/branches/help-api/setup.py	2009-07-13 15:12:48 UTC (rev 101851)
+++ zc.buildout/branches/help-api/setup.py	2009-07-13 15:13:00 UTC (rev 101852)
@@ -12,7 +12,7 @@
 #
 ##############################################################################
 
-version = "1.2.1dev"
+version = "1.3.1dev"
 
 import os
 from setuptools import setup, find_packages

Added: zc.buildout/branches/help-api/src/zc/buildout/bootstrap.txt
===================================================================
--- zc.buildout/branches/help-api/src/zc/buildout/bootstrap.txt	                        (rev 0)
+++ zc.buildout/branches/help-api/src/zc/buildout/bootstrap.txt	2009-07-13 15:13:00 UTC (rev 101852)
@@ -0,0 +1,123 @@
+Make sure the bootstrap script actually works::
+
+    >>> import os, sys
+    >>> from os.path import dirname, join
+    >>> import zc.buildout
+    >>> bootstrap_py = join(
+    ...    dirname(
+    ...     dirname(
+    ...      dirname(
+    ...       dirname(zc.buildout.__file__)
+    ...        )
+    ...      )
+    ...    ),
+    ...   'bootstrap', 'bootstrap.py')
+    >>> sample_buildout = tmpdir('sample')
+    >>> os.chdir(sample_buildout)
+    >>> write('buildout.cfg',
+    ... '''
+    ... [buildout]
+    ... parts =
+    ... ''')
+    >>> write('bootstrap.py', open(bootstrap_py).read())
+    >>> print 'X'; print system(
+    ...     zc.buildout.easy_install._safe_arg(sys.executable)+' '+
+    ...     'bootstrap.py'); print 'X' # doctest: +ELLIPSIS
+    X...
+    Creating directory '/sample/bin'.
+    Creating directory '/sample/parts'.
+    Creating directory '/sample/eggs'.
+    Creating directory '/sample/develop-eggs'.
+    Generated script '/sample/bin/buildout'.
+    ...
+
+    >>> ls(sample_buildout)
+    d  bin
+    -  bootstrap.py
+    -  buildout.cfg
+    d  develop-eggs
+    d  eggs
+    d  parts
+
+
+    >>> ls(sample_buildout, 'bin')
+    -  buildout
+
+    >>> print 'X'; ls(sample_buildout, 'eggs') # doctest: +ELLIPSIS
+    X...
+    d  zc.buildout-...egg
+
+Now trying the `--version` option, that let 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(
+    ...     zc.buildout.easy_install._safe_arg(sys.executable)+' '+
+    ...     'bootstrap.py --version UNKNOWN'); print 'X' # doctest: +ELLIPSIS
+    ...
+    X
+    No local packages or download links found for zc.buildout==UNKNOWN
+    error: Could not find suitable distribution for Requirement.parse('zc.buildout==UNKNOWN')
+    ...
+
+Now let's try with `1.1.2`, which happens to exist::
+
+    >>> print 'X'; print system(
+    ...     zc.buildout.easy_install._safe_arg(sys.executable)+' '+
+    ...     'bootstrap.py --version 1.1.2'); print 'X'
+    ...
+    X
+    Generated script '/sample/bin/buildout'.
+    <BLANKLINE>
+    X
+
+Let's make sure the generated `buildout` script uses it::
+
+    >>> 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/eggs/setuptools-...egg',
+      '/sample/eggs/zc.buildout-1.1.2...egg',
+      ]
+    <BLANKLINE>
+    import zc.buildout.buildout
+    <BLANKLINE>
+    if __name__ == '__main__':
+        zc.buildout.buildout.main()
+    <BLANKLINE>
+
+Let's try with `1.2.1`::
+
+    >>> print 'X'; print system(
+    ...     zc.buildout.easy_install._safe_arg(sys.executable)+' '+
+    ...     'bootstrap.py --version 1.2.1'); print 'X' # doctest: +ELLIPSIS
+    ...
+    X
+    Generated script '/sample/bin/buildout'.
+    <BLANKLINE>
+    X
+
+Let's make sure the generated `buildout` script uses it::
+
+    >>> print open(buildout_script).read() # doctest: +ELLIPSIS
+    #...
+    <BLANKLINE>
+    import sys
+    sys.path[0:0] = [
+      '/sample/eggs/setuptools-...egg',
+      '/sample/eggs/zc.buildout-1.2.1...egg',
+      ]
+    <BLANKLINE>
+    import zc.buildout.buildout
+    <BLANKLINE>
+    if __name__ == '__main__':
+        zc.buildout.buildout.main()
+    <BLANKLINE>
+
+

Modified: zc.buildout/branches/help-api/src/zc/buildout/buildout.py
===================================================================
--- zc.buildout/branches/help-api/src/zc/buildout/buildout.py	2009-07-13 15:12:48 UTC (rev 101851)
+++ zc.buildout/branches/help-api/src/zc/buildout/buildout.py	2009-07-13 15:13:00 UTC (rev 101852)
@@ -81,7 +81,7 @@
                  user_defaults=True, windows_restart=False, command=None):
 
         __doing__ = 'Initializing.'
-        
+
         self.__windows_restart = windows_restart
 
         # default options
@@ -136,7 +136,7 @@
         # because while parsing options those attributes might be
         # used already (Gottfried Ganssauge)
         buildout_section = data.get('buildout')
-            
+
         # Try to make sure we have absolute paths for standard
         # directories. We do this before doing substitutions, in case
         # a one of these gets read by another section.  If any
@@ -153,13 +153,13 @@
 
         allow_hosts = buildout_section and buildout_section.get(
              'allow-hosts', '*').split('\n')
-        self._allow_hosts = tuple([host.strip() for host in allow_hosts 
+        self._allow_hosts = tuple([host.strip() for host in allow_hosts
                                    if host.strip() != ''])
 
         self._logger = logging.getLogger('zc.buildout')
         self.offline = False
         self.newest = True
-        
+
         ##################################################################
         ## WARNING!!!
         ## ALL ATTRIBUTES MUST HAVE REASONABLE DEFAULTS AT THIS POINT
@@ -171,11 +171,15 @@
         # now reinitialize
         links = options.get('find-links', '')
         self._links = links and links.split() or ()
-        
+
         allow_hosts = options.get('allow-hosts', '*').split('\n')
-        self._allow_hosts = tuple([host.strip() for host in allow_hosts 
+        self._allow_hosts = tuple([host.strip() for host in allow_hosts
                                    if host.strip() != ''])
 
+        allow_hosts = options.get('allow-hosts', '*').split('\n')
+        self._allow_hosts = tuple([host.strip() for host in allow_hosts
+                                   if host.strip() != ''])
+
         self._buildout_dir = options['directory']
 
         # Make sure we have absolute paths for standard directories.  We do this
@@ -215,7 +219,7 @@
             self._error('Invalid value for prefer-final option: %s',
                         prefer_final)
         zc.buildout.easy_install.prefer_final(prefer_final=='true')
-        
+
         use_dependency_links = options.get('use-dependency-links', 'true')
         if use_dependency_links not in ('true', 'false'):
             self._error('Invalid value for use-dependency-links option: %s',
@@ -242,7 +246,7 @@
             download_cache = os.path.join(download_cache, 'dist')
             if not os.path.isdir(download_cache):
                 os.mkdir(download_cache)
-                
+
             zc.buildout.easy_install.download_cache(download_cache)
 
         install_from_cache = options.get('install-from-cache')
@@ -334,7 +338,7 @@
         installed_develop_eggs = self._develop()
         installed_part_options['buildout']['installed_develop_eggs'
                                            ] = installed_develop_eggs
-        
+
         if installed_exists:
             self._update_installed(
                 installed_develop_eggs=installed_develop_eggs)
@@ -344,7 +348,7 @@
         conf_parts = conf_parts and conf_parts.split() or []
         installed_parts = installed_part_options['buildout']['parts']
         installed_parts = installed_parts and installed_parts.split() or []
-        
+
         if install_args:
             install_parts = install_args
             uninstall_missing = False
@@ -360,11 +364,11 @@
         if self._log_level < logging.DEBUG:
             sections = list(self)
             sections.sort()
-            print    
+            print
             print 'Configuration data:'
             for section in self._data:
                 _save_options(section, self[section], sys.stdout)
-            print    
+            print
 
 
         # compute new part recipe signatures
@@ -492,7 +496,7 @@
 
             if need_to_save_installed:
                 installed_part_options['buildout']['parts'] = (
-                    ' '.join(installed_parts))            
+                    ' '.join(installed_parts))
                 self._save_installed_options(installed_part_options)
                 installed_exists = True
             else:
@@ -505,6 +509,8 @@
         elif (not installed_parts) and installed_exists:
             os.remove(self['buildout']['installed'])
 
+        self._unload_extensions()
+
     def _update_installed(self, **buildout_options):
         installed = self['buildout']['installed']
         f = open(installed, 'a')
@@ -532,7 +538,6 @@
         self._uninstall(
             installed_part_options[part]['__buildout_installed__'])
 
-
     def _setup_directories(self):
         __doing__ = 'Setting up buildout directories'
 
@@ -563,7 +568,8 @@
                     setup = self._buildout_path(setup)
                     files = glob.glob(setup)
                     if not files:
-                        self._logger.warn("Couldn't develop %r (not found)", setup)
+                        self._logger.warn("Couldn't develop %r (not found)",
+                                          setup)
                     else:
                         files.sort()
                     for setup in files:
@@ -580,7 +586,7 @@
                      if f not in old_files
                      ]))
                 raise
-                     
+
             else:
                 self._sanity_check_develop_eggs_files(dest, old_files)
                 return '\n'.join([os.path.join(dest, f)
@@ -627,7 +633,7 @@
                             value = value.replace(k, v)
                     options[option] = value
                 result[section] = Options(self, section, options)
-                        
+
             return result, True
         else:
             return ({'buildout': Options(self, 'buildout', {'parts': ''})},
@@ -655,8 +661,8 @@
                         # Sigh. This is the exectable used to run the buildout
                         # and, of course, it's in use. Leave it.
                         ):
-                        raise                    
-                
+                        raise
+
     def _install(self, part):
         options = self[part]
         recipe, entry = _recipe(options)
@@ -700,7 +706,7 @@
             buildout_handler.setFormatter(logging.Formatter('%(message)s'))
             self._logger.propagate = False
             self._logger.addHandler(buildout_handler)
-            
+
         handler.setFormatter(logging.Formatter(log_format))
         root_logger.addHandler(handler)
 
@@ -729,7 +735,7 @@
 
         if not self.newest:
             return
-        
+
         ws = zc.buildout.easy_install.install(
             [
             (spec + ' ' + self['buildout'].get(spec+'-version', '')).strip()
@@ -773,8 +779,8 @@
             if not __debug__:
                 args.insert(0, '-O')
             args.insert(0, zc.buildout.easy_install._safe_arg (sys.executable))
-            os.execv(sys.executable, args)            
-        
+            os.execv(sys.executable, args)
+
         self._logger.info("Upgraded:\n  %s;\nrestarting.",
                           ",\n  ".join([("%s version %s"
                                        % (dist.project_name, dist.version)
@@ -783,7 +789,7 @@
                                       ]
                                      ),
                           )
-                
+
         # the new dist is different, so we've upgraded.
         # Update the scripts and return True
         zc.buildout.easy_install.scripts(
@@ -830,6 +836,14 @@
             for ep in pkg_resources.iter_entry_points('zc.buildout.extension'):
                 ep.load()(self)
 
+    def _unload_extensions(self):
+        __doing__ = 'Unloading extensions.'
+        specs = self['buildout'].get('extensions', '').split()
+        if specs:
+            for ep in pkg_resources.iter_entry_points(
+                'zc.buildout.unloadextension'):
+                ep.load()(self)
+
     def setup(self, args):
         if not args:
             raise zc.buildout.UserError(
@@ -853,13 +867,13 @@
                 ))
             if is_jython:
                 arg_list = list()
-                
+
                 for a in args:
                     add_args.append(zc.buildout.easy_install._safe_arg(a))
-                
+
                 subprocess.Popen([zc.buildout.easy_install._safe_arg(sys.executable)] + list(tsetup) +
                                 arg_list).wait()
-            
+
             else:
                 os.spawnl(os.P_WAIT, sys.executable, zc.buildout.easy_install._safe_arg (sys.executable), tsetup,
                         *[zc.buildout.easy_install._safe_arg(a)
@@ -885,7 +899,7 @@
         options = Options(self, section, data)
         self._data[section] = options
         options._initialize()
-        return options          
+        return options
 
     def __setitem__(self, key, value):
         raise NotImplementedError('__setitem__')
@@ -910,7 +924,7 @@
     def _get_recipe_with_version(self, name):
         #if the recipe version is specified in versions section,
         #do nothing
-        if (self.versions and 
+        if (self.versions and
                 name in self[self.versions].keys()):
             return name
         else:
@@ -962,7 +976,7 @@
         else:
             line_2_len = len(lines[1])
             spaces = line_2_len - len(lines[1].lstrip())
-            lines[0] = ' '*spaces + lines[0] 
+            lines[0] = ' '*spaces + lines[0]
             if lines[-1].strip() == '':
                 lines = lines[:-1]
             for line in lines:
@@ -973,10 +987,10 @@
 
     def has_multiple_entry_points(self):
         entries = list(pkg_resources.iter_entry_points('zc.buildout'))
- 
-        self.entry_points = [entry_point for entry_point in 
+
+        self.entry_points = [entry_point for entry_point in
                         entries if entry_point.dist.project_name == self.name]
-        
+
         return len(self.entry_points) > 1
 
     def print_multiple_entry_points(self):
@@ -1038,7 +1052,7 @@
     def _initialize(self):
         name = self.name
         __doing__ = 'Initializing section %s.', name
-        
+
         # force substitutions
         for k, v in self._raw.items():
             if '${' in v:
@@ -1046,11 +1060,11 @@
 
         if self.name == 'buildout':
             return # buildout section can never be a part
-        
+
         recipe = self.get('recipe')
         if not recipe:
             return
-        
+
         reqs, entry = _recipe(self._data)
         buildout = self.buildout
         recipe_class = _install_and_load(reqs, 'zc.buildout', entry, buildout)
@@ -1122,7 +1136,7 @@
                         "The option name in substitution, %s,\n"
                         "has invalid characters."
                         % ref)
-                
+
             v = self.buildout[s[0]].get(s[1], None, seen)
             if v is None:
                 raise MissingOption("Referenced option does not exist:", *s)
@@ -1130,7 +1144,7 @@
         subs.append('')
 
         return ''.join([''.join(v) for v in zip(value[::2], subs)])
-        
+
     def __getitem__(self, key):
         try:
             return self._data[key]
@@ -1234,7 +1248,7 @@
     if value.endswith('\n\t'):
         value = value[:-2] + '%(__buildout_space_n__)s'
     print >>f, option, '=', value
-    
+
 def _save_options(section, options, f):
     print >>f, '[%s]' % section
     items = options.items()
@@ -1297,8 +1311,8 @@
 
     seen.pop()
     return result
-    
 
+
 ignore_directories = '.svn', 'CVS'
 def _dir_hash(dir):
     hash = md5()
@@ -1313,7 +1327,7 @@
         for name in filenames:
             hash.update(open(os.path.join(dirpath, name)).read())
     return hash.digest().encode('base64').strip()
-    
+
 def _dists_sig(dists):
     result = []
     for dist in dists:
@@ -1335,7 +1349,7 @@
             s2[key] = "\n".join([v for v in s1.get(key, "").split('\n')
                                  if v not in s2[k].split('\n')])
             del s2[k]
-                
+
     s1.update(s2)
     return s1
 
@@ -1365,7 +1379,7 @@
         if d:
             doing.append(d)
         tb = tb.tb_next
-        
+
     if doing:
         sys.stderr.write('While:\n')
         for d in doing:
@@ -1422,13 +1436,13 @@
      Don't read user defaults.
 
   -o
-  
-    Run in off-line mode.  This is equivalent to the assignment 
+
+    Run in off-line mode.  This is equivalent to the assignment
     buildout:offline=true.
 
   -O
 
-    Run in non-off-line mode.  This is equivalent to the assignment 
+    Run in non-off-line mode.  This is equivalent to the assignment
     buildout:offline=false.  This is the default buildout mode.  The
     -O option would normally be used to override a true offline
     setting in a configuration file.
@@ -1442,10 +1456,10 @@
 
   -N
 
-    Run in non-newest mode.  This is equivalent to the assignment 
+    Run in non-newest mode.  This is equivalent to the assignment
     buildout:newest=false.  With this setting, buildout will not seek
     new distributions if installed distributions satisfy it's
-    requirements. 
+    requirements.
 
   -D
 
@@ -1495,7 +1509,7 @@
 
     The script can be given either as a script path or a path to a
     directory containing a setup.py script.
-    
+
 """
 def _help():
     print _usage
@@ -1537,7 +1551,7 @@
                 else:
                     _help()
                 op = op[1:]
-                
+
             if op[:1] in  ('c', 't'):
                 op_ = op[:1]
                 op = op[1:]
@@ -1614,10 +1628,10 @@
                     sys.stderr.write(_internal_error_template)
                     traceback.print_exception(*exc_info)
                     sys.exit(1)
-    
-            
+
+
     finally:
-            logging.shutdown()
+        logging.shutdown()
 
 if sys.version_info[:2] < (2, 4):
     def reversed(iterable):

Modified: zc.buildout/branches/help-api/src/zc/buildout/buildout.txt
===================================================================
--- zc.buildout/branches/help-api/src/zc/buildout/buildout.txt	2009-07-13 15:12:48 UTC (rev 101851)
+++ zc.buildout/branches/help-api/src/zc/buildout/buildout.txt	2009-07-13 15:13:00 UTC (rev 101852)
@@ -2368,15 +2368,17 @@
 Extensions
 ----------
 
-An **experimental** feature allows code to be loaded and run after
+A feature allows code to be loaded and run after
 configuration files have been read but before the buildout has begun
 any processing.  The intent is to allow special plugins such as
 urllib2 request handlers to be loaded.
 
 To load an extension, we use the extensions option and list one or
 more distribution requirements, on separate lines.  The distributions
-named will be loaded and any zc.buildout.extensions entry points found
-will be called with the buildout as an argument.
+named will be loaded and any ``zc.buildout.extension`` entry points found
+will be called with the buildout as an argument.  When buildout
+finishes processing, any ``zc.buildout.unloadextension`` entry points
+found will be called with the buildout as an argument.
 
 Let's create a sample extension in our sample buildout created in the
 previous section:
@@ -2387,6 +2389,8 @@
     ... """
     ... def ext(buildout):
     ...     print 'ext', list(buildout)
+    ... def unload(buildout):
+    ...     print 'unload', list(buildout)
     ... """)
 
     >>> write(sample_bootstrapped, 'demo', 'setup.py',
@@ -2395,7 +2399,10 @@
     ...
     ... setup(
     ...     name = "demo",
-    ...     entry_points = {'zc.buildout.extension': ['ext = demo:ext']},
+    ...     entry_points = {
+    ...        'zc.buildout.extension': ['ext = demo:ext'],
+    ...        'zc.buildout.unloadextension': ['ext = demo:unload'],
+    ...        },
     ...     )
     ... """)
 
@@ -2436,6 +2443,7 @@
     >>> print system(os.path.join(sample_bootstrapped, 'bin', 'buildout')),
     ext ['buildout']
     Develop: '/sample-bootstrapped/demo'
+    unload ['buildout']
 
 Allow hosts
 -----------

Modified: zc.buildout/branches/help-api/src/zc/buildout/easy_install.py
===================================================================
--- zc.buildout/branches/help-api/src/zc/buildout/easy_install.py	2009-07-13 15:12:48 UTC (rev 101851)
+++ zc.buildout/branches/help-api/src/zc/buildout/easy_install.py	2009-07-13 15:13:00 UTC (rev 101852)
@@ -967,9 +967,10 @@
 
 def _relative_path_and_setup(sname, path, relative_paths):
     if relative_paths:
-        sname = os.path.abspath(sname)
+        relative_paths = os.path.normcase(relative_paths)
+        sname = os.path.normcase(os.path.abspath(sname))
         spath = ',\n  '.join(
-            [_relativitize(path_item, sname, relative_paths)
+            [_relativitize(os.path.normcase(path_item), sname, relative_paths)
              for path_item in path]
             )
         rpsetup = relative_paths_setup
@@ -1022,7 +1023,7 @@
 import os
 
 join = os.path.join
-base = os.path.dirname(__file__)
+base = os.path.dirname(os.path.abspath(__file__))
 """
 
 def _script(module_name, attrs, path, dest, executable, arguments,
@@ -1245,4 +1246,3 @@
                     subprocess.call([sys.executable, args])
                 else:
                     os.spawnv(os.P_WAIT, sys.executable, args)
-

Modified: zc.buildout/branches/help-api/src/zc/buildout/easy_install.txt
===================================================================
--- zc.buildout/branches/help-api/src/zc/buildout/easy_install.txt	2009-07-13 15:12:48 UTC (rev 101851)
+++ zc.buildout/branches/help-api/src/zc/buildout/easy_install.txt	2009-07-13 15:13:00 UTC (rev 101852)
@@ -717,9 +717,10 @@
 We can pass a keyword argument, extra paths, to cause additional paths
 to be included in the a generated script:
 
+    >>> foo = tmpdir('foo')
     >>> scripts = zc.buildout.easy_install.scripts(
     ...    ['demo'], ws, sys.executable, bin, dict(demo='run'),
-    ...    extra_paths=['/foo/bar'])
+    ...    extra_paths=[foo])
 
     >>> cat(bin, 'run') # doctest: +NORMALIZE_WHITESPACE
     #!/usr/local/bin/python2.4
@@ -728,7 +729,7 @@
     sys.path[0:0] = [
       '/sample-install/demo-0.3-py2.4.egg',
       '/sample-install/demoneeded-1.1-py2.4.egg',
-      '/foo/bar',
+      '/foo',
       ]
     <BLANKLINE>
     import eggrecipedemo
@@ -795,6 +796,7 @@
 to pass a common base directory of the scripts and eggs:
 
     >>> bo = tmpdir('bo')
+    >>> ba = tmpdir('ba')
     >>> mkdir(bo, 'eggs')
     >>> mkdir(bo, 'bin')
     >>> mkdir(bo, 'other')
@@ -805,7 +807,7 @@
 
     >>> scripts = zc.buildout.easy_install.scripts(
     ...    ['demo'], ws, sys.executable, join(bo, 'bin'), dict(demo='run'),
-    ...    extra_paths=[os.path.sep+'foo', join(bo, 'bar')],
+    ...    extra_paths=[ba, join(bo, 'bar')],
     ...    interpreter='py',
     ...    relative_paths=bo)
 
@@ -815,14 +817,14 @@
     import os
     <BLANKLINE>
     join = os.path.join
-    base = os.path.dirname(__file__)
+    base = os.path.dirname(os.path.abspath(__file__))
     base = os.path.dirname(base)
     <BLANKLINE>
     import sys
     sys.path[0:0] = [
       join(base, 'eggs/demo-0.3-pyN.N.egg'),
       join(base, 'eggs/demoneeded-1.1-pyN.N.egg'),
-      '/foo',
+      '/ba',
       join(base, 'bar'),
       ]
     <BLANKLINE>
@@ -847,7 +849,7 @@
     import os
     <BLANKLINE>
     join = os.path.join
-    base = os.path.dirname(__file__)
+    base = os.path.dirname(os.path.abspath(__file__))
     base = os.path.dirname(base)
     <BLANKLINE>
     import sys
@@ -855,7 +857,7 @@
     sys.path[0:0] = [
       join(base, 'eggs/demo-0.3-pyN.N.egg'),
       join(base, 'eggs/demoneeded-1.1-pyN.N.egg'),
-      '/foo',
+      '/ba',
       join(base, 'bar'),
       ]
     <BLANKLINE>

Modified: zc.buildout/branches/help-api/src/zc/buildout/testing.py
===================================================================
--- zc.buildout/branches/help-api/src/zc/buildout/testing.py	2009-07-13 15:12:48 UTC (rev 101851)
+++ zc.buildout/branches/help-api/src/zc/buildout/testing.py	2009-07-13 15:13:00 UTC (rev 101852)
@@ -18,6 +18,7 @@
 
 import BaseHTTPServer
 import errno
+import logging
 import os
 import pkg_resources
 import random
@@ -85,6 +86,8 @@
     fsync(f.fileno())
     f.close()
 
+## FIXME - check for other platforms
+MUST_CLOSE_FDS = not sys.platform.startswith('win')
 
 def system(command, input=''):
     p = subprocess.Popen(command,
@@ -92,7 +95,7 @@
                          stdin=subprocess.PIPE,
                          stdout=subprocess.PIPE,
                          stderr=subprocess.PIPE,
-                         close_fds=not is_win32)
+                         close_fds=MUST_CLOSE_FDS)
     i, o, e = (p.stdin, p.stdout, p.stderr)
     if input:
         i.write(input)
@@ -145,7 +148,7 @@
                              stdin=subprocess.PIPE,
                              stdout=subprocess.PIPE,
                              stderr=subprocess.STDOUT,
-                             close_fds=True)
+                             close_fds=MUST_CLOSE_FDS)
         i, o = (p.stdin, p.stdout)
         i.close()
         e = o.read().strip()
@@ -158,7 +161,7 @@
                              stdin=subprocess.PIPE,
                              stdout=subprocess.PIPE,
                              stderr=subprocess.STDOUT,
-                             close_fds=True)
+                             close_fds=MUST_CLOSE_FDS)
         i, o = (p.stdin, p.stdout)
         i.close()
         e = o.read().strip()
@@ -170,7 +173,7 @@
                                 stdin=subprocess.PIPE,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.STDOUT,
-                                close_fds=True)
+                                close_fds=MUST_CLOSE_FDS)
             i, o = (p.stdin, p.stdout)
             i.close()
             e = o.read().strip()
@@ -210,8 +213,17 @@
     here = os.getcwd()
     register_teardown(lambda: os.chdir(here))
 
+    handlers_before_set_up = logging.getLogger().handlers[:]
+    def restore_root_logger_handlers():
+        root_logger = logging.getLogger()
+        for handler in root_logger.handlers[:]:
+            root_logger.removeHandler(handler)
+        for handler in handlers_before_set_up:
+            root_logger.addHandler(handler)
+    register_teardown(restore_root_logger_handlers)
 
     base = tempfile.mkdtemp('buildoutSetUp')
+    base = os.path.realpath(base)
     register_teardown(lambda base=base: rmtree(base))
 
     old_home = os.environ.get('HOME')
@@ -485,6 +497,8 @@
     _normalize_path,
     )
 
+normalize_endings = re.compile('\r\n'), '\n'
+
 normalize_script = (
     re.compile('(\n?)-  ([a-zA-Z_.-]+)-script.py\n-  \\2.exe\n'),
     '\\1-  \\2\n')

Added: zc.buildout/branches/help-api/src/zc/buildout/testing_bugfix.txt
===================================================================
--- zc.buildout/branches/help-api/src/zc/buildout/testing_bugfix.txt	                        (rev 0)
+++ zc.buildout/branches/help-api/src/zc/buildout/testing_bugfix.txt	2009-07-13 15:13:00 UTC (rev 101852)
@@ -0,0 +1,39 @@
+Bug fixes in zc.buildout.testing
+================================
+
+Logging handler which did not get deleted
+-----------------------------------------
+
+The buildout testing set up runs a buildout which adds a
+``logging.StreamHandler`` to the root logger. But tear down did not
+remove it. This can disturb other tests of packages reusing
+zc.buildout.testing.
+
+The handers before calling set up are:
+
+    >>> import logging
+    >>> len(logging.getLogger().handlers)
+    1
+    >>> logging.getLogger().handlers # doctest: +ELLIPSIS
+    [<zope.testing.testrunner.logsupport.NullHandler instance at ...>]
+
+After calling it, a ``logging.StreamHandler`` was added:
+
+    >>> import zc.buildout.testing
+    >>> import doctest
+    >>> test = doctest.DocTestParser().get_doctest(
+    ...     '>>> x', {}, 'foo', 'foo.py', 0)
+    >>> zc.buildout.testing.buildoutSetUp(test)
+    >>> len(logging.getLogger().handlers)
+    2
+    >>> logging.getLogger().handlers # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
+    [<zope.testing.testrunner.logsupport.NullHandler instance at ...>,
+     <logging.StreamHandler instance at ...>]
+
+But tear down removes the new logging handler:
+
+    >>> zc.buildout.testing.buildoutTearDown(test)
+    >>> len(logging.getLogger().handlers)
+    1
+    >>> logging.getLogger().handlers # doctest: +ELLIPSIS
+    [<zope.testing.testrunner.logsupport.NullHandler instance at ...>]

Modified: zc.buildout/branches/help-api/src/zc/buildout/tests.py
===================================================================
--- zc.buildout/branches/help-api/src/zc/buildout/tests.py	2009-07-13 15:12:48 UTC (rev 101851)
+++ zc.buildout/branches/help-api/src/zc/buildout/tests.py	2009-07-13 15:13:00 UTC (rev 101852)
@@ -43,7 +43,7 @@
     ... '''
     ... [buildout]
     ... develop = foo
-    ... parts = 
+    ... parts =
     ... ''')
 
     >>> print system(join('bin', 'buildout')),
@@ -70,7 +70,7 @@
     ... '''
     ... [buildout]
     ... develop = foo
-    ... parts = 
+    ... parts =
     ... ''')
 
     >>> print system(join('bin', 'buildout')+' -vv'), # doctest: +ELLIPSIS
@@ -265,9 +265,9 @@
     requirements.
 
     >>> make_dist_that_requires(sample_buildout, 'sampley',
-    ...                         ['demoneeded ==1.0']) 
+    ...                         ['demoneeded ==1.0'])
     >>> make_dist_that_requires(sample_buildout, 'samplez',
-    ...                         ['demoneeded ==1.1']) 
+    ...                         ['demoneeded ==1.1'])
 
     Now, let's create a buildout that requires y and z:
 
@@ -299,7 +299,7 @@
     Here, we see that sampley required an older version of demoneeded.
     What if we hadn't required sampley ourselves:
 
-    >>> make_dist_that_requires(sample_buildout, 'samplea', ['sampleb']) 
+    >>> make_dist_that_requires(sample_buildout, 'samplea', ['sampleb'])
     >>> make_dist_that_requires(sample_buildout, 'sampleb',
     ...                         ['sampley', 'samplea'])
     >>> write('buildout.cfg',
@@ -354,8 +354,8 @@
     Fortunately, buildout will tell us who's asking for something that
     we can't find.
 
-    >>> make_dist_that_requires(sample_buildout, 'sampley', ['demoneeded']) 
-    >>> make_dist_that_requires(sample_buildout, 'samplea', ['sampleb']) 
+    >>> make_dist_that_requires(sample_buildout, 'sampley', ['demoneeded'])
+    >>> make_dist_that_requires(sample_buildout, 'samplea', ['sampleb'])
     >>> make_dist_that_requires(sample_buildout, 'sampleb',
     ...                         ['sampley', 'samplea'])
     >>> write('buildout.cfg',
@@ -381,15 +381,15 @@
       Getting distribution for 'demoneeded'.
     Error: Couldn't find a distribution for 'demoneeded'.
     """
-    
- 
+
+
 def test_comparing_saved_options_with_funny_characters():
     """
     If an option has newlines, extra/odd spaces or a %, we need to make
     sure the comparison with the saved value works correctly.
 
     >>> mkdir(sample_buildout, 'recipes')
-    >>> write(sample_buildout, 'recipes', 'debug.py', 
+    >>> write(sample_buildout, 'recipes', 'debug.py',
     ... '''
     ... class Debug:
     ...     def __init__(self, buildout, name, options):
@@ -399,7 +399,7 @@
     ...     path foo
     ...   </filestorage>
     ...
-    ... </zodb>  
+    ... </zodb>
     ...      \"\"\"
     ...         options['debug1'] = \"\"\"
     ... <zodb>
@@ -408,7 +408,7 @@
     ...     path foo
     ...   </filestorage>
     ...
-    ... </zodb>  
+    ... </zodb>
     ... \"\"\"
     ...         options['debug2'] = '  x  '
     ...         options['debug3'] = '42'
@@ -468,7 +468,7 @@
     ... '''
     ... from setuptools import setup
     ... setup(name='demo', py_modules=[''],
-    ...    zip_safe=False, version='1.0', author='bob', url='bob', 
+    ...    zip_safe=False, version='1.0', author='bob', url='bob',
     ...    author_email='bob')
     ... ''')
 
@@ -480,7 +480,7 @@
 
     >>> d1 = tmpdir('d1')
     >>> ws = zc.buildout.easy_install.install(
-    ...     ['demo'], d1, links=[join(src, 'dist')], 
+    ...     ['demo'], d1, links=[join(src, 'dist')],
     ...     )
 
     >>> ls(d1)
@@ -490,7 +490,7 @@
 
     >>> d2 = tmpdir('d2')
     >>> ws = zc.buildout.easy_install.install(
-    ...     ['demo'], d2, links=[d1], 
+    ...     ['demo'], d2, links=[d1],
     ...     )
 
     >>> ls(d2)
@@ -524,7 +524,7 @@
     ... '''
     ... [buildout]
     ... develop = demo
-    ... parts = 
+    ... parts =
     ... ''')
 
     >>> print system(join('bin', 'buildout')),
@@ -562,60 +562,8 @@
     [foo]
     bar = 1
     ...
-    
     """
 
-bootstrap_py = os.path.join(
-       os.path.dirname(
-          os.path.dirname(
-             os.path.dirname(
-                os.path.dirname(zc.buildout.__file__)
-                )
-             )
-          ),
-       'bootstrap', 'bootstrap.py')
-
-if os.path.exists(bootstrap_py):
-    def test_bootstrap_py():
-        """Make sure the bootstrap script actually works
-
-    >>> sample_buildout = tmpdir('sample')
-    >>> os.chdir(sample_buildout)
-    >>> write('buildout.cfg',
-    ... '''
-    ... [buildout]
-    ... parts =
-    ... ''')
-    >>> write('bootstrap.py', open(bootstrap_py).read())
-    >>> print 'X'; print system(
-    ...     zc.buildout.easy_install._safe_arg(sys.executable)+' '+
-    ...     'bootstrap.py'); print 'X' # doctest: +ELLIPSIS
-    X...
-    Creating directory '/sample/bin'.
-    Creating directory '/sample/parts'.
-    Creating directory '/sample/eggs'.
-    Creating directory '/sample/develop-eggs'.
-    Generated script '/sample/bin/buildout'.
-    ...
-
-    >>> ls(sample_buildout)
-    d  bin
-    -  bootstrap.py
-    -  buildout.cfg
-    d  develop-eggs
-    d  eggs
-    d  parts
-
-
-    >>> ls(sample_buildout, 'bin')
-    -  buildout
-
-    >>> print 'X'; ls(sample_buildout, 'eggs') # doctest: +ELLIPSIS
-    X...
-    d  zc.buildout-1.0-py2.4.egg
-
-    """
-
 def test_help():
     """
     >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')+' -h'),
@@ -640,12 +588,12 @@
 
 def test_describe():
     """
-    The describe command shows an arbitrary 
+    The describe command shows an arbitrary
     recipe's class docstring used in the buildout.
-  
+
     Let's call describe for zc.recipe.egg:
 
-    >>> print system('%s describe zc.recipe.egg' % buildout)  
+    >>> print system('%s describe zc.recipe.egg' % buildout)
     zc.recipe.egg
         No description available
     <BLANKLINE>
@@ -660,9 +608,9 @@
     <BLANKLINE>
 
     Now let's create our own recipe:
-    
+
     >>> mkdir(sample_buildout, 'my.recipes')
-    >>> write(sample_buildout, 'my.recipes', 'recipe.py', 
+    >>> write(sample_buildout, 'my.recipes', 'recipe.py',
     ... '''
     ... class MyRecipe:
     ...     def __init__(self, buildout, name, options):
@@ -680,7 +628,7 @@
     ... from setuptools import setup
     ... setup(
     ...     name = "my.recipes",
-    ...     entry_points = {'zc.buildout': 
+    ...     entry_points = {'zc.buildout':
     ...                      ['default = recipe:MyRecipe']},
     ...     )
     ... ''')
@@ -702,14 +650,14 @@
     Develop: '/sample-buildout/my.recipes'
     Installing my-recipe.
 
-    >>> print system('%s describe my.recipes' % buildout) 
+    >>> print system('%s describe my.recipes' % buildout)
     my.recipes
         No description available
     <BLANKLINE>
 
     Let's add a docstring now:
 
-    >>> write(sample_buildout, 'my.recipes', 'recipe.py', 
+    >>> write(sample_buildout, 'my.recipes', 'recipe.py',
     ... '''
     ... class MyRecipe:
     ...     \"\"\"The coolest recipe on Earth.
@@ -724,7 +672,7 @@
     ...     update = install
     ... ''')
 
-    >>> print system('%s describe my.recipes' % buildout) 
+    >>> print system('%s describe my.recipes' % buildout)
     my.recipes
         The coolest recipe on Earth.
         Ever.
@@ -737,14 +685,14 @@
     ... from setuptools import setup
     ... setup(
     ...     name = "my.recipes",
-    ...     entry_points = {'zc.buildout': 
+    ...     entry_points = {'zc.buildout':
     ...                      ['default = recipe:MyRecipe',
     ...                       'second = second:OtherRecipe']},
     ...     )
     ... ''')
 
 
-    >>> write(sample_buildout, 'my.recipes', 'second.py', 
+    >>> write(sample_buildout, 'my.recipes', 'second.py',
     ... '''
     ... class OtherRecipe:
     ...     def __init__(self, buildout, name, options):
@@ -770,13 +718,13 @@
     We have to run the buildout again, because the recipe
     here is a develop, to be able to test the egg itself:
 
-    >>> print system(buildout) 
+    >>> print system(buildout)
     Develop: '/sample-buildout/my.recipes'
     Uninstalling my-recipe.
     Installing my-recipe.
     <BLANKLINE>
 
-    >>> print system('%s describe my.recipes' % buildout) 
+    >>> print system('%s describe my.recipes' % buildout)
     my.recipes
         No description available
     <BLANKLINE>
@@ -786,18 +734,18 @@
         second
     <BLANKLINE>
 
-    >>> print system('%s describe my.recipes:default' % buildout) 
+    >>> print system('%s describe my.recipes:default' % buildout)
     my.recipes:default
         The coolest recipe on Earth.
         Ever.
     <BLANKLINE>
 
-    >>> print system('%s describe my.recipes:second' % buildout) 
+    >>> print system('%s describe my.recipes:second' % buildout)
     my.recipes:second
         No description available
     <BLANKLINE>
 
-    >>> print system('%s describe my.recipes:default my.recipes:second' % buildout) 
+    >>> print system('%s describe my.recipes:default my.recipes:second' % buildout)
     my.recipes:default
         The coolest recipe on Earth.
         Ever.
@@ -807,7 +755,7 @@
 
     Let's call describe for an egg that cannot be installed:
 
-    >>> print system('%s describe foo.bar' % buildout)  
+    >>> print system('%s describe foo.bar' % buildout)
     Couldn't find index page for 'foo.bar' (maybe misspelled?)
     Getting distribution for 'foo.bar'.
     While:
@@ -822,7 +770,7 @@
     Let's create an egg that is not a recipe.
 
     >>> mkdir(sample_buildout, 'my_egg')
-    >>> write(sample_buildout, 'my_egg', 'egg.py', 
+    >>> write(sample_buildout, 'my_egg', 'egg.py',
     ... '''
     ... class MyEgg:
     ...     pass
@@ -856,7 +804,7 @@
 
     Let's ask its description:
 
-    >>> print system('%s describe my.egg' % buildout) 
+    >>> print system('%s describe my.egg' % buildout)
     'my.egg' is not a recipe.
     <BLANKLINE>
 
@@ -869,9 +817,9 @@
     handles this correctly.
 
     Now let's create our own recipe:
-    
+
     >>> mkdir('myrecipes')
-    >>> write('myrecipes', 'recipe.py', 
+    >>> write('myrecipes', 'recipe.py',
     ... '''
     ... class MyRecipe:
     ...     "my.recipes 0.1.3"
@@ -892,7 +840,7 @@
     ...     version = '0.1.3',
     ...     name = "my.recipes",
     ...     py_modules=['recipe'],
-    ...     entry_points = {'zc.buildout': 
+    ...     entry_points = {'zc.buildout':
     ...                      ['default = recipe:MyRecipe']},
     ...     )
     ... ''')
@@ -923,7 +871,7 @@
 
     Let's check the describe call:
 
-    >>> print system('%s describe my.recipes' % buildout) 
+    >>> print system('%s describe my.recipes' % buildout)
     Couldn't find index page for 'my.recipes' (maybe misspelled?)
     my.recipes
         my.recipes 0.1.3
@@ -938,7 +886,7 @@
     ...     version = '0.1.4',
     ...     name = "my.recipes",
     ...     py_modules=['recipe'],
-    ...     entry_points = {'zc.buildout': 
+    ...     entry_points = {'zc.buildout':
     ...                      ['default = recipe:MyRecipe']},
     ...     )
     ... ''')
@@ -946,7 +894,7 @@
 
     We change the docstring as well:
 
-    >>> write('myrecipes', 'recipe.py', 
+    >>> write('myrecipes', 'recipe.py',
     ... '''
     ... class MyRecipe:
     ...     "my.recipes 0.1.4"
@@ -974,8 +922,8 @@
 
 
     Let's try the describe command now:
-    
-    >>> print system('%s describe my.recipes' % buildout) 
+
+    >>> print system('%s describe my.recipes' % buildout)
     Couldn't find index page for 'my.recipes' (maybe misspelled?)
     my.recipes
         my.recipes 0.1.4
@@ -991,7 +939,7 @@
     ... recipe = my.recipes == 0.1.4
     ... ''')
 
-    >>> print system('%s describe my.recipes' % buildout) 
+    >>> print system('%s describe my.recipes' % buildout)
     my.recipes
         my.recipes 0.1.4
     <BLANKLINE>
@@ -1004,7 +952,7 @@
     ... recipe = my.recipes == 0.1.3
     ... ''')
 
-    >>> print system('%s describe my.recipes' % buildout) 
+    >>> print system('%s describe my.recipes' % buildout)
     my.recipes
         my.recipes 0.1.3
     <BLANKLINE>
@@ -1023,7 +971,7 @@
     ... recipe = my.recipes
     ... ''')
 
-    >>> print system('%s describe my.recipes' % buildout) 
+    >>> print system('%s describe my.recipes' % buildout)
     my.recipes
         my.recipes 0.1.3
     <BLANKLINE>
@@ -1039,7 +987,7 @@
     ... recipe = my.recipes
     ... ''')
 
-    >>> print system('%s describe my.recipes' % buildout) 
+    >>> print system('%s describe my.recipes' % buildout)
     my.recipes
         my.recipes 0.1.4
     <BLANKLINE>
@@ -1055,12 +1003,12 @@
 bootstrapping.
 
     >>> d = tmpdir('sample-bootstrap')
-    
+
     >>> write(d, 'buildout.cfg',
     ... '''
     ... [buildout]
     ... extensions = some_awsome_extension
-    ... parts = 
+    ... parts =
     ... ''')
 
     >>> os.chdir(d)
@@ -1077,7 +1025,7 @@
 def bug_92891_bootstrap_crashes_with_egg_recipe_in_buildout_section():
     """
     >>> d = tmpdir('sample-bootstrap')
-    
+
     >>> write(d, 'buildout.cfg',
     ... '''
     ... [buildout]
@@ -1188,7 +1136,7 @@
 
 
 def add_setuptools_to_dependencies_when_namespace_packages():
-    '''    
+    '''
 Often, a package depends on setuptools soley by virtue of using
 namespace packages. In this situation, package authors often forget to
 declare setuptools as a dependency. This is a mistake, but,
@@ -1215,12 +1163,12 @@
     ...       )
     ... """)
     >>> write('foo', 'README.txt', '')
-    
+
     >>> write('buildout.cfg',
     ... """
     ... [buildout]
     ... develop = foo
-    ... parts = 
+    ... parts =
     ... """)
 
     >>> print system(join('bin', 'buildout')),
@@ -1233,7 +1181,7 @@
     >>> handler = zope.testing.loggingsupport.InstalledHandler(
     ...        'zc.buildout.easy_install', level=logging.WARNING)
     >>> logging.getLogger('zc.buildout.easy_install').propagate = False
-    
+
     >>> [dist.project_name
     ...  for dist in zc.buildout.easy_install.working_set(
     ...    ['foox'], sys.executable,
@@ -1258,11 +1206,11 @@
 
     >>> ls('develop-eggs')
     -  zc.recipe.egg.egg-link
-    
+
     >>> ls('eggs') # doctest: +ELLIPSIS
     -  foox-0.0.0-py2.4.egg
     ...
-    
+
 We do not get a warning, but we do get setuptools included in the working set:
 
     >>> [dist.project_name
@@ -1286,12 +1234,12 @@
     ... setup(name='bar', install_requires = ['foox'])
     ... """)
     >>> write('bar', 'README.txt', '')
-    
+
     >>> write('buildout.cfg',
     ... """
     ... [buildout]
     ... develop = foo bar
-    ... parts = 
+    ... parts =
     ... """)
 
     >>> print system(join('bin', 'buildout')),
@@ -1319,7 +1267,7 @@
 
 def develop_preserves_existing_setup_cfg():
     """
-    
+
 See "Handling custom build options for extensions in develop eggs" in
 easy_install.txt.  This will be very similar except that we'll have an
 existing setup.cfg:
@@ -1343,7 +1291,7 @@
 
     >>> dest = tmpdir('dest')
     >>> zc.buildout.easy_install.develop(
-    ...   extdemo, dest, 
+    ...   extdemo, dest,
     ...   {'include-dirs': os.path.join(sample_buildout, 'include')})
     '/dest/extdemo.egg-link'
 
@@ -1422,7 +1370,7 @@
     >>> write('buildout.cfg', '''
     ... [buildout]
     ... develop = recipes
-    ... parts = 
+    ... parts =
     ... ''')
 
     >>> print system(join('bin', 'buildout')),
@@ -1437,7 +1385,7 @@
     '''
     >>> mkdir('demo')
 
-    >>> write('demo', 'demo.py', 
+    >>> write('demo', 'demo.py',
     ... """
     ... def ext(buildout):
     ...     print 'ext', list(buildout)
@@ -1446,7 +1394,7 @@
     >>> write('demo', 'setup.py',
     ... """
     ... from setuptools import setup
-    ... 
+    ...
     ... setup(
     ...     name = "demo",
     ...     py_modules=['demo'],
@@ -1467,13 +1415,13 @@
 
     >>> print system(join(sample_buildout, 'bin', 'buildout')),
     ext ['buildout']
-    
 
+
     '''
 
 def changes_in_svn_or_CVS_dont_affect_sig():
     """
-    
+
 If we have a develop recipe, it's signature shouldn't be affected to
 changes in .svn or CVS directories.
 
@@ -1491,13 +1439,13 @@
     ...     def install(*args): return ()
     ...     update = install
     ... ''')
-    
+
     >>> write('buildout.cfg',
     ... '''
     ... [buildout]
     ... develop = recipe
     ... parts = foo
-    ... 
+    ...
     ... [foo]
     ... recipe = recipe
     ... ''')
@@ -1543,13 +1491,13 @@
     ...     def install(*args): return ()
     ...     update = install
     ... ''')
-    
+
     >>> write('buildout.cfg',
     ... '''
     ... [buildout]
     ... develop = recipe
     ... parts = foo
-    ... 
+    ...
     ... [foo]
     ... recipe = recipe
     ... ''')
@@ -1560,7 +1508,7 @@
     Installing foo.
 
     >>> write('recipe', 'some-file', '1')
-    >>> os.symlink(join('recipe', 'some-file'), 
+    >>> os.symlink(join('recipe', 'some-file'),
     ...            join('recipe', 'another-file'))
     >>> ls('recipe')
     l  another-file
@@ -1702,7 +1650,7 @@
     Uninstalling foo.
     Installing foo.
     recipe v1
-    
+
     """
 
 def update_adds_to_uninstall_list():
@@ -1760,10 +1708,10 @@
     ...
     [foo]
     __buildout_installed__ = a
-    	b
-    	c
-    	d
-    	e
+        b
+        c
+        d
+        e
     __buildout_signature__ = ...
 
 """
@@ -1792,7 +1740,7 @@
 
     >>> handler.uninstall()
     >>> logger.propagate = old_propogate
-    
+
     """
 
 def internal_errors():
@@ -1800,7 +1748,7 @@
 
     >>> mkdir(sample_buildout, 'recipes')
 
-    >>> write(sample_buildout, 'recipes', 'mkdir.py', 
+    >>> write(sample_buildout, 'recipes', 'mkdir.py',
     ... '''
     ... class Mkdir:
     ...     def __init__(self, buildout, name, options):
@@ -1846,7 +1794,7 @@
 def whine_about_unused_options():
     '''
 
-    >>> write('foo.py', 
+    >>> write('foo.py',
     ... """
     ... class Foo:
     ...
@@ -2115,7 +2063,7 @@
     >>> print system(buildout+' setup badegg sdist'), # doctest: +ELLIPSIS
     Running setup script 'badegg/setup.py'.
     ...
-    
+
     >>> dist = join('badegg', 'dist')
 
     >>> write('buildout.cfg',
@@ -2148,7 +2096,7 @@
     >>> ls('eggs') # doctest: +ELLIPSIS
     d  badegg-1-py2.4.egg
     ...
-    
+
     >>> ls('bin')
     -  bo
     -  buildout
@@ -2166,7 +2114,7 @@
     ... """)
 
     >>> zc.buildout.easy_install.build(
-    ...   'extdemo ==1.4', dest, 
+    ...   'extdemo ==1.4', dest,
     ...   {'include-dirs': os.path.join(sample_buildout, 'include')},
     ...   links=[link_server], index=link_server+'index/',
     ...   newest=False)
@@ -2217,7 +2165,7 @@
     ... recipe = zc.recipe.egg
     ... eggs = demo ==0.1
     ... ''' % globals())
-    
+
     >>> print system(buildout),
     Uninstalling x.
     Installing x.
@@ -2239,7 +2187,7 @@
         ...     p.stdin.close()
         ...     print p.stdout.read()
         ...     print 'Exit:', bool(p.wait())
-        
+
         >>> call(buildout)
         <BLANKLINE>
         Exit: False
@@ -2323,7 +2271,7 @@
     ... setup(name='bad.test',
     ...       entry_points={'zc.buildout': ['default=bad_recipe:Bad']},)
     ... ''')
-    
+
     >>> write('buildout.cfg',
     ... '''
     ... [buildout]
@@ -2347,12 +2295,12 @@
     Installing b2.
     /sample-buildout
     /sample-buildout/bad_start
-    
+
     """
 
 def bug_61890_file_urls_dont_seem_to_work_in_find_dash_links():
     """
-    
+
     This bug arises from the fact that setuptools is overly restrictive
     about file urls, requiring that file urls pointing at directories
     must end in a slash.
@@ -2373,7 +2321,7 @@
     >>> ls(dest)
     -  demo-0.2-py2.4.egg
     -  demoneeded-1.1-py2.4.egg
-    
+
     """
 
 def bug_75607_buildout_should_not_run_if_it_creates_an_empty_buildout_cfg():
@@ -2385,12 +2333,12 @@
     Error: Couldn't open /sample-buildout/buildout.cfg
 
 
-    
+
     """
 
 def dealing_with_extremely_insane_dependencies():
     r"""
-    
+
     There was a problem with analysis of dependencies taking a long
     time, in part because the analysis would get repeated every time a
     package was encountered in a dependency list.  Now, we don't do
@@ -2412,7 +2360,7 @@
     >>> write('buildout.cfg',
     ... '''
     ... [buildout]
-    ... develop = pack0 pack1 pack2 pack3 pack4 
+    ... develop = pack0 pack1 pack2 pack3 pack4
     ... parts = pack1
     ...
     ... [pack1]
@@ -2531,7 +2479,7 @@
     Installing demo.
     Getting distribution for 'demoneeded'.
     Got demoneeded 1.0.
-    
+
     """
 
 def distributions_from_local_find_links_make_it_to_download_cache():
@@ -2557,12 +2505,12 @@
     >>> list(zc.buildout.easy_install.install(['foo'], 'eggs',
     ...          links=[join('test', 'dist')])) # doctest: +ELLIPSIS
     [foo 0.0.0 ...
-        
+
     >>> ls('cache')
     -  foo-0.0.0-py2.4.egg
 
     >>> _ = zc.buildout.easy_install.download_cache(old_cache)
-    
+
     """
 
 def create_egg(name, version, dest, install_requires=None,
@@ -2706,13 +2654,13 @@
     had 33a1
 
     >>> _ = zc.buildout.easy_install.prefer_final(True)
-    
+
     """
 
 def buildout_prefer_final_option():
     """
 The prefer-final buildout option can be used for override the default
-preference for newer distributions. 
+preference for newer distributions.
 
 The default is prefer-final = false:
 
@@ -2819,7 +2767,7 @@
     ... '''
     ... [buildout]
     ... develop = foo
-    ... parts = 
+    ... parts =
     ... ''')
 
     >>> print system(join('bin', 'buildout')),
@@ -2867,7 +2815,7 @@
     Installing foo.
     Getting distribution for 'foo==1'.
     Got foo 1.
-    
+
     """
 
 def pyc_and_pyo_files_have_correct_paths():
@@ -2916,10 +2864,10 @@
     ... '''
     ... [buildout]
     ... eggs-directory = ${buildout:directory}/develop-eggs
-    ... parts = 
+    ... parts =
     ... ''' % globals())
     >>> print system(buildout),
-    
+
     """
 
 def expand_shell_patterns_in_develop_paths():
@@ -2990,7 +2938,7 @@
 
 
 ######################################################################
-    
+
 def create_sample_eggs(test, executable=sys.executable):
     write = test.globs['write']
     dest = test.globs['sample_eggs']
@@ -3113,7 +3061,7 @@
         test.globs['sample_eggs'])
     test.globs['update_extdemo'] = lambda : add_source_dist(test, 1.5)
     zc.buildout.testing.install_develop('zc.recipe.egg', test)
-        
+
 egg_parse = re.compile('([0-9a-zA-Z_.]+)-([0-9a-zA-Z_.]+)-py(\d[.]\d).egg$'
                        ).match
 def makeNewRelease(project, ws, dest):
@@ -3121,20 +3069,20 @@
     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-99.99-py%s.egg" % (eggname, 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, 
+            zip.read('EGG-INFO/PKG-INFO').replace("Version: %s" % oldver,
                                                   "Version: 99.99")
             )
         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, 
+        info = open(info_path).read().replace("Version: %s" % oldver,
                                               "Version: 99.99")
         open(info_path, 'w').write(info)
 
@@ -3192,13 +3140,14 @@
     )
 
 def test_suite():
-    return unittest.TestSuite((
+    test_suite = [
         doctest.DocFileSuite(
             'buildout.txt', 'runsetup.txt', 'repeatable.txt', 'setup.txt',
             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+'),
@@ -3228,6 +3177,7 @@
             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)'),
@@ -3240,6 +3190,7 @@
             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,
@@ -3252,7 +3203,7 @@
                (re.compile('[-d]  setuptools'), '-  setuptools'),
                ])
             ),
-        
+
         doctest.DocFileSuite(
             'easy_install.txt', 'downloadcache.txt', 'dependencylinks.txt',
             'allowhosts.txt', 'unzip.txt',
@@ -3260,11 +3211,13 @@
             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-\S+[.]egg'), 'setuptools.egg'),
+               (re.compile(r'\\[\\]?'), '/'),
                ]),
             ),
         doctest.DocTestSuite(
@@ -3272,6 +3225,7 @@
             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"),
@@ -3302,6 +3256,7 @@
             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+'),
@@ -3322,5 +3277,35 @@
                 '[Errno 17] File exists: '
                 ),
                ])
-            ), 
-        ))
+            ),
+        doctest.DocFileSuite(
+            'testing_bugfix.txt'),
+    ]
+
+    # adding bootstrap.txt doctest to the suite
+    # only if bootstrap.py is present
+    bootstrap_py = os.path.join(
+       os.path.dirname(
+          os.path.dirname(
+             os.path.dirname(
+                os.path.dirname(zc.buildout.__file__)
+                )
+             )
+          ),
+       'bootstrap', 'bootstrap.py')
+
+    if os.path.exists(bootstrap_py):
+        test_suite.append(doctest.DocFileSuite(
+            'bootstrap.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'), ''),
+               ]),
+            ))
+
+    return unittest.TestSuite(test_suite)

Modified: zc.buildout/branches/help-api/zc.recipe.egg_/src/zc/recipe/egg/README.txt
===================================================================
--- zc.buildout/branches/help-api/zc.recipe.egg_/src/zc/recipe/egg/README.txt	2009-07-13 15:12:48 UTC (rev 101851)
+++ zc.buildout/branches/help-api/zc.recipe.egg_/src/zc/recipe/egg/README.txt	2009-07-13 15:13:00 UTC (rev 101852)
@@ -425,7 +425,7 @@
     import os
     <BLANKLINE>
     join = os.path.join
-    base = os.path.dirname(__file__)
+    base = os.path.dirname(os.path.abspath(__file__))
     base = os.path.dirname(base)
     <BLANKLINE>
     import sys
@@ -472,7 +472,7 @@
     import os
     <BLANKLINE>
     join = os.path.join
-    base = os.path.dirname(__file__)
+    base = os.path.dirname(os.path.abspath(__file__))
     base = os.path.dirname(base)
     <BLANKLINE>
     import sys

Modified: zc.buildout/branches/help-api/zc.recipe.egg_/src/zc/recipe/egg/tests.py
===================================================================
--- zc.buildout/branches/help-api/zc.recipe.egg_/src/zc/recipe/egg/tests.py	2009-07-13 15:12:48 UTC (rev 101851)
+++ zc.buildout/branches/help-api/zc.recipe.egg_/src/zc/recipe/egg/tests.py	2009-07-13 15:13:00 UTC (rev 101852)
@@ -44,12 +44,15 @@
             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-[^-]+-'), 'setuptools-X-')
+               (re.compile('[-d]  setuptools-[^-]+-'), 'setuptools-X-'),
+               (re.compile(r'eggs\\\\demo'), 'eggs/demo'),
+               (re.compile(r'[a-zA-Z]:\\\\foo\\\\bar'), '/foo/bar'),
                ])
             ),
         doctest.DocFileSuite(
@@ -57,6 +60,7 @@
             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+'
@@ -77,6 +81,7 @@
             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'),
@@ -97,9 +102,11 @@
                 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 \S+'), 'Got setuptools V'),
-                   (re.compile('([d-]  )?setuptools-\S+-py'), 'setuptools-V-py'),
+                   (re.compile('([d-]  )?setuptools-\S+-py'),
+                    'setuptools-V-py'),
                    (re.compile('-py2[.][0-35-9][.]'), 'py2.5.'),
                    (re.compile('zc.buildout-\S+[.]egg'),
                     'zc.buildout.egg'),



More information about the Checkins mailing list