eggs/zc.buildout-1.5.2-py2.6.egg/zc/buildout/tests.py
changeset 69 c6bca38c1cbf
equal deleted inserted replaced
68:5ff1fc726848 69:c6bca38c1cbf
       
     1 ##############################################################################
       
     2 #
       
     3 # Copyright (c) 2004-2009 Zope Corporation and Contributors.
       
     4 # All Rights Reserved.
       
     5 #
       
     6 # This software is subject to the provisions of the Zope Public License,
       
     7 # Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
       
     8 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
       
     9 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
       
    10 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
       
    11 # FOR A PARTICULAR PURPOSE.
       
    12 #
       
    13 ##############################################################################
       
    14 import doctest
       
    15 from zope.testing import renormalizing
       
    16 import os
       
    17 import pkg_resources
       
    18 import re
       
    19 import shutil
       
    20 import sys
       
    21 import tempfile
       
    22 import unittest
       
    23 import zc.buildout.easy_install
       
    24 import zc.buildout.testing
       
    25 import zc.buildout.testselectingpython
       
    26 import zipfile
       
    27 
       
    28 os_path_sep = os.path.sep
       
    29 if os_path_sep == '\\':
       
    30     os_path_sep *= 2
       
    31 
       
    32 
       
    33 def develop_w_non_setuptools_setup_scripts():
       
    34     """
       
    35 We should be able to deal with setup scripts that aren't setuptools based.
       
    36 
       
    37     >>> mkdir('foo')
       
    38     >>> write('foo', 'setup.py',
       
    39     ... '''
       
    40     ... from distutils.core import setup
       
    41     ... setup(name="foo")
       
    42     ... ''')
       
    43 
       
    44     >>> write('buildout.cfg',
       
    45     ... '''
       
    46     ... [buildout]
       
    47     ... develop = foo
       
    48     ... parts =
       
    49     ... ''')
       
    50 
       
    51     >>> print system(join('bin', 'buildout')),
       
    52     Develop: '/sample-buildout/foo'
       
    53 
       
    54     >>> ls('develop-eggs')
       
    55     -  foo.egg-link
       
    56     -  z3c.recipe.scripts.egg-link
       
    57     -  zc.recipe.egg.egg-link
       
    58 
       
    59     """
       
    60 
       
    61 def develop_verbose():
       
    62     """
       
    63 We should be able to deal with setup scripts that aren't setuptools based.
       
    64 
       
    65     >>> mkdir('foo')
       
    66     >>> write('foo', 'setup.py',
       
    67     ... '''
       
    68     ... from setuptools import setup
       
    69     ... setup(name="foo")
       
    70     ... ''')
       
    71 
       
    72     >>> write('buildout.cfg',
       
    73     ... '''
       
    74     ... [buildout]
       
    75     ... develop = foo
       
    76     ... parts =
       
    77     ... ''')
       
    78 
       
    79     >>> print system(join('bin', 'buildout')+' -vv'), # doctest: +ELLIPSIS
       
    80     Installing...
       
    81     Develop: '/sample-buildout/foo'
       
    82     ...
       
    83     Installed /sample-buildout/foo
       
    84     ...
       
    85 
       
    86     >>> ls('develop-eggs')
       
    87     -  foo.egg-link
       
    88     -  z3c.recipe.scripts.egg-link
       
    89     -  zc.recipe.egg.egg-link
       
    90 
       
    91     >>> print system(join('bin', 'buildout')+' -vvv'), # doctest: +ELLIPSIS
       
    92     Installing...
       
    93     Develop: '/sample-buildout/foo'
       
    94     in: '/sample-buildout/foo'
       
    95     ... -q develop -mxN -d /sample-buildout/develop-eggs/...
       
    96 
       
    97 
       
    98     """
       
    99 
       
   100 def buildout_error_handling():
       
   101     r"""Buildout error handling
       
   102 
       
   103 Asking for a section that doesn't exist, yields a missing section error:
       
   104 
       
   105     >>> import os
       
   106     >>> os.chdir(sample_buildout)
       
   107     >>> import zc.buildout.buildout
       
   108     >>> buildout = zc.buildout.buildout.Buildout('buildout.cfg', [])
       
   109     >>> buildout['eek']
       
   110     Traceback (most recent call last):
       
   111     ...
       
   112     MissingSection: The referenced section, 'eek', was not defined.
       
   113 
       
   114 Asking for an option that doesn't exist, a MissingOption error is raised:
       
   115 
       
   116     >>> buildout['buildout']['eek']
       
   117     Traceback (most recent call last):
       
   118     ...
       
   119     MissingOption: Missing option: buildout:eek
       
   120 
       
   121 It is an error to create a variable-reference cycle:
       
   122 
       
   123     >>> write(sample_buildout, 'buildout.cfg',
       
   124     ... '''
       
   125     ... [buildout]
       
   126     ... parts =
       
   127     ... x = ${buildout:y}
       
   128     ... y = ${buildout:z}
       
   129     ... z = ${buildout:x}
       
   130     ... ''')
       
   131 
       
   132     >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')),
       
   133     ... # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
       
   134     While:
       
   135       Initializing.
       
   136       Getting section buildout.
       
   137       Initializing section buildout.
       
   138       Getting option buildout:y.
       
   139       Getting option buildout:z.
       
   140       Getting option buildout:x.
       
   141       Getting option buildout:y.
       
   142     Error: Circular reference in substitutions.
       
   143 
       
   144 It is an error to use funny characters in variable refereces:
       
   145 
       
   146     >>> write(sample_buildout, 'buildout.cfg',
       
   147     ... '''
       
   148     ... [buildout]
       
   149     ... develop = recipes
       
   150     ... parts = data_dir debug
       
   151     ... x = ${bui$ldout:y}
       
   152     ... ''')
       
   153 
       
   154     >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')),
       
   155     While:
       
   156       Initializing.
       
   157       Getting section buildout.
       
   158       Initializing section buildout.
       
   159       Getting option buildout:x.
       
   160     Error: The section name in substitution, ${bui$ldout:y},
       
   161     has invalid characters.
       
   162 
       
   163     >>> write(sample_buildout, 'buildout.cfg',
       
   164     ... '''
       
   165     ... [buildout]
       
   166     ... develop = recipes
       
   167     ... parts = data_dir debug
       
   168     ... x = ${buildout:y{z}
       
   169     ... ''')
       
   170 
       
   171     >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')),
       
   172     While:
       
   173       Initializing.
       
   174       Getting section buildout.
       
   175       Initializing section buildout.
       
   176       Getting option buildout:x.
       
   177     Error: The option name in substitution, ${buildout:y{z},
       
   178     has invalid characters.
       
   179 
       
   180 and too have too many or too few colons:
       
   181 
       
   182     >>> write(sample_buildout, 'buildout.cfg',
       
   183     ... '''
       
   184     ... [buildout]
       
   185     ... develop = recipes
       
   186     ... parts = data_dir debug
       
   187     ... x = ${parts}
       
   188     ... ''')
       
   189 
       
   190     >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')),
       
   191     While:
       
   192       Initializing.
       
   193       Getting section buildout.
       
   194       Initializing section buildout.
       
   195       Getting option buildout:x.
       
   196     Error: The substitution, ${parts},
       
   197     doesn't contain a colon.
       
   198 
       
   199     >>> write(sample_buildout, 'buildout.cfg',
       
   200     ... '''
       
   201     ... [buildout]
       
   202     ... develop = recipes
       
   203     ... parts = data_dir debug
       
   204     ... x = ${buildout:y:z}
       
   205     ... ''')
       
   206 
       
   207     >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')),
       
   208     While:
       
   209       Initializing.
       
   210       Getting section buildout.
       
   211       Initializing section buildout.
       
   212       Getting option buildout:x.
       
   213     Error: The substitution, ${buildout:y:z},
       
   214     has too many colons.
       
   215 
       
   216 Al parts have to have a section:
       
   217 
       
   218     >>> write(sample_buildout, 'buildout.cfg',
       
   219     ... '''
       
   220     ... [buildout]
       
   221     ... parts = x
       
   222     ... ''')
       
   223 
       
   224     >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')),
       
   225     While:
       
   226       Installing.
       
   227       Getting section x.
       
   228     Error: The referenced section, 'x', was not defined.
       
   229 
       
   230 and all parts have to have a specified recipe:
       
   231 
       
   232 
       
   233     >>> write(sample_buildout, 'buildout.cfg',
       
   234     ... '''
       
   235     ... [buildout]
       
   236     ... parts = x
       
   237     ...
       
   238     ... [x]
       
   239     ... foo = 1
       
   240     ... ''')
       
   241 
       
   242     >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')),
       
   243     While:
       
   244       Installing.
       
   245     Error: Missing option: x:recipe
       
   246 
       
   247 """
       
   248 
       
   249 make_dist_that_requires_setup_py_template = """
       
   250 from setuptools import setup
       
   251 setup(name=%r, version=%r,
       
   252       install_requires=%r,
       
   253       )
       
   254 """
       
   255 
       
   256 def make_dist_that_requires(dest, name, requires=[], version=1, egg=''):
       
   257     os.mkdir(os.path.join(dest, name))
       
   258     open(os.path.join(dest, name, 'setup.py'), 'w').write(
       
   259         make_dist_that_requires_setup_py_template
       
   260         % (name, version, requires)
       
   261         )
       
   262 
       
   263 def show_who_requires_when_there_is_a_conflict():
       
   264     """
       
   265 It's a pain when we require eggs that have requirements that are
       
   266 incompatible. We want the error we get to tell us what is missing.
       
   267 
       
   268 Let's make a few develop distros, some of which have incompatible
       
   269 requirements.
       
   270 
       
   271     >>> make_dist_that_requires(sample_buildout, 'sampley',
       
   272     ...                         ['demoneeded ==1.0'])
       
   273     >>> make_dist_that_requires(sample_buildout, 'samplez',
       
   274     ...                         ['demoneeded ==1.1'])
       
   275 
       
   276 Now, let's create a buildout that requires y and z:
       
   277 
       
   278     >>> write('buildout.cfg',
       
   279     ... '''
       
   280     ... [buildout]
       
   281     ... parts = eggs
       
   282     ... develop = sampley samplez
       
   283     ... find-links = %(link_server)s
       
   284     ...
       
   285     ... [eggs]
       
   286     ... recipe = zc.recipe.egg
       
   287     ... eggs = sampley
       
   288     ...        samplez
       
   289     ... ''' % globals())
       
   290 
       
   291     >>> print system(buildout),
       
   292     Develop: '/sample-buildout/sampley'
       
   293     Develop: '/sample-buildout/samplez'
       
   294     Installing eggs.
       
   295     Getting distribution for 'demoneeded==1.1'.
       
   296     Got demoneeded 1.1.
       
   297     While:
       
   298       Installing eggs.
       
   299     Error: There is a version conflict.
       
   300     We already have: demoneeded 1.1
       
   301     but sampley 1 requires 'demoneeded==1.0'.
       
   302 
       
   303 Here, we see that sampley required an older version of demoneeded. What
       
   304 if we hadn't required sampley ourselves:
       
   305 
       
   306     >>> make_dist_that_requires(sample_buildout, 'samplea', ['sampleb'])
       
   307     >>> make_dist_that_requires(sample_buildout, 'sampleb',
       
   308     ...                         ['sampley', 'samplea'])
       
   309     >>> write('buildout.cfg',
       
   310     ... '''
       
   311     ... [buildout]
       
   312     ... parts = eggs
       
   313     ... develop = sampley samplez samplea sampleb
       
   314     ... find-links = %(link_server)s
       
   315     ...
       
   316     ... [eggs]
       
   317     ... recipe = zc.recipe.egg
       
   318     ... eggs = samplea
       
   319     ...        samplez
       
   320     ... ''' % globals())
       
   321 
       
   322 If we use the verbose switch, we can see where requirements are coming from:
       
   323 
       
   324     >>> print system(buildout+' -v'), # doctest: +ELLIPSIS
       
   325     Installing 'zc.buildout', 'setuptools'.
       
   326     We have a develop egg: zc.buildout 1.0.0
       
   327     We have the best distribution that satisfies 'setuptools'.
       
   328     Picked: setuptools = 0.6
       
   329     Develop: '/sample-buildout/sampley'
       
   330     Develop: '/sample-buildout/samplez'
       
   331     Develop: '/sample-buildout/samplea'
       
   332     Develop: '/sample-buildout/sampleb'
       
   333     ...Installing eggs.
       
   334     Installing 'samplea', 'samplez'.
       
   335     We have a develop egg: samplea 1
       
   336     We have a develop egg: samplez 1
       
   337     Getting required 'demoneeded==1.1'
       
   338       required by samplez 1.
       
   339     We have the distribution that satisfies 'demoneeded==1.1'.
       
   340     Getting required 'sampleb'
       
   341       required by samplea 1.
       
   342     We have a develop egg: sampleb 1
       
   343     Getting required 'sampley'
       
   344       required by sampleb 1.
       
   345     We have a develop egg: sampley 1
       
   346     While:
       
   347       Installing eggs.
       
   348     Error: There is a version conflict.
       
   349     We already have: demoneeded 1.1
       
   350     but sampley 1 requires 'demoneeded==1.0'.
       
   351     """
       
   352 
       
   353 def show_who_requires_missing_distributions():
       
   354     """
       
   355 
       
   356 When working with a lot of eggs, which require eggs recursively, it can
       
   357 be hard to tell why we're requiring things we can't find. Fortunately,
       
   358 buildout will tell us who's asking for something that we can't find.
       
   359 
       
   360     >>> make_dist_that_requires(sample_buildout, 'sampley', ['demoneeded'])
       
   361     >>> make_dist_that_requires(sample_buildout, 'samplea', ['sampleb'])
       
   362     >>> make_dist_that_requires(sample_buildout, 'sampleb',
       
   363     ...                         ['sampley', 'samplea'])
       
   364     >>> write('buildout.cfg',
       
   365     ... '''
       
   366     ... [buildout]
       
   367     ... parts = eggs
       
   368     ... develop = sampley samplea sampleb
       
   369     ...
       
   370     ... [eggs]
       
   371     ... recipe = zc.recipe.egg
       
   372     ... eggs = samplea
       
   373     ... ''')
       
   374 
       
   375     >>> print system(buildout),
       
   376     Develop: '/sample-buildout/sampley'
       
   377     Develop: '/sample-buildout/samplea'
       
   378     Develop: '/sample-buildout/sampleb'
       
   379     Installing eggs.
       
   380     Couldn't find index page for 'demoneeded' (maybe misspelled?)
       
   381     Getting distribution for 'demoneeded'.
       
   382     While:
       
   383       Installing eggs.
       
   384       Getting distribution for 'demoneeded'.
       
   385     Error: Couldn't find a distribution for 'demoneeded'.
       
   386     """
       
   387 
       
   388 def show_eggs_from_site_packages():
       
   389     """
       
   390 Sometimes you want to know what eggs are coming from site-packages.  This
       
   391 might be for a diagnostic, or so that you can get a starting value for the
       
   392 allowed-eggs-from-site-packages option.  The -v flag will also include this
       
   393 information.
       
   394 
       
   395 Our "py_path" has the "demoneeded," "demo"
       
   396 packages available.  We'll ask for "bigdemo," which will get both of them.
       
   397 
       
   398 Here's our set up.
       
   399 
       
   400     >>> py_path, site_packages_path = make_py()
       
   401     >>> create_sample_sys_install(site_packages_path)
       
   402 
       
   403     >>> write('buildout.cfg',
       
   404     ... '''
       
   405     ... [buildout]
       
   406     ... parts = eggs
       
   407     ... prefer-final = true
       
   408     ... find-links = %(link_server)s
       
   409     ...
       
   410     ... [primed_python]
       
   411     ... executable = %(py_path)s
       
   412     ...
       
   413     ... [eggs]
       
   414     ... recipe = zc.recipe.egg:eggs
       
   415     ... python = primed_python
       
   416     ... eggs = bigdemo
       
   417     ... ''' % globals())
       
   418 
       
   419 Now here is the output.  The lines that begin with "Egg from site-packages:"
       
   420 indicate the eggs from site-packages that have been selected.  You'll see
       
   421 we have two: demo 0.3 and demoneeded 1.1.
       
   422 
       
   423     >>> print system(buildout+" -v"),
       
   424     Installing 'zc.buildout', 'setuptools'.
       
   425     We have a develop egg: zc.buildout V
       
   426     We have the best distribution that satisfies 'setuptools'.
       
   427     Picked: setuptools = V
       
   428     Installing 'zc.recipe.egg'.
       
   429     We have a develop egg: zc.recipe.egg V
       
   430     Installing eggs.
       
   431     Installing 'bigdemo'.
       
   432     We have no distributions for bigdemo that satisfies 'bigdemo'.
       
   433     Getting distribution for 'bigdemo'.
       
   434     Got bigdemo 0.1.
       
   435     Picked: bigdemo = 0.1
       
   436     Getting required 'demo'
       
   437       required by bigdemo 0.1.
       
   438     We have the best distribution that satisfies 'demo'.
       
   439     Egg from site-packages: demo 0.3
       
   440     Getting required 'demoneeded'
       
   441       required by demo 0.3.
       
   442     We have the best distribution that satisfies 'demoneeded'.
       
   443     Egg from site-packages: demoneeded 1.1
       
   444     """
       
   445 
       
   446 def test_comparing_saved_options_with_funny_characters():
       
   447     """
       
   448 If an option has newlines, extra/odd spaces or a %, we need to make sure
       
   449 the comparison with the saved value works correctly.
       
   450 
       
   451     >>> mkdir(sample_buildout, 'recipes')
       
   452     >>> write(sample_buildout, 'recipes', 'debug.py',
       
   453     ... '''
       
   454     ... class Debug:
       
   455     ...     def __init__(self, buildout, name, options):
       
   456     ...         options['debug'] = \"\"\"  <zodb>
       
   457     ...
       
   458     ...   <filestorage>
       
   459     ...     path foo
       
   460     ...   </filestorage>
       
   461     ...
       
   462     ... </zodb>
       
   463     ...      \"\"\"
       
   464     ...         options['debug1'] = \"\"\"
       
   465     ... <zodb>
       
   466     ...
       
   467     ...   <filestorage>
       
   468     ...     path foo
       
   469     ...   </filestorage>
       
   470     ...
       
   471     ... </zodb>
       
   472     ... \"\"\"
       
   473     ...         options['debug2'] = '  x  '
       
   474     ...         options['debug3'] = '42'
       
   475     ...         options['format'] = '%3d'
       
   476     ...
       
   477     ...     def install(self):
       
   478     ...         open('t', 'w').write('t')
       
   479     ...         return 't'
       
   480     ...
       
   481     ...     update = install
       
   482     ... ''')
       
   483 
       
   484 
       
   485     >>> write(sample_buildout, 'recipes', 'setup.py',
       
   486     ... '''
       
   487     ... from setuptools import setup
       
   488     ... setup(
       
   489     ...     name = "recipes",
       
   490     ...     entry_points = {'zc.buildout': ['default = debug:Debug']},
       
   491     ...     )
       
   492     ... ''')
       
   493 
       
   494     >>> write(sample_buildout, 'recipes', 'README.txt', " ")
       
   495 
       
   496     >>> write(sample_buildout, 'buildout.cfg',
       
   497     ... '''
       
   498     ... [buildout]
       
   499     ... develop = recipes
       
   500     ... parts = debug
       
   501     ...
       
   502     ... [debug]
       
   503     ... recipe = recipes
       
   504     ... ''')
       
   505 
       
   506     >>> os.chdir(sample_buildout)
       
   507     >>> buildout = os.path.join(sample_buildout, 'bin', 'buildout')
       
   508 
       
   509     >>> print system(buildout),
       
   510     Develop: '/sample-buildout/recipes'
       
   511     Installing debug.
       
   512 
       
   513 If we run the buildout again, we shoudn't get a message about
       
   514 uninstalling anything because the configuration hasn't changed.
       
   515 
       
   516     >>> print system(buildout),
       
   517     Develop: '/sample-buildout/recipes'
       
   518     Updating debug.
       
   519 """
       
   520 
       
   521 def finding_eggs_as_local_directories():
       
   522     r"""
       
   523 It is possible to set up find-links so that we could install from
       
   524 a local directory that may contained unzipped eggs.
       
   525 
       
   526     >>> src = tmpdir('src')
       
   527     >>> write(src, 'setup.py',
       
   528     ... '''
       
   529     ... from setuptools import setup
       
   530     ... setup(name='demo', py_modules=[''],
       
   531     ...    zip_safe=False, version='1.0', author='bob', url='bob',
       
   532     ...    author_email='bob')
       
   533     ... ''')
       
   534 
       
   535     >>> write(src, 't.py', '#\n')
       
   536     >>> write(src, 'README.txt', '')
       
   537     >>> _ = system(join('bin', 'buildout')+' setup ' + src + ' bdist_egg')
       
   538 
       
   539 Install it so it gets unzipped:
       
   540 
       
   541     >>> d1 = tmpdir('d1')
       
   542     >>> ws = zc.buildout.easy_install.install(
       
   543     ...     ['demo'], d1, links=[join(src, 'dist')],
       
   544     ...     )
       
   545 
       
   546     >>> ls(d1)
       
   547     d  demo-1.0-py2.4.egg
       
   548 
       
   549 Then try to install it again:
       
   550 
       
   551     >>> d2 = tmpdir('d2')
       
   552     >>> ws = zc.buildout.easy_install.install(
       
   553     ...     ['demo'], d2, links=[d1],
       
   554     ...     )
       
   555 
       
   556     >>> ls(d2)
       
   557     d  demo-1.0-py2.4.egg
       
   558 
       
   559     """
       
   560 
       
   561 def make_sure__get_version_works_with_2_digit_python_versions():
       
   562     """
       
   563 
       
   564 This is a test of an internal function used by higher-level machinery.
       
   565 
       
   566 We'll start by creating a faux 'python' that executable that prints a
       
   567 2-digit version. This is a bit of a pain to do portably. :(
       
   568 
       
   569     >>> mkdir('demo')
       
   570     >>> write('demo', 'setup.py',
       
   571     ... '''
       
   572     ... from setuptools import setup
       
   573     ... setup(name='demo',
       
   574     ...       entry_points = {'console_scripts': ['demo = demo:main']},
       
   575     ...       )
       
   576     ... ''')
       
   577     >>> write('demo', 'demo.py',
       
   578     ... '''
       
   579     ... def main():
       
   580     ...     print 'Python 2.5'
       
   581     ... ''')
       
   582 
       
   583     >>> write('buildout.cfg',
       
   584     ... '''
       
   585     ... [buildout]
       
   586     ... develop = demo
       
   587     ... parts =
       
   588     ... ''')
       
   589 
       
   590     >>> print system(join('bin', 'buildout')),
       
   591     Develop: '/sample-buildout/demo'
       
   592 
       
   593     >>> import zc.buildout.easy_install
       
   594     >>> ws = zc.buildout.easy_install.working_set(
       
   595     ...    ['demo'], sys.executable, ['develop-eggs'])
       
   596     >>> bool(zc.buildout.easy_install.scripts(
       
   597     ...      ['demo'], ws, sys.executable, 'bin'))
       
   598     True
       
   599 
       
   600     >>> print system(join('bin', 'demo')),
       
   601     Python 2.5
       
   602 
       
   603 Now, finally, let's test _get_version:
       
   604 
       
   605     >>> zc.buildout.easy_install._get_version(join('bin', 'demo'))
       
   606     '2.5'
       
   607 
       
   608     """
       
   609 
       
   610 def create_sections_on_command_line():
       
   611     """
       
   612     >>> write('buildout.cfg',
       
   613     ... '''
       
   614     ... [buildout]
       
   615     ... parts =
       
   616     ... x = ${foo:bar}
       
   617     ... ''')
       
   618 
       
   619     >>> print system(buildout + ' foo:bar=1 -vv'), # doctest: +ELLIPSIS
       
   620     Installing 'zc.buildout', 'setuptools'.
       
   621     ...
       
   622     [foo]
       
   623     bar = 1
       
   624     ...
       
   625 
       
   626     """
       
   627 
       
   628 def test_help():
       
   629     """
       
   630     >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')+' -h'),
       
   631     ... # doctest: +ELLIPSIS
       
   632     Usage: buildout [options] [assignments] [command [command arguments]]
       
   633     <BLANKLINE>
       
   634     Options:
       
   635     <BLANKLINE>
       
   636       -h, --help
       
   637     ...
       
   638 
       
   639     >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')
       
   640     ...              +' --help'),
       
   641     ... # doctest: +ELLIPSIS
       
   642     Usage: buildout [options] [assignments] [command [command arguments]]
       
   643     <BLANKLINE>
       
   644     Options:
       
   645     <BLANKLINE>
       
   646       -h, --help
       
   647     ...
       
   648     """
       
   649 
       
   650 def test_bootstrap_with_extension():
       
   651     """
       
   652 We had a problem running a bootstrap with an extension.  Let's make
       
   653 sure it is fixed.  Basically, we don't load extensions when
       
   654 bootstrapping.
       
   655 
       
   656     >>> d = tmpdir('sample-bootstrap')
       
   657 
       
   658     >>> write(d, 'buildout.cfg',
       
   659     ... '''
       
   660     ... [buildout]
       
   661     ... extensions = some_awsome_extension
       
   662     ... parts =
       
   663     ... ''')
       
   664 
       
   665     >>> os.chdir(d)
       
   666     >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')
       
   667     ...              + ' bootstrap'),
       
   668     Creating directory '/sample-bootstrap/bin'.
       
   669     Creating directory '/sample-bootstrap/parts'.
       
   670     Creating directory '/sample-bootstrap/eggs'.
       
   671     Creating directory '/sample-bootstrap/develop-eggs'.
       
   672     Generated script '/sample-bootstrap/bin/buildout'.
       
   673     """
       
   674 
       
   675 
       
   676 def bug_92891_bootstrap_crashes_with_egg_recipe_in_buildout_section():
       
   677     """
       
   678     >>> d = tmpdir('sample-bootstrap')
       
   679 
       
   680     >>> write(d, 'buildout.cfg',
       
   681     ... '''
       
   682     ... [buildout]
       
   683     ... parts = buildout
       
   684     ... eggs-directory = eggs
       
   685     ...
       
   686     ... [buildout]
       
   687     ... recipe = zc.recipe.egg
       
   688     ... eggs = zc.buildout
       
   689     ... scripts = buildout=buildout
       
   690     ... ''')
       
   691 
       
   692     >>> os.chdir(d)
       
   693     >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')
       
   694     ...              + ' bootstrap'),
       
   695     Creating directory '/sample-bootstrap/bin'.
       
   696     Creating directory '/sample-bootstrap/parts'.
       
   697     Creating directory '/sample-bootstrap/eggs'.
       
   698     Creating directory '/sample-bootstrap/develop-eggs'.
       
   699     Generated script '/sample-bootstrap/bin/buildout'.
       
   700 
       
   701     >>> print system(os.path.join('bin', 'buildout')),
       
   702     Unused options for buildout: 'scripts' 'eggs'.
       
   703 
       
   704     """
       
   705 
       
   706 def removing_eggs_from_develop_section_causes_egg_link_to_be_removed():
       
   707     '''
       
   708     >>> cd(sample_buildout)
       
   709 
       
   710 Create a develop egg:
       
   711 
       
   712     >>> mkdir('foo')
       
   713     >>> write('foo', 'setup.py',
       
   714     ... """
       
   715     ... from setuptools import setup
       
   716     ... setup(name='foox')
       
   717     ... """)
       
   718     >>> write('buildout.cfg',
       
   719     ... """
       
   720     ... [buildout]
       
   721     ... develop = foo
       
   722     ... parts =
       
   723     ... """)
       
   724 
       
   725     >>> print system(join('bin', 'buildout')),
       
   726     Develop: '/sample-buildout/foo'
       
   727 
       
   728     >>> ls('develop-eggs')
       
   729     -  foox.egg-link
       
   730     -  z3c.recipe.scripts.egg-link
       
   731     -  zc.recipe.egg.egg-link
       
   732 
       
   733 Create another:
       
   734 
       
   735     >>> mkdir('bar')
       
   736     >>> write('bar', 'setup.py',
       
   737     ... """
       
   738     ... from setuptools import setup
       
   739     ... setup(name='fooy')
       
   740     ... """)
       
   741     >>> write('buildout.cfg',
       
   742     ... """
       
   743     ... [buildout]
       
   744     ... develop = foo bar
       
   745     ... parts =
       
   746     ... """)
       
   747 
       
   748     >>> print system(join('bin', 'buildout')),
       
   749     Develop: '/sample-buildout/foo'
       
   750     Develop: '/sample-buildout/bar'
       
   751 
       
   752     >>> ls('develop-eggs')
       
   753     -  foox.egg-link
       
   754     -  fooy.egg-link
       
   755     -  z3c.recipe.scripts.egg-link
       
   756     -  zc.recipe.egg.egg-link
       
   757 
       
   758 Remove one:
       
   759 
       
   760     >>> write('buildout.cfg',
       
   761     ... """
       
   762     ... [buildout]
       
   763     ... develop = bar
       
   764     ... parts =
       
   765     ... """)
       
   766     >>> print system(join('bin', 'buildout')),
       
   767     Develop: '/sample-buildout/bar'
       
   768 
       
   769 It is gone
       
   770 
       
   771     >>> ls('develop-eggs')
       
   772     -  fooy.egg-link
       
   773     -  z3c.recipe.scripts.egg-link
       
   774     -  zc.recipe.egg.egg-link
       
   775 
       
   776 Remove the other:
       
   777 
       
   778     >>> write('buildout.cfg',
       
   779     ... """
       
   780     ... [buildout]
       
   781     ... parts =
       
   782     ... """)
       
   783     >>> print system(join('bin', 'buildout')),
       
   784 
       
   785 All gone
       
   786 
       
   787     >>> ls('develop-eggs')
       
   788     -  z3c.recipe.scripts.egg-link
       
   789     -  zc.recipe.egg.egg-link
       
   790     '''
       
   791 
       
   792 
       
   793 def add_setuptools_to_dependencies_when_namespace_packages():
       
   794     '''
       
   795 Often, a package depends on setuptools soley by virtue of using
       
   796 namespace packages. In this situation, package authors often forget to
       
   797 declare setuptools as a dependency. This is a mistake, but,
       
   798 unfortunately, a common one that we need to work around.  If an egg
       
   799 uses namespace packages and does not include setuptools as a depenency,
       
   800 we will still include setuptools in the working set.  If we see this for
       
   801 a devlop egg, we will also generate a warning.
       
   802 
       
   803     >>> mkdir('foo')
       
   804     >>> mkdir('foo', 'src')
       
   805     >>> mkdir('foo', 'src', 'stuff')
       
   806     >>> write('foo', 'src', 'stuff', '__init__.py',
       
   807     ... """__import__('pkg_resources').declare_namespace(__name__)
       
   808     ... """)
       
   809     >>> mkdir('foo', 'src', 'stuff', 'foox')
       
   810     >>> write('foo', 'src', 'stuff', 'foox', '__init__.py', '')
       
   811     >>> write('foo', 'setup.py',
       
   812     ... """
       
   813     ... from setuptools import setup
       
   814     ... setup(name='foox',
       
   815     ...       namespace_packages = ['stuff'],
       
   816     ...       package_dir = {'': 'src'},
       
   817     ...       packages = ['stuff', 'stuff.foox'],
       
   818     ...       )
       
   819     ... """)
       
   820     >>> write('foo', 'README.txt', '')
       
   821 
       
   822     >>> write('buildout.cfg',
       
   823     ... """
       
   824     ... [buildout]
       
   825     ... develop = foo
       
   826     ... parts =
       
   827     ... """)
       
   828 
       
   829     >>> print system(join('bin', 'buildout')),
       
   830     Develop: '/sample-buildout/foo'
       
   831 
       
   832 Now, if we generate a working set using the egg link, we will get a warning
       
   833 and we will get setuptools included in the working set.
       
   834 
       
   835     >>> import logging, zope.testing.loggingsupport
       
   836     >>> handler = zope.testing.loggingsupport.InstalledHandler(
       
   837     ...        'zc.buildout.easy_install', level=logging.WARNING)
       
   838     >>> logging.getLogger('zc.buildout.easy_install').propagate = False
       
   839 
       
   840     >>> [dist.project_name
       
   841     ...  for dist in zc.buildout.easy_install.working_set(
       
   842     ...    ['foox'], sys.executable,
       
   843     ...    [join(sample_buildout, 'eggs'),
       
   844     ...     join(sample_buildout, 'develop-eggs'),
       
   845     ...     ])]
       
   846     ['foox', 'setuptools']
       
   847 
       
   848     >>> print handler
       
   849     zc.buildout.easy_install WARNING
       
   850       Develop distribution: foox 0.0.0
       
   851     uses namespace packages but the distribution does not require setuptools.
       
   852 
       
   853     >>> handler.clear()
       
   854 
       
   855 On the other hand, if we have a regular egg, rather than a develop egg:
       
   856 
       
   857     >>> os.remove(join('develop-eggs', 'foox.egg-link'))
       
   858 
       
   859     >>> _ = system(join('bin', 'buildout') + ' setup foo bdist_egg -d'
       
   860     ...            + join(sample_buildout, 'eggs'))
       
   861 
       
   862     >>> ls('develop-eggs')
       
   863     -  z3c.recipe.scripts.egg-link
       
   864     -  zc.recipe.egg.egg-link
       
   865 
       
   866     >>> print 'START ->'; ls('eggs') # doctest: +ELLIPSIS
       
   867     START...
       
   868     -  foox-0.0.0-py2.4.egg
       
   869     ...
       
   870 
       
   871 We do not get a warning, but we do get setuptools included in the working set:
       
   872 
       
   873     >>> [dist.project_name
       
   874     ...  for dist in zc.buildout.easy_install.working_set(
       
   875     ...    ['foox'], sys.executable,
       
   876     ...    [join(sample_buildout, 'eggs'),
       
   877     ...     join(sample_buildout, 'develop-eggs'),
       
   878     ...     ])]
       
   879     ['foox', 'setuptools']
       
   880 
       
   881     >>> print handler,
       
   882 
       
   883 We get the same behavior if the it is a depedency that uses a
       
   884 namespace package.
       
   885 
       
   886 
       
   887     >>> mkdir('bar')
       
   888     >>> write('bar', 'setup.py',
       
   889     ... """
       
   890     ... from setuptools import setup
       
   891     ... setup(name='bar', install_requires = ['foox'])
       
   892     ... """)
       
   893     >>> write('bar', 'README.txt', '')
       
   894 
       
   895     >>> write('buildout.cfg',
       
   896     ... """
       
   897     ... [buildout]
       
   898     ... develop = foo bar
       
   899     ... parts =
       
   900     ... """)
       
   901 
       
   902     >>> print system(join('bin', 'buildout')),
       
   903     Develop: '/sample-buildout/foo'
       
   904     Develop: '/sample-buildout/bar'
       
   905 
       
   906     >>> [dist.project_name
       
   907     ...  for dist in zc.buildout.easy_install.working_set(
       
   908     ...    ['bar'], sys.executable,
       
   909     ...    [join(sample_buildout, 'eggs'),
       
   910     ...     join(sample_buildout, 'develop-eggs'),
       
   911     ...     ])]
       
   912     ['bar', 'foox', 'setuptools']
       
   913 
       
   914     >>> print handler,
       
   915     zc.buildout.easy_install WARNING
       
   916       Develop distribution: foox 0.0.0
       
   917     uses namespace packages but the distribution does not require setuptools.
       
   918 
       
   919 
       
   920     >>> logging.getLogger('zc.buildout.easy_install').propagate = True
       
   921     >>> handler.uninstall()
       
   922 
       
   923     '''
       
   924 
       
   925 def develop_preserves_existing_setup_cfg():
       
   926     """
       
   927 
       
   928 See "Handling custom build options for extensions in develop eggs" in
       
   929 easy_install.txt.  This will be very similar except that we'll have an
       
   930 existing setup.cfg:
       
   931 
       
   932     >>> write(extdemo, "setup.cfg",
       
   933     ... '''
       
   934     ... # sampe cfg file
       
   935     ...
       
   936     ... [foo]
       
   937     ... bar = 1
       
   938     ...
       
   939     ... [build_ext]
       
   940     ... define = X,Y
       
   941     ... ''')
       
   942 
       
   943     >>> mkdir('include')
       
   944     >>> write('include', 'extdemo.h',
       
   945     ... '''
       
   946     ... #define EXTDEMO 42
       
   947     ... ''')
       
   948 
       
   949     >>> dest = tmpdir('dest')
       
   950     >>> zc.buildout.easy_install.develop(
       
   951     ...   extdemo, dest,
       
   952     ...   {'include-dirs': os.path.join(sample_buildout, 'include')})
       
   953     '/dest/extdemo.egg-link'
       
   954 
       
   955     >>> ls(dest)
       
   956     -  extdemo.egg-link
       
   957 
       
   958     >>> cat(extdemo, "setup.cfg")
       
   959     <BLANKLINE>
       
   960     # sampe cfg file
       
   961     <BLANKLINE>
       
   962     [foo]
       
   963     bar = 1
       
   964     <BLANKLINE>
       
   965     [build_ext]
       
   966     define = X,Y
       
   967 
       
   968 """
       
   969 
       
   970 def uninstall_recipes_used_for_removal():
       
   971     """
       
   972 Uninstall recipes need to be called when a part is removed too:
       
   973 
       
   974     >>> mkdir("recipes")
       
   975     >>> write("recipes", "setup.py",
       
   976     ... '''
       
   977     ... from setuptools import setup
       
   978     ... setup(name='recipes',
       
   979     ...       entry_points={
       
   980     ...          'zc.buildout': ["demo=demo:Install"],
       
   981     ...          'zc.buildout.uninstall': ["demo=demo:uninstall"],
       
   982     ...          })
       
   983     ... ''')
       
   984 
       
   985     >>> write("recipes", "demo.py",
       
   986     ... '''
       
   987     ... class Install:
       
   988     ...     def __init__(*args): pass
       
   989     ...     def install(self):
       
   990     ...         print 'installing'
       
   991     ...         return ()
       
   992     ... def uninstall(name, options): print 'uninstalling'
       
   993     ... ''')
       
   994 
       
   995     >>> write('buildout.cfg', '''
       
   996     ... [buildout]
       
   997     ... develop = recipes
       
   998     ... parts = demo
       
   999     ... [demo]
       
  1000     ... recipe = recipes:demo
       
  1001     ... ''')
       
  1002 
       
  1003     >>> print system(join('bin', 'buildout')),
       
  1004     Develop: '/sample-buildout/recipes'
       
  1005     Installing demo.
       
  1006     installing
       
  1007 
       
  1008 
       
  1009     >>> write('buildout.cfg', '''
       
  1010     ... [buildout]
       
  1011     ... develop = recipes
       
  1012     ... parts = demo
       
  1013     ... [demo]
       
  1014     ... recipe = recipes:demo
       
  1015     ... x = 1
       
  1016     ... ''')
       
  1017 
       
  1018     >>> print system(join('bin', 'buildout')),
       
  1019     Develop: '/sample-buildout/recipes'
       
  1020     Uninstalling demo.
       
  1021     Running uninstall recipe.
       
  1022     uninstalling
       
  1023     Installing demo.
       
  1024     installing
       
  1025 
       
  1026 
       
  1027     >>> write('buildout.cfg', '''
       
  1028     ... [buildout]
       
  1029     ... develop = recipes
       
  1030     ... parts =
       
  1031     ... ''')
       
  1032 
       
  1033     >>> print system(join('bin', 'buildout')),
       
  1034     Develop: '/sample-buildout/recipes'
       
  1035     Uninstalling demo.
       
  1036     Running uninstall recipe.
       
  1037     uninstalling
       
  1038 
       
  1039 """
       
  1040 
       
  1041 def extensions_installed_as_eggs_work_in_offline_mode():
       
  1042     '''
       
  1043     >>> mkdir('demo')
       
  1044 
       
  1045     >>> write('demo', 'demo.py',
       
  1046     ... """
       
  1047     ... def ext(buildout):
       
  1048     ...     print 'ext', list(buildout)
       
  1049     ... """)
       
  1050 
       
  1051     >>> write('demo', 'setup.py',
       
  1052     ... """
       
  1053     ... from setuptools import setup
       
  1054     ...
       
  1055     ... setup(
       
  1056     ...     name = "demo",
       
  1057     ...     py_modules=['demo'],
       
  1058     ...     entry_points = {'zc.buildout.extension': ['ext = demo:ext']},
       
  1059     ...     )
       
  1060     ... """)
       
  1061 
       
  1062     >>> bdist_egg(join(sample_buildout, "demo"), sys.executable,
       
  1063     ...           join(sample_buildout, "eggs"))
       
  1064 
       
  1065     >>> write(sample_buildout, 'buildout.cfg',
       
  1066     ... """
       
  1067     ... [buildout]
       
  1068     ... extensions = demo
       
  1069     ... parts =
       
  1070     ... offline = true
       
  1071     ... """)
       
  1072 
       
  1073     >>> print system(join(sample_buildout, 'bin', 'buildout')),
       
  1074     ext ['buildout']
       
  1075 
       
  1076 
       
  1077     '''
       
  1078 
       
  1079 def changes_in_svn_or_CVS_dont_affect_sig():
       
  1080     """
       
  1081 
       
  1082 If we have a develop recipe, it's signature shouldn't be affected to
       
  1083 changes in .svn or CVS directories.
       
  1084 
       
  1085     >>> mkdir('recipe')
       
  1086     >>> write('recipe', 'setup.py',
       
  1087     ... '''
       
  1088     ... from setuptools import setup
       
  1089     ... setup(name='recipe',
       
  1090     ...       entry_points={'zc.buildout': ['default=foo:Foo']})
       
  1091     ... ''')
       
  1092     >>> write('recipe', 'foo.py',
       
  1093     ... '''
       
  1094     ... class Foo:
       
  1095     ...     def __init__(*args): pass
       
  1096     ...     def install(*args): return ()
       
  1097     ...     update = install
       
  1098     ... ''')
       
  1099 
       
  1100     >>> write('buildout.cfg',
       
  1101     ... '''
       
  1102     ... [buildout]
       
  1103     ... develop = recipe
       
  1104     ... parts = foo
       
  1105     ...
       
  1106     ... [foo]
       
  1107     ... recipe = recipe
       
  1108     ... ''')
       
  1109 
       
  1110 
       
  1111     >>> print system(join(sample_buildout, 'bin', 'buildout')),
       
  1112     Develop: '/sample-buildout/recipe'
       
  1113     Installing foo.
       
  1114 
       
  1115     >>> mkdir('recipe', '.svn')
       
  1116     >>> mkdir('recipe', 'CVS')
       
  1117     >>> print system(join(sample_buildout, 'bin', 'buildout')),
       
  1118     Develop: '/sample-buildout/recipe'
       
  1119     Updating foo.
       
  1120 
       
  1121     >>> write('recipe', '.svn', 'x', '1')
       
  1122     >>> write('recipe', 'CVS', 'x', '1')
       
  1123 
       
  1124     >>> print system(join(sample_buildout, 'bin', 'buildout')),
       
  1125     Develop: '/sample-buildout/recipe'
       
  1126     Updating foo.
       
  1127 
       
  1128     """
       
  1129 
       
  1130 if hasattr(os, 'symlink'):
       
  1131     def bug_250537_broken_symlink_doesnt_affect_sig():
       
  1132         """
       
  1133 If we have a develop recipe, it's signature shouldn't be affected by
       
  1134 broken symlinks, and better yet, computing the hash should not break
       
  1135 because of the missing target file.
       
  1136 
       
  1137     >>> mkdir('recipe')
       
  1138     >>> write('recipe', 'setup.py',
       
  1139     ... '''
       
  1140     ... from setuptools import setup
       
  1141     ... setup(name='recipe',
       
  1142     ...       entry_points={'zc.buildout': ['default=foo:Foo']})
       
  1143     ... ''')
       
  1144     >>> write('recipe', 'foo.py',
       
  1145     ... '''
       
  1146     ... class Foo:
       
  1147     ...     def __init__(*args): pass
       
  1148     ...     def install(*args): return ()
       
  1149     ...     update = install
       
  1150     ... ''')
       
  1151 
       
  1152     >>> write('buildout.cfg',
       
  1153     ... '''
       
  1154     ... [buildout]
       
  1155     ... develop = recipe
       
  1156     ... parts = foo
       
  1157     ...
       
  1158     ... [foo]
       
  1159     ... recipe = recipe
       
  1160     ... ''')
       
  1161 
       
  1162 
       
  1163     >>> print system(join(sample_buildout, 'bin', 'buildout')),
       
  1164     Develop: '/sample-buildout/recipe'
       
  1165     Installing foo.
       
  1166 
       
  1167     >>> write('recipe', 'some-file', '1')
       
  1168     >>> os.symlink(join('recipe', 'some-file'),
       
  1169     ...            join('recipe', 'another-file'))
       
  1170     >>> ls('recipe')
       
  1171     l  another-file
       
  1172     -  foo.py
       
  1173     -  foo.pyc
       
  1174     d  recipe.egg-info
       
  1175     -  setup.py
       
  1176     -  some-file
       
  1177 
       
  1178     >>> remove('recipe', 'some-file')
       
  1179 
       
  1180     >>> print system(join(sample_buildout, 'bin', 'buildout')),
       
  1181     Develop: '/sample-buildout/recipe'
       
  1182     Updating foo.
       
  1183 
       
  1184     """
       
  1185 
       
  1186 def o_option_sets_offline():
       
  1187     """
       
  1188     >>> print system(join(sample_buildout, 'bin', 'buildout')+' -vvo'),
       
  1189     ... # doctest: +ELLIPSIS
       
  1190     <BLANKLINE>
       
  1191     ...
       
  1192     offline = true
       
  1193     ...
       
  1194     """
       
  1195 
       
  1196 def recipe_upgrade():
       
  1197     """
       
  1198 
       
  1199 The buildout will upgrade recipes in newest (and non-offline) mode.
       
  1200 
       
  1201 Let's create a recipe egg
       
  1202 
       
  1203     >>> mkdir('recipe')
       
  1204     >>> write('recipe', 'recipe.py',
       
  1205     ... '''
       
  1206     ... class Recipe:
       
  1207     ...     def __init__(*a): pass
       
  1208     ...     def install(self):
       
  1209     ...         print 'recipe v1'
       
  1210     ...         return ()
       
  1211     ...     update = install
       
  1212     ... ''')
       
  1213 
       
  1214     >>> write('recipe', 'setup.py',
       
  1215     ... '''
       
  1216     ... from setuptools import setup
       
  1217     ... setup(name='recipe', version='1', py_modules=['recipe'],
       
  1218     ...       entry_points={'zc.buildout': ['default = recipe:Recipe']},
       
  1219     ...       )
       
  1220     ... ''')
       
  1221 
       
  1222     >>> write('recipe', 'README', '')
       
  1223 
       
  1224     >>> print system(buildout+' setup recipe bdist_egg'), # doctest: +ELLIPSIS
       
  1225     Running setup script 'recipe/setup.py'.
       
  1226     ...
       
  1227 
       
  1228     >>> rmdir('recipe', 'build')
       
  1229 
       
  1230 And update our buildout to use it.
       
  1231 
       
  1232     >>> write('buildout.cfg',
       
  1233     ... '''
       
  1234     ... [buildout]
       
  1235     ... parts = foo
       
  1236     ... find-links = %s
       
  1237     ...
       
  1238     ... [foo]
       
  1239     ... recipe = recipe
       
  1240     ... ''' % join('recipe', 'dist'))
       
  1241 
       
  1242     >>> print system(buildout),
       
  1243     Getting distribution for 'recipe'.
       
  1244     Got recipe 1.
       
  1245     Installing foo.
       
  1246     recipe v1
       
  1247 
       
  1248 Now, if we update the recipe egg:
       
  1249 
       
  1250     >>> write('recipe', 'recipe.py',
       
  1251     ... '''
       
  1252     ... class Recipe:
       
  1253     ...     def __init__(*a): pass
       
  1254     ...     def install(self):
       
  1255     ...         print 'recipe v2'
       
  1256     ...         return ()
       
  1257     ...     update = install
       
  1258     ... ''')
       
  1259 
       
  1260     >>> write('recipe', 'setup.py',
       
  1261     ... '''
       
  1262     ... from setuptools import setup
       
  1263     ... setup(name='recipe', version='2', py_modules=['recipe'],
       
  1264     ...       entry_points={'zc.buildout': ['default = recipe:Recipe']},
       
  1265     ...       )
       
  1266     ... ''')
       
  1267 
       
  1268 
       
  1269     >>> print system(buildout+' setup recipe bdist_egg'), # doctest: +ELLIPSIS
       
  1270     Running setup script 'recipe/setup.py'.
       
  1271     ...
       
  1272 
       
  1273 We won't get the update if we specify -N:
       
  1274 
       
  1275     >>> print system(buildout+' -N'),
       
  1276     Updating foo.
       
  1277     recipe v1
       
  1278 
       
  1279 or if we use -o:
       
  1280 
       
  1281     >>> print system(buildout+' -o'),
       
  1282     Updating foo.
       
  1283     recipe v1
       
  1284 
       
  1285 But we will if we use neither of these:
       
  1286 
       
  1287     >>> print system(buildout),
       
  1288     Getting distribution for 'recipe'.
       
  1289     Got recipe 2.
       
  1290     Uninstalling foo.
       
  1291     Installing foo.
       
  1292     recipe v2
       
  1293 
       
  1294 We can also select a particular recipe version:
       
  1295 
       
  1296     >>> write('buildout.cfg',
       
  1297     ... '''
       
  1298     ... [buildout]
       
  1299     ... parts = foo
       
  1300     ... find-links = %s
       
  1301     ...
       
  1302     ... [foo]
       
  1303     ... recipe = recipe ==1
       
  1304     ... ''' % join('recipe', 'dist'))
       
  1305 
       
  1306     >>> print system(buildout),
       
  1307     Uninstalling foo.
       
  1308     Installing foo.
       
  1309     recipe v1
       
  1310 
       
  1311     """
       
  1312 
       
  1313 def update_adds_to_uninstall_list():
       
  1314     """
       
  1315 
       
  1316 Paths returned by the update method are added to the list of paths to
       
  1317 uninstall
       
  1318 
       
  1319     >>> mkdir('recipe')
       
  1320     >>> write('recipe', 'setup.py',
       
  1321     ... '''
       
  1322     ... from setuptools import setup
       
  1323     ... setup(name='recipe',
       
  1324     ...       entry_points={'zc.buildout': ['default = recipe:Recipe']},
       
  1325     ...       )
       
  1326     ... ''')
       
  1327 
       
  1328     >>> write('recipe', 'recipe.py',
       
  1329     ... '''
       
  1330     ... import os
       
  1331     ... class Recipe:
       
  1332     ...     def __init__(*_): pass
       
  1333     ...     def install(self):
       
  1334     ...         r = ('a', 'b', 'c')
       
  1335     ...         for p in r: os.mkdir(p)
       
  1336     ...         return r
       
  1337     ...     def update(self):
       
  1338     ...         r = ('c', 'd', 'e')
       
  1339     ...         for p in r:
       
  1340     ...             if not os.path.exists(p):
       
  1341     ...                os.mkdir(p)
       
  1342     ...         return r
       
  1343     ... ''')
       
  1344 
       
  1345     >>> write('buildout.cfg',
       
  1346     ... '''
       
  1347     ... [buildout]
       
  1348     ... develop = recipe
       
  1349     ... parts = foo
       
  1350     ...
       
  1351     ... [foo]
       
  1352     ... recipe = recipe
       
  1353     ... ''')
       
  1354 
       
  1355     >>> print system(buildout),
       
  1356     Develop: '/sample-buildout/recipe'
       
  1357     Installing foo.
       
  1358 
       
  1359     >>> print system(buildout),
       
  1360     Develop: '/sample-buildout/recipe'
       
  1361     Updating foo.
       
  1362 
       
  1363     >>> cat('.installed.cfg') # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
       
  1364     [buildout]
       
  1365     ...
       
  1366     [foo]
       
  1367     __buildout_installed__ = a
       
  1368     	b
       
  1369     	c
       
  1370     	d
       
  1371     	e
       
  1372     __buildout_signature__ = ...
       
  1373 
       
  1374 """
       
  1375 
       
  1376 def log_when_there_are_not_local_distros():
       
  1377     """
       
  1378     >>> from zope.testing.loggingsupport import InstalledHandler
       
  1379     >>> handler = InstalledHandler('zc.buildout.easy_install')
       
  1380     >>> import logging
       
  1381     >>> logger = logging.getLogger('zc.buildout.easy_install')
       
  1382     >>> old_propogate = logger.propagate
       
  1383     >>> logger.propagate = False
       
  1384 
       
  1385     >>> dest = tmpdir('sample-install')
       
  1386     >>> import zc.buildout.easy_install
       
  1387     >>> ws = zc.buildout.easy_install.install(
       
  1388     ...     ['demo==0.2'], dest,
       
  1389     ...     links=[link_server], index=link_server+'index/')
       
  1390 
       
  1391     >>> print handler # doctest: +ELLIPSIS
       
  1392     zc.buildout.easy_install DEBUG
       
  1393       Installing 'demo==0.2'.
       
  1394     zc.buildout.easy_install DEBUG
       
  1395       We have no distributions for demo that satisfies 'demo==0.2'.
       
  1396     ...
       
  1397 
       
  1398     >>> handler.uninstall()
       
  1399     >>> logger.propagate = old_propogate
       
  1400 
       
  1401     """
       
  1402 
       
  1403 def internal_errors():
       
  1404     """Internal errors are clearly marked and don't generate tracebacks:
       
  1405 
       
  1406     >>> mkdir(sample_buildout, 'recipes')
       
  1407 
       
  1408     >>> write(sample_buildout, 'recipes', 'mkdir.py',
       
  1409     ... '''
       
  1410     ... class Mkdir:
       
  1411     ...     def __init__(self, buildout, name, options):
       
  1412     ...         self.name, self.options = name, options
       
  1413     ...         options['path'] = os.path.join(
       
  1414     ...                               buildout['buildout']['directory'],
       
  1415     ...                               options['path'],
       
  1416     ...                               )
       
  1417     ... ''')
       
  1418 
       
  1419     >>> write(sample_buildout, 'recipes', 'setup.py',
       
  1420     ... '''
       
  1421     ... from setuptools import setup
       
  1422     ... setup(name = "recipes",
       
  1423     ...       entry_points = {'zc.buildout': ['mkdir = mkdir:Mkdir']},
       
  1424     ...       )
       
  1425     ... ''')
       
  1426 
       
  1427     >>> write(sample_buildout, 'buildout.cfg',
       
  1428     ... '''
       
  1429     ... [buildout]
       
  1430     ... develop = recipes
       
  1431     ... parts = data-dir
       
  1432     ...
       
  1433     ... [data-dir]
       
  1434     ... recipe = recipes:mkdir
       
  1435     ... ''')
       
  1436 
       
  1437     >>> print system(buildout), # doctest: +ELLIPSIS
       
  1438     Develop: '/sample-buildout/recipes'
       
  1439     While:
       
  1440       Installing.
       
  1441       Getting section data-dir.
       
  1442       Initializing part data-dir.
       
  1443     <BLANKLINE>
       
  1444     An internal error occurred due to a bug in either zc.buildout or in a
       
  1445     recipe being used:
       
  1446     Traceback (most recent call last):
       
  1447     ...
       
  1448     NameError: global name 'os' is not defined
       
  1449     """
       
  1450 
       
  1451 def whine_about_unused_options():
       
  1452     '''
       
  1453 
       
  1454     >>> write('foo.py',
       
  1455     ... """
       
  1456     ... class Foo:
       
  1457     ...
       
  1458     ...     def __init__(self, buildout, name, options):
       
  1459     ...         self.name, self.options = name, options
       
  1460     ...         options['x']
       
  1461     ...
       
  1462     ...     def install(self):
       
  1463     ...         self.options['y']
       
  1464     ...         return ()
       
  1465     ... """)
       
  1466 
       
  1467     >>> write('setup.py',
       
  1468     ... """
       
  1469     ... from setuptools import setup
       
  1470     ... setup(name = "foo",
       
  1471     ...       entry_points = {'zc.buildout': ['default = foo:Foo']},
       
  1472     ...       )
       
  1473     ... """)
       
  1474 
       
  1475     >>> write('buildout.cfg',
       
  1476     ... """
       
  1477     ... [buildout]
       
  1478     ... develop = .
       
  1479     ... parts = foo
       
  1480     ... a = 1
       
  1481     ...
       
  1482     ... [foo]
       
  1483     ... recipe = foo
       
  1484     ... x = 1
       
  1485     ... y = 1
       
  1486     ... z = 1
       
  1487     ... """)
       
  1488 
       
  1489     >>> print system(buildout),
       
  1490     Develop: '/sample-buildout/.'
       
  1491     Unused options for buildout: 'a'.
       
  1492     Installing foo.
       
  1493     Unused options for foo: 'z'.
       
  1494     '''
       
  1495 
       
  1496 def abnormal_exit():
       
  1497     """
       
  1498 People sometimes hit control-c while running a builout. We need to make
       
  1499 sure that the installed database Isn't corrupted.  To test this, we'll create
       
  1500 some evil recipes that exit uncleanly:
       
  1501 
       
  1502     >>> mkdir('recipes')
       
  1503     >>> write('recipes', 'recipes.py',
       
  1504     ... '''
       
  1505     ... import os
       
  1506     ...
       
  1507     ... class Clean:
       
  1508     ...     def __init__(*_): pass
       
  1509     ...     def install(_): return ()
       
  1510     ...     def update(_): pass
       
  1511     ...
       
  1512     ... class EvilInstall(Clean):
       
  1513     ...     def install(_): os._exit(1)
       
  1514     ...
       
  1515     ... class EvilUpdate(Clean):
       
  1516     ...     def update(_): os._exit(1)
       
  1517     ... ''')
       
  1518 
       
  1519     >>> write('recipes', 'setup.py',
       
  1520     ... '''
       
  1521     ... import setuptools
       
  1522     ... setuptools.setup(name='recipes',
       
  1523     ...    entry_points = {
       
  1524     ...      'zc.buildout': [
       
  1525     ...          'clean = recipes:Clean',
       
  1526     ...          'evil_install = recipes:EvilInstall',
       
  1527     ...          'evil_update = recipes:EvilUpdate',
       
  1528     ...          'evil_uninstall = recipes:Clean',
       
  1529     ...          ],
       
  1530     ...       },
       
  1531     ...     )
       
  1532     ... ''')
       
  1533 
       
  1534 Now let's look at 3 cases:
       
  1535 
       
  1536 1. We exit during installation after installing some other parts:
       
  1537 
       
  1538     >>> write('buildout.cfg',
       
  1539     ... '''
       
  1540     ... [buildout]
       
  1541     ... develop = recipes
       
  1542     ... parts = p1 p2 p3 p4
       
  1543     ...
       
  1544     ... [p1]
       
  1545     ... recipe = recipes:clean
       
  1546     ...
       
  1547     ... [p2]
       
  1548     ... recipe = recipes:clean
       
  1549     ...
       
  1550     ... [p3]
       
  1551     ... recipe = recipes:evil_install
       
  1552     ...
       
  1553     ... [p4]
       
  1554     ... recipe = recipes:clean
       
  1555     ... ''')
       
  1556 
       
  1557     >>> print system(buildout),
       
  1558     Develop: '/sample-buildout/recipes'
       
  1559     Installing p1.
       
  1560     Installing p2.
       
  1561     Installing p3.
       
  1562 
       
  1563     >>> print system(buildout),
       
  1564     Develop: '/sample-buildout/recipes'
       
  1565     Updating p1.
       
  1566     Updating p2.
       
  1567     Installing p3.
       
  1568 
       
  1569     >>> print system(buildout+' buildout:parts='),
       
  1570     Develop: '/sample-buildout/recipes'
       
  1571     Uninstalling p2.
       
  1572     Uninstalling p1.
       
  1573 
       
  1574 2. We exit while updating:
       
  1575 
       
  1576     >>> write('buildout.cfg',
       
  1577     ... '''
       
  1578     ... [buildout]
       
  1579     ... develop = recipes
       
  1580     ... parts = p1 p2 p3 p4
       
  1581     ...
       
  1582     ... [p1]
       
  1583     ... recipe = recipes:clean
       
  1584     ...
       
  1585     ... [p2]
       
  1586     ... recipe = recipes:clean
       
  1587     ...
       
  1588     ... [p3]
       
  1589     ... recipe = recipes:evil_update
       
  1590     ...
       
  1591     ... [p4]
       
  1592     ... recipe = recipes:clean
       
  1593     ... ''')
       
  1594 
       
  1595     >>> print system(buildout),
       
  1596     Develop: '/sample-buildout/recipes'
       
  1597     Installing p1.
       
  1598     Installing p2.
       
  1599     Installing p3.
       
  1600     Installing p4.
       
  1601 
       
  1602     >>> print system(buildout),
       
  1603     Develop: '/sample-buildout/recipes'
       
  1604     Updating p1.
       
  1605     Updating p2.
       
  1606     Updating p3.
       
  1607 
       
  1608     >>> print system(buildout+' buildout:parts='),
       
  1609     Develop: '/sample-buildout/recipes'
       
  1610     Uninstalling p2.
       
  1611     Uninstalling p1.
       
  1612     Uninstalling p4.
       
  1613     Uninstalling p3.
       
  1614 
       
  1615 3. We exit while installing or updating after uninstalling:
       
  1616 
       
  1617     >>> write('buildout.cfg',
       
  1618     ... '''
       
  1619     ... [buildout]
       
  1620     ... develop = recipes
       
  1621     ... parts = p1 p2 p3 p4
       
  1622     ...
       
  1623     ... [p1]
       
  1624     ... recipe = recipes:evil_update
       
  1625     ...
       
  1626     ... [p2]
       
  1627     ... recipe = recipes:clean
       
  1628     ...
       
  1629     ... [p3]
       
  1630     ... recipe = recipes:clean
       
  1631     ...
       
  1632     ... [p4]
       
  1633     ... recipe = recipes:clean
       
  1634     ... ''')
       
  1635 
       
  1636     >>> print system(buildout),
       
  1637     Develop: '/sample-buildout/recipes'
       
  1638     Installing p1.
       
  1639     Installing p2.
       
  1640     Installing p3.
       
  1641     Installing p4.
       
  1642 
       
  1643     >>> write('buildout.cfg',
       
  1644     ... '''
       
  1645     ... [buildout]
       
  1646     ... develop = recipes
       
  1647     ... parts = p1 p2 p3 p4
       
  1648     ...
       
  1649     ... [p1]
       
  1650     ... recipe = recipes:evil_update
       
  1651     ...
       
  1652     ... [p2]
       
  1653     ... recipe = recipes:clean
       
  1654     ...
       
  1655     ... [p3]
       
  1656     ... recipe = recipes:clean
       
  1657     ...
       
  1658     ... [p4]
       
  1659     ... recipe = recipes:clean
       
  1660     ... x = 1
       
  1661     ... ''')
       
  1662 
       
  1663     >>> print system(buildout),
       
  1664     Develop: '/sample-buildout/recipes'
       
  1665     Uninstalling p4.
       
  1666     Updating p1.
       
  1667 
       
  1668     >>> write('buildout.cfg',
       
  1669     ... '''
       
  1670     ... [buildout]
       
  1671     ... develop = recipes
       
  1672     ... parts = p1 p2 p3 p4
       
  1673     ...
       
  1674     ... [p1]
       
  1675     ... recipe = recipes:clean
       
  1676     ...
       
  1677     ... [p2]
       
  1678     ... recipe = recipes:clean
       
  1679     ...
       
  1680     ... [p3]
       
  1681     ... recipe = recipes:clean
       
  1682     ...
       
  1683     ... [p4]
       
  1684     ... recipe = recipes:clean
       
  1685     ... ''')
       
  1686 
       
  1687     >>> print system(buildout),
       
  1688     Develop: '/sample-buildout/recipes'
       
  1689     Uninstalling p1.
       
  1690     Installing p1.
       
  1691     Updating p2.
       
  1692     Updating p3.
       
  1693     Installing p4.
       
  1694 
       
  1695     """
       
  1696 
       
  1697 def install_source_dist_with_bad_py():
       
  1698     """
       
  1699 
       
  1700     >>> mkdir('badegg')
       
  1701     >>> mkdir('badegg', 'badegg')
       
  1702     >>> write('badegg', 'badegg', '__init__.py', '#\\n')
       
  1703     >>> mkdir('badegg', 'badegg', 'scripts')
       
  1704     >>> write('badegg', 'badegg', 'scripts', '__init__.py', '#\\n')
       
  1705     >>> write('badegg', 'badegg', 'scripts', 'one.py',
       
  1706     ... '''
       
  1707     ... return 1
       
  1708     ... ''')
       
  1709 
       
  1710     >>> write('badegg', 'setup.py',
       
  1711     ... '''
       
  1712     ... from setuptools import setup, find_packages
       
  1713     ... setup(
       
  1714     ...     name='badegg',
       
  1715     ...     version='1',
       
  1716     ...     packages = find_packages('.'),
       
  1717     ...     zip_safe=False)
       
  1718     ... ''')
       
  1719 
       
  1720     >>> print system(buildout+' setup badegg sdist'), # doctest: +ELLIPSIS
       
  1721     Running setup script 'badegg/setup.py'.
       
  1722     ...
       
  1723 
       
  1724     >>> dist = join('badegg', 'dist')
       
  1725 
       
  1726     >>> write('buildout.cfg',
       
  1727     ... '''
       
  1728     ... [buildout]
       
  1729     ... parts = eggs bo
       
  1730     ... find-links = %(dist)s
       
  1731     ...
       
  1732     ... [eggs]
       
  1733     ... recipe = zc.recipe.egg
       
  1734     ... eggs = badegg
       
  1735     ...
       
  1736     ... [bo]
       
  1737     ... recipe = zc.recipe.egg
       
  1738     ... eggs = zc.buildout
       
  1739     ... scripts = buildout=bo
       
  1740     ... ''' % globals())
       
  1741 
       
  1742     >>> print system(buildout);print 'X' # doctest: +ELLIPSIS
       
  1743     Installing eggs.
       
  1744     Getting distribution for 'badegg'.
       
  1745     Got badegg 1.
       
  1746     Installing bo.
       
  1747     ...
       
  1748     SyntaxError: ...'return' outside function...
       
  1749     ...
       
  1750     SyntaxError: ...'return' outside function...
       
  1751     ...
       
  1752 
       
  1753     >>> ls('eggs') # doctest: +ELLIPSIS
       
  1754     d  badegg-1-py2.4.egg
       
  1755     ...
       
  1756 
       
  1757     >>> ls('bin')
       
  1758     -  bo
       
  1759     -  buildout
       
  1760     """
       
  1761 
       
  1762 def version_requirements_in_build_honored():
       
  1763     '''
       
  1764 
       
  1765     >>> update_extdemo()
       
  1766     >>> dest = tmpdir('sample-install')
       
  1767     >>> mkdir('include')
       
  1768     >>> write('include', 'extdemo.h',
       
  1769     ... """
       
  1770     ... #define EXTDEMO 42
       
  1771     ... """)
       
  1772 
       
  1773     >>> zc.buildout.easy_install.build(
       
  1774     ...   'extdemo ==1.4', dest,
       
  1775     ...   {'include-dirs': os.path.join(sample_buildout, 'include')},
       
  1776     ...   links=[link_server], index=link_server+'index/',
       
  1777     ...   newest=False)
       
  1778     ['/sample-install/extdemo-1.4-py2.4-linux-i686.egg']
       
  1779 
       
  1780     '''
       
  1781 
       
  1782 def bug_105081_Specific_egg_versions_are_ignored_when_newer_eggs_are_around():
       
  1783     """
       
  1784     Buildout might ignore a specific egg requirement for a recipe:
       
  1785 
       
  1786     - Have a newer version of an egg in your eggs directory
       
  1787     - Use 'recipe==olderversion' in your buildout.cfg to request an
       
  1788       older version
       
  1789 
       
  1790     Buildout will go and fetch the older version, but it will *use*
       
  1791     the newer version when installing a part with this recipe.
       
  1792 
       
  1793     >>> write('buildout.cfg',
       
  1794     ... '''
       
  1795     ... [buildout]
       
  1796     ... parts = x
       
  1797     ... find-links = %(sample_eggs)s
       
  1798     ...
       
  1799     ... [x]
       
  1800     ... recipe = zc.recipe.egg
       
  1801     ... eggs = demo
       
  1802     ... ''' % globals())
       
  1803 
       
  1804     >>> print system(buildout),
       
  1805     Installing x.
       
  1806     Getting distribution for 'demo'.
       
  1807     Got demo 0.4c1.
       
  1808     Getting distribution for 'demoneeded'.
       
  1809     Got demoneeded 1.2c1.
       
  1810     Generated script '/sample-buildout/bin/demo'.
       
  1811 
       
  1812     >>> print system(join('bin', 'demo')),
       
  1813     4 2
       
  1814 
       
  1815     >>> write('buildout.cfg',
       
  1816     ... '''
       
  1817     ... [buildout]
       
  1818     ... parts = x
       
  1819     ... find-links = %(sample_eggs)s
       
  1820     ...
       
  1821     ... [x]
       
  1822     ... recipe = zc.recipe.egg
       
  1823     ... eggs = demo ==0.1
       
  1824     ... ''' % globals())
       
  1825 
       
  1826     >>> print system(buildout),
       
  1827     Uninstalling x.
       
  1828     Installing x.
       
  1829     Getting distribution for 'demo==0.1'.
       
  1830     Got demo 0.1.
       
  1831     Generated script '/sample-buildout/bin/demo'.
       
  1832 
       
  1833     >>> print system(join('bin', 'demo')),
       
  1834     1 2
       
  1835     """
       
  1836 
       
  1837 def versions_section_ignored_for_dependency_in_favor_of_site_packages():
       
  1838     r"""
       
  1839 This is a test for a bugfix.
       
  1840 
       
  1841 The error showed itself when at least two dependencies were in a shared
       
  1842 location like site-packages, and the first one met the "versions" setting.  The
       
  1843 first dependency would be added, but subsequent dependencies from the same
       
  1844 location (e.g., site-packages) would use the version of the package found in
       
  1845 the shared location, ignoring the version setting.
       
  1846 
       
  1847 We begin with a Python that has demoneeded version 1.1 installed and a
       
  1848 demo version 0.3, all in a site-packages-like shared directory.  We need
       
  1849 to create this.  ``eggrecipedemo.main()`` shows the number after the dot
       
  1850 (that is, ``X`` in ``1.X``), for the demo package and the demoneeded
       
  1851 package, so this demonstrates that our Python does in fact have demo
       
  1852 version 0.3 and demoneeded version 1.1.
       
  1853 
       
  1854     >>> py_path = make_py_with_system_install(make_py, sample_eggs)
       
  1855     >>> print call_py(
       
  1856     ...     py_path,
       
  1857     ...     "import tellmy.version; print tellmy.version.__version__"),
       
  1858     1.1
       
  1859 
       
  1860 Now here's a setup that would expose the bug, using the
       
  1861 zc.buildout.easy_install API.
       
  1862 
       
  1863     >>> example_dest = tmpdir('example_dest')
       
  1864     >>> workingset = zc.buildout.easy_install.install(
       
  1865     ...     ['tellmy.version'], example_dest, links=[sample_eggs],
       
  1866     ...     executable=py_path,
       
  1867     ...     index=None,
       
  1868     ...     versions={'tellmy.version': '1.0'})
       
  1869     >>> for dist in workingset:
       
  1870     ...     res = str(dist)
       
  1871     ...     if res.startswith('tellmy.version'):
       
  1872     ...         print res
       
  1873     ...         break
       
  1874     tellmy.version 1.0
       
  1875 
       
  1876 Before the bugfix, the desired tellmy.version distribution would have
       
  1877 been blocked the one in site-packages.
       
  1878 """
       
  1879 
       
  1880 def handle_namespace_package_in_both_site_packages_and_buildout_eggs():
       
  1881     r"""
       
  1882 If you have the same namespace package in both site-packages and in
       
  1883 buildout, we need to be very careful that faux-Python-executables and
       
  1884 scripts generated by easy_install.sitepackage_safe_scripts correctly
       
  1885 combine the two. We show this with the local recipe that uses the
       
  1886 function, z3c.recipe.scripts.
       
  1887 
       
  1888 To demonstrate this, we will create three packages: tellmy.version 1.0,
       
  1889 tellmy.version 1.1, and tellmy.fortune 1.0.  tellmy.version 1.1 is installed.
       
  1890 
       
  1891     >>> py_path = make_py_with_system_install(make_py, sample_eggs)
       
  1892     >>> print call_py(
       
  1893     ...     py_path,
       
  1894     ...     "import tellmy.version; print tellmy.version.__version__")
       
  1895     1.1
       
  1896     <BLANKLINE>
       
  1897 
       
  1898 Now we will create a buildout that creates a script and a faux-Python script.
       
  1899 We want to see that both can successfully import the specified versions of
       
  1900 tellmy.version and tellmy.fortune.
       
  1901 
       
  1902     >>> write('buildout.cfg',
       
  1903     ... '''
       
  1904     ... [buildout]
       
  1905     ... parts = eggs
       
  1906     ... find-links = %(link_server)s
       
  1907     ...
       
  1908     ... [primed_python]
       
  1909     ... executable = %(py_path)s
       
  1910     ...
       
  1911     ... [eggs]
       
  1912     ... recipe = z3c.recipe.scripts
       
  1913     ... python = primed_python
       
  1914     ... interpreter = py
       
  1915     ... include-site-packages = true
       
  1916     ... eggs = tellmy.version == 1.0
       
  1917     ...        tellmy.fortune == 1.0
       
  1918     ...        demo
       
  1919     ... script-initialization =
       
  1920     ...     import tellmy.version
       
  1921     ...     print tellmy.version.__version__
       
  1922     ...     import tellmy.fortune
       
  1923     ...     print tellmy.fortune.__version__
       
  1924     ... ''' % globals())
       
  1925 
       
  1926     >>> print system(buildout)
       
  1927     Installing eggs.
       
  1928     Getting distribution for 'tellmy.version==1.0'.
       
  1929     Got tellmy.version 1.0.
       
  1930     Getting distribution for 'tellmy.fortune==1.0'.
       
  1931     Got tellmy.fortune 1.0.
       
  1932     Getting distribution for 'demo'.
       
  1933     Got demo 0.4c1.
       
  1934     Getting distribution for 'demoneeded'.
       
  1935     Got demoneeded 1.2c1.
       
  1936     Generated script '/sample-buildout/bin/demo'.
       
  1937     Generated interpreter '/sample-buildout/bin/py'.
       
  1938     <BLANKLINE>
       
  1939 
       
  1940 Finally, we are ready to see if it worked.  Prior to the bug fix that
       
  1941 this tests, the results of both calls below was the following::
       
  1942 
       
  1943     1.1
       
  1944     Traceback (most recent call last):
       
  1945       ...
       
  1946     ImportError: No module named fortune
       
  1947     <BLANKLINE>
       
  1948 
       
  1949 In other words, we got the site-packages version of tellmy.version, and
       
  1950 we could not import tellmy.fortune at all.  The following are the correct
       
  1951 results for the interpreter and for the script.
       
  1952 
       
  1953     >>> print call_py(
       
  1954     ...     join('bin', 'py'),
       
  1955     ...     "import tellmy.version; " +
       
  1956     ...     "print tellmy.version.__version__; " +
       
  1957     ...     "import tellmy.fortune; " +
       
  1958     ...     "print tellmy.fortune.__version__") # doctest: +ELLIPSIS
       
  1959     1.0
       
  1960     1.0...
       
  1961 
       
  1962     >>> print system(join('bin', 'demo'))
       
  1963     1.0
       
  1964     1.0
       
  1965     4 2
       
  1966     <BLANKLINE>
       
  1967     """
       
  1968 
       
  1969 def handle_sys_path_version_hack():
       
  1970     r"""
       
  1971 This is a test for a bugfix.
       
  1972 
       
  1973 If you use a Python that has a different version of one of your
       
  1974 dependencies, and the new package tries to do sys.path tricks in the
       
  1975 setup.py to get a __version__, and it uses namespace packages, the older
       
  1976 package will be loaded first, making the setup version the wrong number.
       
  1977 While very arguably packages simply shouldn't do this, some do, and we
       
  1978 don't want buildout to fall over when they do.
       
  1979 
       
  1980 To demonstrate this, we will need to create a distribution that has one of
       
  1981 these unpleasant tricks, and a Python that has an older version installed.
       
  1982 
       
  1983     >>> py_path, site_packages_path = make_py()
       
  1984     >>> for version in ('1.0', '1.1'):
       
  1985     ...     tmp = tempfile.mkdtemp()
       
  1986     ...     try:
       
  1987     ...         write(tmp, 'README.txt', '')
       
  1988     ...         mkdir(tmp, 'src')
       
  1989     ...         mkdir(tmp, 'src', 'tellmy')
       
  1990     ...         write(tmp, 'src', 'tellmy', '__init__.py',
       
  1991     ...             "__import__("
       
  1992     ...             "'pkg_resources').declare_namespace(__name__)\n")
       
  1993     ...         mkdir(tmp, 'src', 'tellmy', 'version')
       
  1994     ...         write(tmp, 'src', 'tellmy', 'version',
       
  1995     ...               '__init__.py', '__version__=%r\n' % version)
       
  1996     ...         write(
       
  1997     ...             tmp, 'setup.py',
       
  1998     ...             "from setuptools import setup\n"
       
  1999     ...             "import sys\n"
       
  2000     ...             "sys.path.insert(0, 'src')\n"
       
  2001     ...             "from tellmy.version import __version__\n"
       
  2002     ...             "setup(\n"
       
  2003     ...             " name='tellmy.version',\n"
       
  2004     ...             " package_dir = {'': 'src'},\n"
       
  2005     ...             " packages = ['tellmy', 'tellmy.version'],\n"
       
  2006     ...             " install_requires = ['setuptools'],\n"
       
  2007     ...             " namespace_packages=['tellmy'],\n"
       
  2008     ...             " zip_safe=True, version=__version__,\n"
       
  2009     ...             " author='bob', url='bob', author_email='bob')\n"
       
  2010     ...             )
       
  2011     ...         zc.buildout.testing.sdist(tmp, sample_eggs)
       
  2012     ...         if version == '1.0':
       
  2013     ...             # We install the 1.0 version in site packages the way a
       
  2014     ...             # system packaging system (debs, rpms) would do it.
       
  2015     ...             zc.buildout.testing.sys_install(tmp, site_packages_path)
       
  2016     ...     finally:
       
  2017     ...         shutil.rmtree(tmp)
       
  2018     >>> print call_py(
       
  2019     ...     py_path,
       
  2020     ...     "import tellmy.version; print tellmy.version.__version__")
       
  2021     1.0
       
  2022     <BLANKLINE>
       
  2023     >>> write('buildout.cfg',
       
  2024     ... '''
       
  2025     ... [buildout]
       
  2026     ... parts = eggs
       
  2027     ... find-links = %(sample_eggs)s
       
  2028     ...
       
  2029     ... [primed_python]
       
  2030     ... executable = %(py_path)s
       
  2031     ...
       
  2032     ... [eggs]
       
  2033     ... recipe = zc.recipe.egg:eggs
       
  2034     ... python = primed_python
       
  2035     ... eggs = tellmy.version == 1.1
       
  2036     ... ''' % globals())
       
  2037 
       
  2038 Before the bugfix, running this buildout would generate this error:
       
  2039 
       
  2040     Installing eggs.
       
  2041     Getting distribution for 'tellmy.version==1.1'.
       
  2042     Installing tellmy.version 1.1
       
  2043     Caused installation of a distribution:
       
  2044     tellmy.version 1.0
       
  2045     with a different version.
       
  2046     Got None.
       
  2047     While:
       
  2048       Installing eggs.
       
  2049     Error: There is a version conflict.
       
  2050     We already have: tellmy.version 1.0
       
  2051     <BLANKLINE>
       
  2052 
       
  2053 You can see the copiously commented fix for this in easy_install.py (see
       
  2054 zc.buildout.easy_install.Installer._call_easy_install and particularly
       
  2055 the comment leading up to zc.buildout.easy_install._easy_install_cmd).
       
  2056 Now the install works correctly, as seen here.
       
  2057 
       
  2058     >>> print system(buildout)
       
  2059     Installing eggs.
       
  2060     Getting distribution for 'tellmy.version==1.1'.
       
  2061     Got tellmy.version 1.1.
       
  2062     <BLANKLINE>
       
  2063 
       
  2064     """
       
  2065 
       
  2066 def isolated_include_site_packages():
       
  2067     """
       
  2068 
       
  2069 This is an isolated test of the include_site_packages functionality, passing
       
  2070 the argument directly to install, overriding a default.
       
  2071 
       
  2072 Our "py_path" has the "demoneeded" and "demo" packages available.  We'll
       
  2073 simply be asking for "demoneeded" here.
       
  2074 
       
  2075     >>> py_path, site_packages_path = make_py()
       
  2076     >>> create_sample_sys_install(site_packages_path)
       
  2077     >>> zc.buildout.easy_install.include_site_packages(False)
       
  2078     True
       
  2079 
       
  2080     >>> example_dest = tmpdir('site-packages-example-install')
       
  2081     >>> workingset = zc.buildout.easy_install.install(
       
  2082     ...     ['demoneeded'], example_dest, links=[], executable=py_path,
       
  2083     ...     index=None, include_site_packages=True)
       
  2084     >>> [dist.project_name for dist in workingset]
       
  2085     ['demoneeded']
       
  2086 
       
  2087 That worked fine.  Let's try again with site packages not allowed (and
       
  2088 reversing the default).
       
  2089 
       
  2090     >>> zc.buildout.easy_install.include_site_packages(True)
       
  2091     False
       
  2092 
       
  2093     >>> zc.buildout.easy_install.clear_index_cache()
       
  2094     >>> rmdir(example_dest)
       
  2095     >>> example_dest = tmpdir('site-packages-example-install')
       
  2096     >>> workingset = zc.buildout.easy_install.install(
       
  2097     ...     ['demoneeded'], example_dest, links=[], executable=py_path,
       
  2098     ...     index=None, include_site_packages=False)
       
  2099     Traceback (most recent call last):
       
  2100         ...
       
  2101     MissingDistribution: Couldn't find a distribution for 'demoneeded'.
       
  2102 
       
  2103 That's a failure, as expected.
       
  2104 
       
  2105 Now we explore an important edge case.
       
  2106 
       
  2107 Some system Pythons include setuptools (and other Python packages) in their
       
  2108 site-packages (or equivalent) using a .egg-info directory.  The pkg_resources
       
  2109 module (from setuptools) considers a package installed using .egg-info to be a
       
  2110 develop egg.
       
  2111 
       
  2112 zc.buildout.buildout.Buildout.bootstrap will make setuptools and zc.buildout
       
  2113 available to the buildout via the eggs directory, for normal eggs; or the
       
  2114 develop-eggs directory, for develop-eggs.
       
  2115 
       
  2116 If setuptools or zc.buildout is found in site-packages and considered by
       
  2117 pkg_resources to be a develop egg, then the bootstrap code will use a .egg-link
       
  2118 in the local develop-eggs, pointing to site-packages, in its entirety.  Because
       
  2119 develop-eggs must always be available for searching for distributions, this
       
  2120 indirectly brings site-packages back into the search path for distributions.
       
  2121 
       
  2122 Because of this, we have to take special care that we still exclude
       
  2123 site-packages even in this case.  See the comments about site packages in the
       
  2124 Installer._satisfied and Installer._obtain methods for the implementation
       
  2125 (as of this writing).
       
  2126 
       
  2127 In this demonstration, we insert a link to the "demoneeded" distribution
       
  2128 in our develop-eggs, which would bring the package back in, except for
       
  2129 the special care we have taken to exclude it.
       
  2130 
       
  2131     >>> zc.buildout.easy_install.clear_index_cache()
       
  2132     >>> rmdir(example_dest)
       
  2133     >>> example_dest = tmpdir('site-packages-example-install')
       
  2134     >>> mkdir(example_dest, 'develop-eggs')
       
  2135     >>> write(example_dest, 'develop-eggs', 'demoneeded.egg-link',
       
  2136     ...       site_packages_path)
       
  2137     >>> workingset = zc.buildout.easy_install.install(
       
  2138     ...     ['demoneeded'], example_dest, links=[],
       
  2139     ...     path=[join(example_dest, 'develop-eggs')],
       
  2140     ...     executable=py_path,
       
  2141     ...     index=None, include_site_packages=False)
       
  2142     Traceback (most recent call last):
       
  2143         ...
       
  2144     MissingDistribution: Couldn't find a distribution for 'demoneeded'.
       
  2145 
       
  2146 The MissingDistribution error shows that buildout correctly excluded the
       
  2147 "site-packages" source even though it was indirectly included in the path
       
  2148 via a .egg-link file.
       
  2149 
       
  2150     """
       
  2151 
       
  2152 def include_site_packages_bug_623590():
       
  2153     """
       
  2154 As mentioned in isolated_include_site_packages, some system Pythons
       
  2155 include various Python packages in their site-packages (or equivalent)
       
  2156 using a .egg-info directory.  The pkg_resources module (from setuptools)
       
  2157 considers a package installed using .egg-info to be a develop egg
       
  2158 
       
  2159 We generally prefer develop eggs when we are selecting dependencies, because
       
  2160 we expect them to be eggs that buildout has been told to develop.  However,
       
  2161 we should not consider these site-packages eggs as develop eggs--they should
       
  2162 not have automatic precedence over eggs available elsewhere.
       
  2163 
       
  2164 We have specific code to handle this case, as identified in bug 623590.
       
  2165 See zc.buildout.easy_install.Installer._satisfied, as of this writing,
       
  2166 for the pertinent code. Here's the test for the bugfix.
       
  2167 
       
  2168     >>> py_path, site_packages_path = make_py()
       
  2169     >>> create_sample_sys_install(site_packages_path)
       
  2170     >>> zc.buildout.easy_install.include_site_packages(False)
       
  2171     True
       
  2172 
       
  2173     >>> example_dest = tmpdir('site-packages-example-install')
       
  2174     >>> workingset = zc.buildout.easy_install.install(
       
  2175     ...     ['demo'], example_dest, links=[sample_eggs], executable=py_path,
       
  2176     ...     index=None, include_site_packages=True, prefer_final=False)
       
  2177     >>> [(dist.project_name, dist.version) for dist in workingset]
       
  2178     [('demo', '0.4c1'), ('demoneeded', '1.2c1')]
       
  2179 """
       
  2180 
       
  2181 def allowed_eggs_from_site_packages():
       
  2182     """
       
  2183 Sometimes you need or want to control what eggs from site-packages are used.
       
  2184 The allowed-eggs-from-site-packages option allows you to specify a whitelist of
       
  2185 project names that may be included from site-packages.  You can use globs to
       
  2186 specify the value.  It defaults to a single value of '*', indicating that any
       
  2187 package may come from site-packages.
       
  2188 
       
  2189 This option interacts with include-site-packages in the following ways.
       
  2190 
       
  2191 If include-site-packages is true, then allowed-eggs-from-site-packages filters
       
  2192 what eggs from site-packages may be chosen.  If allowed-eggs-from-site-packages
       
  2193 is an empty list, then no eggs from site-packages are chosen, but site-packages
       
  2194 will still be included at the end of path lists.
       
  2195 
       
  2196 If include-site-packages is false, allowed-eggs-from-site-packages is
       
  2197 irrelevant.
       
  2198 
       
  2199 This test shows the interaction with the zc.buildout.easy_install API.  Another
       
  2200 test below (allow_site_package_eggs_option) shows using it with a buildout.cfg.
       
  2201 
       
  2202 Our "py_path" has the "demoneeded" and "demo" packages available.  We'll
       
  2203 simply be asking for "demoneeded" here.
       
  2204 
       
  2205     >>> py_path, site_packages_path = make_py()
       
  2206     >>> create_sample_sys_install(site_packages_path)
       
  2207 
       
  2208     >>> example_dest = tmpdir('site-packages-example-install')
       
  2209     >>> workingset = zc.buildout.easy_install.install(
       
  2210     ...     ['demoneeded'], example_dest, links=[], executable=py_path,
       
  2211     ...     index=None,
       
  2212     ...     allowed_eggs_from_site_packages=['demoneeded', 'other'])
       
  2213     >>> [dist.project_name for dist in workingset]
       
  2214     ['demoneeded']
       
  2215 
       
  2216 That worked fine.  It would work fine for a glob too.
       
  2217 
       
  2218     >>> zc.buildout.easy_install.clear_index_cache()
       
  2219     >>> rmdir(example_dest)
       
  2220     >>> example_dest = tmpdir('site-packages-example-install')
       
  2221     >>> workingset = zc.buildout.easy_install.install(
       
  2222     ...     ['demoneeded'], example_dest, links=[], executable=py_path,
       
  2223     ...     index=None,
       
  2224     ...     allowed_eggs_from_site_packages=['?emon*', 'other'])
       
  2225     >>> [dist.project_name for dist in workingset]
       
  2226     ['demoneeded']
       
  2227 
       
  2228 But now let's try again with 'demoneeded' not allowed.
       
  2229 
       
  2230     >>> zc.buildout.easy_install.clear_index_cache()
       
  2231     >>> rmdir(example_dest)
       
  2232     >>> example_dest = tmpdir('site-packages-example-install')
       
  2233     >>> workingset = zc.buildout.easy_install.install(
       
  2234     ...     ['demoneeded'], example_dest, links=[], executable=py_path,
       
  2235     ...     index=None,
       
  2236     ...     allowed_eggs_from_site_packages=['demo'])
       
  2237     Traceback (most recent call last):
       
  2238         ...
       
  2239     MissingDistribution: Couldn't find a distribution for 'demoneeded'.
       
  2240 
       
  2241 Here's the same, but with an empty list.
       
  2242 
       
  2243     >>> zc.buildout.easy_install.clear_index_cache()
       
  2244     >>> rmdir(example_dest)
       
  2245     >>> example_dest = tmpdir('site-packages-example-install')
       
  2246     >>> workingset = zc.buildout.easy_install.install(
       
  2247     ...     ['demoneeded'], example_dest, links=[], executable=py_path,
       
  2248     ...     index=None,
       
  2249     ...     allowed_eggs_from_site_packages=[])
       
  2250     Traceback (most recent call last):
       
  2251         ...
       
  2252     MissingDistribution: Couldn't find a distribution for 'demoneeded'.
       
  2253 
       
  2254 Of course, this doesn't stop us from getting a package from elsewhere.  Here,
       
  2255 we add a link server.
       
  2256 
       
  2257     >>> zc.buildout.easy_install.clear_index_cache()
       
  2258     >>> rmdir(example_dest)
       
  2259     >>> example_dest = tmpdir('site-packages-example-install')
       
  2260     >>> workingset = zc.buildout.easy_install.install(
       
  2261     ...     ['demoneeded'], example_dest, executable=py_path,
       
  2262     ...     links=[link_server], index=link_server+'index/',
       
  2263     ...     allowed_eggs_from_site_packages=['other'])
       
  2264     >>> [dist.project_name for dist in workingset]
       
  2265     ['demoneeded']
       
  2266     >>> [dist.location for dist in workingset]
       
  2267     ['/site-packages-example-install/demoneeded-1.1-py2.6.egg']
       
  2268 
       
  2269 Finally, here's an example of an interaction: we say that it is OK to
       
  2270 allow the "demoneeded" egg to come from site-packages, but we don't
       
  2271 include-site-packages.
       
  2272 
       
  2273     >>> zc.buildout.easy_install.clear_index_cache()
       
  2274     >>> rmdir(example_dest)
       
  2275     >>> example_dest = tmpdir('site-packages-example-install')
       
  2276     >>> workingset = zc.buildout.easy_install.install(
       
  2277     ...     ['demoneeded'], example_dest, links=[], executable=py_path,
       
  2278     ...     index=None, include_site_packages=False,
       
  2279     ...     allowed_eggs_from_site_packages=['demoneeded'])
       
  2280     Traceback (most recent call last):
       
  2281         ...
       
  2282     MissingDistribution: Couldn't find a distribution for 'demoneeded'.
       
  2283 
       
  2284     """
       
  2285 
       
  2286 def allowed_eggs_from_site_packages_dependencies_bugfix():
       
  2287     """
       
  2288 If you specify that a package with a dependency may come from site-packages,
       
  2289 that doesn't mean that the dependency may come from site-packages.  This
       
  2290 is a test for a bug fix to verify that this is true.
       
  2291 
       
  2292     >>> py_path, site_packages_path = make_py()
       
  2293     >>> create_sample_sys_install(site_packages_path)
       
  2294     >>> interpreter_dir = tmpdir('interpreter')
       
  2295     >>> interpreter_parts_dir = os.path.join(
       
  2296     ...     interpreter_dir, 'parts', 'interpreter')
       
  2297     >>> interpreter_bin_dir = os.path.join(interpreter_dir, 'bin')
       
  2298     >>> mkdir(interpreter_bin_dir)
       
  2299     >>> mkdir(interpreter_dir, 'eggs')
       
  2300     >>> mkdir(interpreter_dir, 'parts')
       
  2301     >>> mkdir(interpreter_parts_dir)
       
  2302     >>> ws = zc.buildout.easy_install.install(
       
  2303     ...     ['demo'], join(interpreter_dir, 'eggs'), executable=py_path,
       
  2304     ...     links=[link_server], index=link_server+'index/',
       
  2305     ...     allowed_eggs_from_site_packages=['demo'])
       
  2306     >>> [dist.project_name for dist in ws]
       
  2307     ['demo', 'demoneeded']
       
  2308     >>> from pprint import pprint
       
  2309     >>> pprint([dist.location for dist in ws])
       
  2310     ['/executable_buildout/site-packages',
       
  2311      '/interpreter/eggs/demoneeded-1.1-pyN.N.egg']
       
  2312 
       
  2313     """
       
  2314 
       
  2315 def allowed_eggs_from_site_packages_bug_592524():
       
  2316     """
       
  2317 When we use allowed_eggs_from_site_packages, we need to make sure that the
       
  2318 site-packages paths are not inserted with the normal egg paths.  They already
       
  2319 included at the end, and including them along with the normal egg paths will
       
  2320 possibly mask subsequent egg paths.  This affects interpreters and scripts
       
  2321 generated by sitepackage_safe_scripts.
       
  2322 
       
  2323 Our "py_path" has the "demoneeded" and "demo" packages available.
       
  2324 
       
  2325     >>> py_path, site_packages_path = make_py()
       
  2326     >>> create_sample_sys_install(site_packages_path)
       
  2327     >>> interpreter_dir = tmpdir('interpreter')
       
  2328     >>> interpreter_parts_dir = os.path.join(
       
  2329     ...     interpreter_dir, 'parts', 'interpreter')
       
  2330     >>> interpreter_bin_dir = os.path.join(interpreter_dir, 'bin')
       
  2331     >>> mkdir(interpreter_bin_dir)
       
  2332     >>> mkdir(interpreter_dir, 'eggs')
       
  2333     >>> mkdir(interpreter_dir, 'parts')
       
  2334     >>> mkdir(interpreter_parts_dir)
       
  2335     >>> ws = zc.buildout.easy_install.install(
       
  2336     ...     ['demo', 'other'], join(interpreter_dir, 'eggs'), executable=py_path,
       
  2337     ...     links=[link_server], index=link_server+'index/',
       
  2338     ...     allowed_eggs_from_site_packages=['demo'])
       
  2339     >>> generated = zc.buildout.easy_install.sitepackage_safe_scripts(
       
  2340     ...     interpreter_bin_dir, ws, py_path, interpreter_parts_dir,
       
  2341     ...     interpreter='py', include_site_packages=True)
       
  2342 
       
  2343 Now we will look at the paths in the site.py we generated.  Notice that the
       
  2344 site-packages are at the end.  They were not before this bugfix.
       
  2345 
       
  2346     >>> test = 'import pprint, sys; pprint.pprint(sys.path[-4:])'
       
  2347     >>> print call_py(join(interpreter_bin_dir, 'py'), test)
       
  2348     ['/interpreter/eggs/other-1.0-pyN.N.egg',
       
  2349      '/interpreter/eggs/demoneeded-1.1-pyN.N.egg',
       
  2350      '/executable_buildout/eggs/setuptools-0.0-pyN.N.egg',
       
  2351      '/executable_buildout/site-packages']
       
  2352     <BLANKLINE>
       
  2353     """
       
  2354 
       
  2355 def subprocesses_have_same_environment_by_default():
       
  2356     """
       
  2357 The scripts generated by sitepackage_safe_scripts set the PYTHONPATH so that,
       
  2358 if the environment is maintained (the default behavior), subprocesses get
       
  2359 the same Python packages.
       
  2360 
       
  2361 First, we set up a script and an interpreter.
       
  2362 
       
  2363     >>> interpreter_dir = tmpdir('interpreter')
       
  2364     >>> interpreter_parts_dir = os.path.join(
       
  2365     ...     interpreter_dir, 'parts', 'interpreter')
       
  2366     >>> interpreter_bin_dir = os.path.join(interpreter_dir, 'bin')
       
  2367     >>> mkdir(interpreter_bin_dir)
       
  2368     >>> mkdir(interpreter_dir, 'eggs')
       
  2369     >>> mkdir(interpreter_dir, 'parts')
       
  2370     >>> mkdir(interpreter_parts_dir)
       
  2371     >>> ws = zc.buildout.easy_install.install(
       
  2372     ...     ['demo'], join(interpreter_dir, 'eggs'), links=[link_server],
       
  2373     ...     index=link_server+'index/')
       
  2374     >>> test = (
       
  2375     ...     "import subprocess, sys; subprocess.call("
       
  2376     ...     "[sys.executable, '-c', "
       
  2377     ...     "'import eggrecipedemo; print eggrecipedemo.x'])")
       
  2378     >>> generated = zc.buildout.easy_install.sitepackage_safe_scripts(
       
  2379     ...     interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir,
       
  2380     ...     reqs=['demo'], interpreter='py',
       
  2381     ...     script_initialization=test + '; sys.exit(0)')
       
  2382 
       
  2383 This works for the script.
       
  2384 
       
  2385     >>> print system(join(interpreter_bin_dir, 'demo'))
       
  2386     3
       
  2387     <BLANKLINE>
       
  2388 
       
  2389 This also works for the generated interpreter.
       
  2390 
       
  2391     >>> print call_py(join(interpreter_bin_dir, 'py'), test)
       
  2392     3
       
  2393     <BLANKLINE>
       
  2394 
       
  2395 If you have a PYTHONPATH in your environment, it will be honored, after
       
  2396 the buildout-generated path.
       
  2397 
       
  2398     >>> original_pythonpath = os.environ.get('PYTHONPATH')
       
  2399     >>> os.environ['PYTHONPATH'] = 'foo'
       
  2400     >>> test = (
       
  2401     ...     "import subprocess, sys; subprocess.call("
       
  2402     ...     "[sys.executable, '-c', "
       
  2403     ...     "'import sys, pprint; pprint.pprint(sys.path)'])")
       
  2404     >>> generated = zc.buildout.easy_install.sitepackage_safe_scripts(
       
  2405     ...     interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir,
       
  2406     ...     reqs=['demo'], interpreter='py',
       
  2407     ...     script_initialization=test + '; sys.exit(0)')
       
  2408 
       
  2409 This works for the script.  As you can see, /sample_buildout/foo is included
       
  2410 right after the "parts" directory that contains site.py and sitecustomize.py.
       
  2411 You can also see, actually more easily than in the other example, that we
       
  2412 have the desired eggs available.
       
  2413 
       
  2414     >>> print system(join(interpreter_bin_dir, 'demo')), # doctest: +ELLIPSIS
       
  2415     ['',
       
  2416      '/interpreter/parts/interpreter',
       
  2417      '/sample-buildout/foo',
       
  2418      ...
       
  2419      '/interpreter/eggs/demo-0.3-pyN.N.egg',
       
  2420      '/interpreter/eggs/demoneeded-1.1-pyN.N.egg']
       
  2421 
       
  2422 This also works for the generated interpreter, with identical results.
       
  2423 
       
  2424     >>> print call_py(join(interpreter_bin_dir, 'py'), test),
       
  2425     ... # doctest: +ELLIPSIS
       
  2426     ['',
       
  2427      '/interpreter/parts/interpreter',
       
  2428      '/sample-buildout/foo',
       
  2429      ...
       
  2430      '/interpreter/eggs/demo-0.3-pyN.N.egg',
       
  2431      '/interpreter/eggs/demoneeded-1.1-pyN.N.egg']
       
  2432 
       
  2433     >>> # Cleanup
       
  2434     >>> if original_pythonpath:
       
  2435     ...     os.environ['PYTHONPATH'] = original_pythonpath
       
  2436     ... else:
       
  2437     ...     del os.environ['PYTHONPATH']
       
  2438     ...
       
  2439 
       
  2440     """
       
  2441 
       
  2442 def bootstrap_makes_buildout_that_works_with_system_python():
       
  2443     r"""
       
  2444 In order to work smoothly with a system Python, bootstrapping creates
       
  2445 the buildout script with
       
  2446 zc.buildout.easy_install.sitepackage_safe_scripts. If it did not, a
       
  2447 variety of problems might happen.  For instance, if another version of
       
  2448 buildout or setuptools is installed in the site-packages than is
       
  2449 desired, it may cause a problem.
       
  2450 
       
  2451 A problem actually experienced in the field is when
       
  2452 a recipe wants a different version of a dependency that is installed in
       
  2453 site-packages.  We will create a similar situation, and show that it is now
       
  2454 handled.
       
  2455 
       
  2456 First let's write a dummy recipe.
       
  2457 
       
  2458     >>> mkdir(sample_buildout, 'recipes')
       
  2459     >>> write(sample_buildout, 'recipes', 'dummy.py',
       
  2460     ... '''
       
  2461     ... import logging, os, zc.buildout
       
  2462     ... class Dummy:
       
  2463     ...     def __init__(self, buildout, name, options):
       
  2464     ...         pass
       
  2465     ...     def install(self):
       
  2466     ...         return ()
       
  2467     ...     def update(self):
       
  2468     ...         pass
       
  2469     ... ''')
       
  2470     >>> write(sample_buildout, 'recipes', 'setup.py',
       
  2471     ... '''
       
  2472     ... from setuptools import setup
       
  2473     ...
       
  2474     ... setup(
       
  2475     ...     name = "recipes",
       
  2476     ...     entry_points = {'zc.buildout': ['dummy = dummy:Dummy']},
       
  2477     ...     install_requires = 'demoneeded==1.2c1',
       
  2478     ...     )
       
  2479     ... ''')
       
  2480     >>> write(sample_buildout, 'recipes', 'README.txt', " ")
       
  2481 
       
  2482 Now we'll try to use it with a Python that has a different version of
       
  2483 demoneeded installed.
       
  2484 
       
  2485     >>> py_path, site_packages_path = make_py()
       
  2486     >>> create_sample_sys_install(site_packages_path)
       
  2487     >>> rmdir('develop-eggs')
       
  2488     >>> from zc.buildout.testing import make_buildout
       
  2489     >>> make_buildout(executable=py_path)
       
  2490     >>> write(sample_buildout, 'buildout.cfg',
       
  2491     ... '''
       
  2492     ... [buildout]
       
  2493     ... develop = recipes
       
  2494     ... parts = dummy
       
  2495     ... find-links = %(link_server)s
       
  2496     ... executable = %(py_path)s
       
  2497     ...
       
  2498     ... [dummy]
       
  2499     ... recipe = recipes:dummy
       
  2500     ... ''' % globals())
       
  2501 
       
  2502 Now we actually run the buildout.  Before the change, we got the following
       
  2503 error:
       
  2504 
       
  2505     Develop: '/sample-buildout/recipes'
       
  2506     While:
       
  2507       Installing.
       
  2508       Getting section dummy.
       
  2509       Initializing section dummy.
       
  2510       Installing recipe recipes.
       
  2511     Error: There is a version conflict.
       
  2512     We already have: demoneeded 1.1
       
  2513     but recipes 0.0.0 requires 'demoneeded==1.2c1'.
       
  2514 
       
  2515 Now, it is handled smoothly.
       
  2516 
       
  2517     >>> print system(buildout)
       
  2518     Develop: '/sample-buildout/recipes'
       
  2519     Getting distribution for 'demoneeded==1.2c1'.
       
  2520     Got demoneeded 1.2c1.
       
  2521     Installing dummy.
       
  2522     <BLANKLINE>
       
  2523 
       
  2524 Here's the same story with a namespace package, which has some additional
       
  2525 complications behind the scenes.  First, a recipe, in the "tellmy" namespace.
       
  2526 
       
  2527     >>> mkdir(sample_buildout, 'ns')
       
  2528     >>> mkdir(sample_buildout, 'ns', 'tellmy')
       
  2529     >>> write(sample_buildout, 'ns', 'tellmy', '__init__.py',
       
  2530     ...       "__import__('pkg_resources').declare_namespace(__name__)\n")
       
  2531     >>> mkdir(sample_buildout, 'ns', 'tellmy', 'recipes')
       
  2532     >>> write(sample_buildout, 'ns', 'tellmy', 'recipes', '__init__.py', ' ')
       
  2533     >>> write(sample_buildout, 'ns', 'tellmy', 'recipes', 'dummy.py',
       
  2534     ... '''
       
  2535     ... import logging, os, zc.buildout
       
  2536     ... class Dummy:
       
  2537     ...     def __init__(self, buildout, name, options):
       
  2538     ...         pass
       
  2539     ...     def install(self):
       
  2540     ...         return ()
       
  2541     ...     def update(self):
       
  2542     ...         pass
       
  2543     ... ''')
       
  2544     >>> write(sample_buildout, 'ns', 'setup.py',
       
  2545     ... '''
       
  2546     ... from setuptools import setup
       
  2547     ... setup(
       
  2548     ...     name="tellmy.recipes",
       
  2549     ...     packages=['tellmy', 'tellmy.recipes'],
       
  2550     ...     install_requires=['setuptools'],
       
  2551     ...     namespace_packages=['tellmy'],
       
  2552     ...     entry_points = {'zc.buildout':
       
  2553     ...                     ['dummy = tellmy.recipes.dummy:Dummy']},
       
  2554     ...     )
       
  2555     ... ''')
       
  2556 
       
  2557 Now, a buildout that uses it.
       
  2558 
       
  2559     >>> create_sample_namespace_eggs(sample_eggs, site_packages_path)
       
  2560     >>> rmdir('develop-eggs')
       
  2561     >>> from zc.buildout.testing import make_buildout
       
  2562     >>> make_buildout(executable=py_path)
       
  2563     >>> write(sample_buildout, 'buildout.cfg',
       
  2564     ... '''
       
  2565     ... [buildout]
       
  2566     ... develop = ns
       
  2567     ...           recipes
       
  2568     ... parts = dummy
       
  2569     ... find-links = %(link_server)s
       
  2570     ... executable = %(py_path)s
       
  2571     ...
       
  2572     ... [dummy]
       
  2573     ... recipe = tellmy.recipes:dummy
       
  2574     ... ''' % globals())
       
  2575 
       
  2576 Now we actually run the buildout.
       
  2577 
       
  2578     >>> print system(buildout)
       
  2579     Develop: '/sample-buildout/ns'
       
  2580     Develop: '/sample-buildout/recipes'
       
  2581     Uninstalling dummy.
       
  2582     Installing dummy.
       
  2583     <BLANKLINE>
       
  2584 
       
  2585     """
       
  2586 
       
  2587 if sys.version_info > (2, 4):
       
  2588     def test_exit_codes():
       
  2589         """
       
  2590         >>> import subprocess
       
  2591         >>> def call(s):
       
  2592         ...     p = subprocess.Popen(s, stdin=subprocess.PIPE,
       
  2593         ...                 stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
       
  2594         ...     p.stdin.close()
       
  2595         ...     print p.stdout.read()
       
  2596         ...     print 'Exit:', bool(p.wait())
       
  2597 
       
  2598         >>> call(buildout)
       
  2599         <BLANKLINE>
       
  2600         Exit: False
       
  2601 
       
  2602         >>> write('buildout.cfg',
       
  2603         ... '''
       
  2604         ... [buildout]
       
  2605         ... parts = x
       
  2606         ... ''')
       
  2607 
       
  2608         >>> call(buildout) # doctest: +NORMALIZE_WHITESPACE
       
  2609         While:
       
  2610           Installing.
       
  2611           Getting section x.
       
  2612         Error: The referenced section, 'x', was not defined.
       
  2613         <BLANKLINE>
       
  2614         Exit: True
       
  2615 
       
  2616         >>> write('setup.py',
       
  2617         ... '''
       
  2618         ... from setuptools import setup
       
  2619         ... setup(name='zc.buildout.testexit', entry_points={
       
  2620         ...    'zc.buildout': ['default = testexitrecipe:x']})
       
  2621         ... ''')
       
  2622 
       
  2623         >>> write('testexitrecipe.py',
       
  2624         ... '''
       
  2625         ... x y
       
  2626         ... ''')
       
  2627 
       
  2628         >>> write('buildout.cfg',
       
  2629         ... '''
       
  2630         ... [buildout]
       
  2631         ... parts = x
       
  2632         ... develop = .
       
  2633         ...
       
  2634         ... [x]
       
  2635         ... recipe = zc.buildout.testexit
       
  2636         ... ''')
       
  2637 
       
  2638         >>> call(buildout) # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
       
  2639         Develop: '/sample-buildout/.'
       
  2640         While:
       
  2641           Installing.
       
  2642           Getting section x.
       
  2643           Initializing section x.
       
  2644           Loading zc.buildout recipe entry zc.buildout.testexit:default.
       
  2645         <BLANKLINE>
       
  2646         An internal error occurred due to a bug in either zc.buildout or in a
       
  2647         recipe being used:
       
  2648         Traceback (most recent call last):
       
  2649         ...
       
  2650              x y
       
  2651                ^
       
  2652          SyntaxError: invalid syntax
       
  2653         <BLANKLINE>
       
  2654         Exit: True
       
  2655         """
       
  2656 
       
  2657 def bug_59270_recipes_always_start_in_buildout_dir():
       
  2658     """
       
  2659     Recipes can rely on running from buildout directory
       
  2660 
       
  2661     >>> mkdir('bad_start')
       
  2662     >>> write('bad_recipe.py',
       
  2663     ... '''
       
  2664     ... import os
       
  2665     ... class Bad:
       
  2666     ...     def __init__(self, *_):
       
  2667     ...         print os.getcwd()
       
  2668     ...     def install(self):
       
  2669     ...         print os.getcwd()
       
  2670     ...         os.chdir('bad_start')
       
  2671     ...         print os.getcwd()
       
  2672     ...         return ()
       
  2673     ... ''')
       
  2674 
       
  2675     >>> write('setup.py',
       
  2676     ... '''
       
  2677     ... from setuptools import setup
       
  2678     ... setup(name='bad.test',
       
  2679     ...       entry_points={'zc.buildout': ['default=bad_recipe:Bad']},)
       
  2680     ... ''')
       
  2681 
       
  2682     >>> write('buildout.cfg',
       
  2683     ... '''
       
  2684     ... [buildout]
       
  2685     ... develop = .
       
  2686     ... parts = b1 b2
       
  2687     ... [b1]
       
  2688     ... recipe = bad.test
       
  2689     ... [b2]
       
  2690     ... recipe = bad.test
       
  2691     ... ''')
       
  2692 
       
  2693     >>> os.chdir('bad_start')
       
  2694     >>> print system(join(sample_buildout, 'bin', 'buildout')
       
  2695     ...              +' -c '+join(sample_buildout, 'buildout.cfg')),
       
  2696     Develop: '/sample-buildout/.'
       
  2697     /sample-buildout
       
  2698     /sample-buildout
       
  2699     Installing b1.
       
  2700     /sample-buildout
       
  2701     /sample-buildout/bad_start
       
  2702     Installing b2.
       
  2703     /sample-buildout
       
  2704     /sample-buildout/bad_start
       
  2705 
       
  2706     """
       
  2707 
       
  2708 def bug_61890_file_urls_dont_seem_to_work_in_find_dash_links():
       
  2709     """
       
  2710 
       
  2711     This bug arises from the fact that setuptools is overly restrictive
       
  2712     about file urls, requiring that file urls pointing at directories
       
  2713     must end in a slash.
       
  2714 
       
  2715     >>> dest = tmpdir('sample-install')
       
  2716     >>> import zc.buildout.easy_install
       
  2717     >>> sample_eggs = sample_eggs.replace(os.path.sep, '/')
       
  2718     >>> ws = zc.buildout.easy_install.install(
       
  2719     ...     ['demo==0.2'], dest,
       
  2720     ...     links=['file://'+sample_eggs], index=link_server+'index/')
       
  2721 
       
  2722 
       
  2723     >>> for dist in ws:
       
  2724     ...     print dist
       
  2725     demo 0.2
       
  2726     demoneeded 1.1
       
  2727 
       
  2728     >>> ls(dest)
       
  2729     -  demo-0.2-py2.4.egg
       
  2730     -  demoneeded-1.1-py2.4.egg
       
  2731 
       
  2732     """
       
  2733 
       
  2734 def bug_75607_buildout_should_not_run_if_it_creates_an_empty_buildout_cfg():
       
  2735     """
       
  2736     >>> remove('buildout.cfg')
       
  2737     >>> print system(buildout),
       
  2738     While:
       
  2739       Initializing.
       
  2740     Error: Couldn't open /sample-buildout/buildout.cfg
       
  2741 
       
  2742 
       
  2743 
       
  2744     """
       
  2745 
       
  2746 def dealing_with_extremely_insane_dependencies():
       
  2747     r"""
       
  2748 
       
  2749     There was a problem with analysis of dependencies taking a long
       
  2750     time, in part because the analysis would get repeated every time a
       
  2751     package was encountered in a dependency list.  Now, we don't do
       
  2752     the analysis any more:
       
  2753 
       
  2754     >>> import os
       
  2755     >>> for i in range(5):
       
  2756     ...     p = 'pack%s' % i
       
  2757     ...     deps = [('pack%s' % j) for j in range(5) if j is not i]
       
  2758     ...     if i == 4:
       
  2759     ...         deps.append('pack5')
       
  2760     ...     mkdir(p)
       
  2761     ...     write(p, 'setup.py',
       
  2762     ...           'from setuptools import setup\n'
       
  2763     ...           'setup(name=%r, install_requires=%r,\n'
       
  2764     ...           '      url="u", author="a", author_email="e")\n'
       
  2765     ...           % (p, deps))
       
  2766 
       
  2767     >>> write('buildout.cfg',
       
  2768     ... '''
       
  2769     ... [buildout]
       
  2770     ... develop = pack0 pack1 pack2 pack3 pack4
       
  2771     ... parts = pack1
       
  2772     ...
       
  2773     ... [pack1]
       
  2774     ... recipe = zc.recipe.egg:eggs
       
  2775     ... eggs = pack0
       
  2776     ... ''')
       
  2777 
       
  2778     >>> print system(buildout),
       
  2779     Develop: '/sample-buildout/pack0'
       
  2780     Develop: '/sample-buildout/pack1'
       
  2781     Develop: '/sample-buildout/pack2'
       
  2782     Develop: '/sample-buildout/pack3'
       
  2783     Develop: '/sample-buildout/pack4'
       
  2784     Installing pack1.
       
  2785     Couldn't find index page for 'pack5' (maybe misspelled?)
       
  2786     Getting distribution for 'pack5'.
       
  2787     While:
       
  2788       Installing pack1.
       
  2789       Getting distribution for 'pack5'.
       
  2790     Error: Couldn't find a distribution for 'pack5'.
       
  2791 
       
  2792     However, if we run in verbose mode, we can see why packages were included:
       
  2793 
       
  2794     >>> print system(buildout+' -v'), # doctest: +ELLIPSIS
       
  2795     Installing 'zc.buildout', 'setuptools'.
       
  2796     We have a develop egg: zc.buildout 1.0.0
       
  2797     We have the best distribution that satisfies 'setuptools'.
       
  2798     Picked: setuptools = 0.6
       
  2799     Develop: '/sample-buildout/pack0'
       
  2800     Develop: '/sample-buildout/pack1'
       
  2801     Develop: '/sample-buildout/pack2'
       
  2802     Develop: '/sample-buildout/pack3'
       
  2803     Develop: '/sample-buildout/pack4'
       
  2804     ...Installing pack1.
       
  2805     Installing 'pack0'.
       
  2806     We have a develop egg: pack0 0.0.0
       
  2807     Getting required 'pack4'
       
  2808       required by pack0 0.0.0.
       
  2809     We have a develop egg: pack4 0.0.0
       
  2810     Getting required 'pack3'
       
  2811       required by pack0 0.0.0.
       
  2812       required by pack4 0.0.0.
       
  2813     We have a develop egg: pack3 0.0.0
       
  2814     Getting required 'pack2'
       
  2815       required by pack0 0.0.0.
       
  2816       required by pack3 0.0.0.
       
  2817       required by pack4 0.0.0.
       
  2818     We have a develop egg: pack2 0.0.0
       
  2819     Getting required 'pack1'
       
  2820       required by pack0 0.0.0.
       
  2821       required by pack2 0.0.0.
       
  2822       required by pack3 0.0.0.
       
  2823       required by pack4 0.0.0.
       
  2824     We have a develop egg: pack1 0.0.0
       
  2825     Getting required 'pack5'
       
  2826       required by pack4 0.0.0.
       
  2827     We have no distributions for pack5 that satisfies 'pack5'.
       
  2828     Couldn't find index page for 'pack5' (maybe misspelled?)
       
  2829     Getting distribution for 'pack5'.
       
  2830     While:
       
  2831       Installing pack1.
       
  2832       Getting distribution for 'pack5'.
       
  2833     Error: Couldn't find a distribution for 'pack5'.
       
  2834     """
       
  2835 
       
  2836 def read_find_links_to_load_extensions():
       
  2837     """
       
  2838 We'll create a wacky buildout extension that is just another name for http:
       
  2839 
       
  2840     >>> src = tmpdir('src')
       
  2841     >>> write(src, 'wacky_handler.py',
       
  2842     ... '''
       
  2843     ... import urllib2
       
  2844     ... class Wacky(urllib2.HTTPHandler):
       
  2845     ...     wacky_open = urllib2.HTTPHandler.http_open
       
  2846     ... def install(buildout=None):
       
  2847     ...     urllib2.install_opener(urllib2.build_opener(Wacky))
       
  2848     ... ''')
       
  2849     >>> write(src, 'setup.py',
       
  2850     ... '''
       
  2851     ... from setuptools import setup
       
  2852     ... setup(name='wackyextension', version='1',
       
  2853     ...       py_modules=['wacky_handler'],
       
  2854     ...       entry_points = {'zc.buildout.extension':
       
  2855     ...             ['default = wacky_handler:install']
       
  2856     ...             },
       
  2857     ...       )
       
  2858     ... ''')
       
  2859     >>> print system(buildout+' setup '+src+' bdist_egg'),
       
  2860     ... # doctest: +ELLIPSIS
       
  2861     Running setup ...
       
  2862     creating 'dist/wackyextension-1-...
       
  2863 
       
  2864 Now we'll create a buildout that uses this extension to load other packages:
       
  2865 
       
  2866     >>> wacky_server = link_server.replace('http', 'wacky')
       
  2867     >>> dist = 'file://' + join(src, 'dist').replace(os.path.sep, '/')
       
  2868     >>> write('buildout.cfg',
       
  2869     ... '''
       
  2870     ... [buildout]
       
  2871     ... parts = demo
       
  2872     ... extensions = wackyextension
       
  2873     ... find-links = %(wacky_server)s/demoneeded-1.0.zip
       
  2874     ...              %(dist)s
       
  2875     ... [demo]
       
  2876     ... recipe = zc.recipe.egg
       
  2877     ... eggs = demoneeded
       
  2878     ... ''' % globals())
       
  2879 
       
  2880 When we run the buildout. it will load the extension from the dist
       
  2881 directory and then use the wacky extension to load the demo package
       
  2882 
       
  2883     >>> print system(buildout),
       
  2884     Getting distribution for 'wackyextension'.
       
  2885     Got wackyextension 1.
       
  2886     Installing demo.
       
  2887     Getting distribution for 'demoneeded'.
       
  2888     Got demoneeded 1.0.
       
  2889 
       
  2890     """
       
  2891 
       
  2892 def distributions_from_local_find_links_make_it_to_download_cache():
       
  2893     """
       
  2894 
       
  2895 If we specify a local directory in find links, distors found there
       
  2896 need to make it to the download cache.
       
  2897 
       
  2898     >>> mkdir('test')
       
  2899     >>> write('test', 'setup.py',
       
  2900     ... '''
       
  2901     ... from setuptools import setup
       
  2902     ... setup(name='foo')
       
  2903     ... ''')
       
  2904 
       
  2905     >>> print system(buildout+' setup test bdist_egg'), # doctest: +ELLIPSIS
       
  2906     Running setup script 'test/setup.py'.
       
  2907     ...
       
  2908 
       
  2909 
       
  2910     >>> mkdir('cache')
       
  2911     >>> old_cache = zc.buildout.easy_install.download_cache('cache')
       
  2912     >>> list(zc.buildout.easy_install.install(['foo'], 'eggs',
       
  2913     ...          links=[join('test', 'dist')])) # doctest: +ELLIPSIS
       
  2914     [foo 0.0.0 ...
       
  2915 
       
  2916     >>> ls('cache')
       
  2917     -  foo-0.0.0-py2.4.egg
       
  2918 
       
  2919     >>> _ = zc.buildout.easy_install.download_cache(old_cache)
       
  2920 
       
  2921     """
       
  2922 
       
  2923 def create_egg(name, version, dest, install_requires=None,
       
  2924                dependency_links=None):
       
  2925     d = tempfile.mkdtemp()
       
  2926     if dest=='available':
       
  2927         extras = dict(x=['x'])
       
  2928     else:
       
  2929         extras = {}
       
  2930     if dependency_links:
       
  2931         links = 'dependency_links = %s, ' % dependency_links
       
  2932     else:
       
  2933         links = ''
       
  2934     if install_requires:
       
  2935         requires = 'install_requires = %s, ' % install_requires
       
  2936     else:
       
  2937         requires = ''
       
  2938     try:
       
  2939         open(os.path.join(d, 'setup.py'), 'w').write(
       
  2940             'from setuptools import setup\n'
       
  2941             'setup(name=%r, version=%r, extras_require=%r, zip_safe=True,\n'
       
  2942             '      %s %s py_modules=["setup"]\n)'
       
  2943             % (name, str(version), extras, requires, links)
       
  2944             )
       
  2945         zc.buildout.testing.bdist_egg(d, sys.executable, os.path.abspath(dest))
       
  2946     finally:
       
  2947         shutil.rmtree(d)
       
  2948 
       
  2949 def prefer_final_permutation(existing, available):
       
  2950     for d in ('existing', 'available'):
       
  2951         if os.path.exists(d):
       
  2952             shutil.rmtree(d)
       
  2953         os.mkdir(d)
       
  2954     for version in existing:
       
  2955         create_egg('spam', version, 'existing')
       
  2956     for version in available:
       
  2957         create_egg('spam', version, 'available')
       
  2958 
       
  2959     zc.buildout.easy_install.clear_index_cache()
       
  2960     [dist] = list(
       
  2961         zc.buildout.easy_install.install(['spam'], 'existing', ['available'],
       
  2962                                          always_unzip=True)
       
  2963         )
       
  2964 
       
  2965     if dist.extras:
       
  2966         print 'downloaded', dist.version
       
  2967     else:
       
  2968         print 'had', dist.version
       
  2969     sys.path_importer_cache.clear()
       
  2970 
       
  2971 def prefer_final():
       
  2972     """
       
  2973 This test tests several permutations:
       
  2974 
       
  2975 Using different version numbers to work around zip importer cache problems. :(
       
  2976 
       
  2977 - With prefer final:
       
  2978 
       
  2979     - no existing and newer dev available
       
  2980     >>> prefer_final_permutation((), [1, '2a1'])
       
  2981     downloaded 1
       
  2982 
       
  2983     - no existing and only dev available
       
  2984     >>> prefer_final_permutation((), ['3a1'])
       
  2985     downloaded 3a1
       
  2986 
       
  2987     - final existing and only dev acailable
       
  2988     >>> prefer_final_permutation([4], ['5a1'])
       
  2989     had 4
       
  2990 
       
  2991     - final existing and newer final available
       
  2992     >>> prefer_final_permutation([6], [7])
       
  2993     downloaded 7
       
  2994 
       
  2995     - final existing and same final available
       
  2996     >>> prefer_final_permutation([8], [8])
       
  2997     had 8
       
  2998 
       
  2999     - final existing and older final available
       
  3000     >>> prefer_final_permutation([10], [9])
       
  3001     had 10
       
  3002 
       
  3003     - only dev existing and final available
       
  3004     >>> prefer_final_permutation(['12a1'], [11])
       
  3005     downloaded 11
       
  3006 
       
  3007     - only dev existing and no final available newer dev available
       
  3008     >>> prefer_final_permutation(['13a1'], ['13a2'])
       
  3009     downloaded 13a2
       
  3010 
       
  3011     - only dev existing and no final available older dev available
       
  3012     >>> prefer_final_permutation(['15a1'], ['14a1'])
       
  3013     had 15a1
       
  3014 
       
  3015     - only dev existing and no final available same dev available
       
  3016     >>> prefer_final_permutation(['16a1'], ['16a1'])
       
  3017     had 16a1
       
  3018 
       
  3019 - Without prefer final:
       
  3020 
       
  3021     >>> _ = zc.buildout.easy_install.prefer_final(False)
       
  3022 
       
  3023     - no existing and newer dev available
       
  3024     >>> prefer_final_permutation((), [18, '19a1'])
       
  3025     downloaded 19a1
       
  3026 
       
  3027     - no existing and only dev available
       
  3028     >>> prefer_final_permutation((), ['20a1'])
       
  3029     downloaded 20a1
       
  3030 
       
  3031     - final existing and only dev acailable
       
  3032     >>> prefer_final_permutation([21], ['22a1'])
       
  3033     downloaded 22a1
       
  3034 
       
  3035     - final existing and newer final available
       
  3036     >>> prefer_final_permutation([23], [24])
       
  3037     downloaded 24
       
  3038 
       
  3039     - final existing and same final available
       
  3040     >>> prefer_final_permutation([25], [25])
       
  3041     had 25
       
  3042 
       
  3043     - final existing and older final available
       
  3044     >>> prefer_final_permutation([27], [26])
       
  3045     had 27
       
  3046 
       
  3047     - only dev existing and final available
       
  3048     >>> prefer_final_permutation(['29a1'], [28])
       
  3049     had 29a1
       
  3050 
       
  3051     - only dev existing and no final available newer dev available
       
  3052     >>> prefer_final_permutation(['30a1'], ['30a2'])
       
  3053     downloaded 30a2
       
  3054 
       
  3055     - only dev existing and no final available older dev available
       
  3056     >>> prefer_final_permutation(['32a1'], ['31a1'])
       
  3057     had 32a1
       
  3058 
       
  3059     - only dev existing and no final available same dev available
       
  3060     >>> prefer_final_permutation(['33a1'], ['33a1'])
       
  3061     had 33a1
       
  3062 
       
  3063     >>> _ = zc.buildout.easy_install.prefer_final(True)
       
  3064 
       
  3065     """
       
  3066 
       
  3067 def buildout_prefer_final_option():
       
  3068     """
       
  3069 The prefer-final buildout option can be used for override the default
       
  3070 preference for newer distributions.
       
  3071 
       
  3072 The default is prefer-final = false:
       
  3073 
       
  3074     >>> write('buildout.cfg',
       
  3075     ... '''
       
  3076     ... [buildout]
       
  3077     ... parts = eggs
       
  3078     ... find-links = %(link_server)s
       
  3079     ...
       
  3080     ... [eggs]
       
  3081     ... recipe = zc.recipe.egg:eggs
       
  3082     ... eggs = demo
       
  3083     ... ''' % globals())
       
  3084 
       
  3085     >>> print system(buildout+' -v'), # doctest: +ELLIPSIS
       
  3086     Installing 'zc.buildout', 'setuptools'.
       
  3087     ...
       
  3088     Picked: demo = 0.4c1
       
  3089     ...
       
  3090     Picked: demoneeded = 1.2c1
       
  3091 
       
  3092 Here we see that the final versions of demo and demoneeded are used.
       
  3093 We get the same behavior if we add prefer-final = false
       
  3094 
       
  3095     >>> write('buildout.cfg',
       
  3096     ... '''
       
  3097     ... [buildout]
       
  3098     ... parts = eggs
       
  3099     ... find-links = %(link_server)s
       
  3100     ... prefer-final = false
       
  3101     ...
       
  3102     ... [eggs]
       
  3103     ... recipe = zc.recipe.egg:eggs
       
  3104     ... eggs = demo
       
  3105     ... ''' % globals())
       
  3106 
       
  3107     >>> print system(buildout+' -v'), # doctest: +ELLIPSIS
       
  3108     Installing 'zc.buildout', 'setuptools'.
       
  3109     ...
       
  3110     Picked: demo = 0.4c1
       
  3111     ...
       
  3112     Picked: demoneeded = 1.2c1
       
  3113 
       
  3114 If we specify prefer-final = true, we'll get the newest
       
  3115 distributions:
       
  3116 
       
  3117     >>> write('buildout.cfg',
       
  3118     ... '''
       
  3119     ... [buildout]
       
  3120     ... parts = eggs
       
  3121     ... find-links = %(link_server)s
       
  3122     ... prefer-final = true
       
  3123     ...
       
  3124     ... [eggs]
       
  3125     ... recipe = zc.recipe.egg:eggs
       
  3126     ... eggs = demo
       
  3127     ... ''' % globals())
       
  3128 
       
  3129     >>> print system(buildout+' -v'), # doctest: +ELLIPSIS
       
  3130     Installing 'zc.buildout', 'setuptools'.
       
  3131     ...
       
  3132     Picked: demo = 0.3
       
  3133     ...
       
  3134     Picked: demoneeded = 1.1
       
  3135 
       
  3136 We get an error if we specify anything but true or false:
       
  3137 
       
  3138     >>> write('buildout.cfg',
       
  3139     ... '''
       
  3140     ... [buildout]
       
  3141     ... parts = eggs
       
  3142     ... find-links = %(link_server)s
       
  3143     ... prefer-final = no
       
  3144     ...
       
  3145     ... [eggs]
       
  3146     ... recipe = zc.recipe.egg:eggs
       
  3147     ... eggs = demo
       
  3148     ... ''' % globals())
       
  3149 
       
  3150     >>> print system(buildout+' -v'), # doctest: +ELLIPSIS
       
  3151     While:
       
  3152       Initializing.
       
  3153     Error: Invalid value for prefer-final option: no
       
  3154 
       
  3155     """
       
  3156 
       
  3157 def buildout_prefer_final_build_system_option():
       
  3158     """
       
  3159 The accept-buildout-test-releases buildout option can be used for overriding
       
  3160 the default preference for final distributions for recipes, buildout
       
  3161 extensions, and buildout itself.  It is usually controlled via the bootstrap
       
  3162 script rather than in the configuration file, but we will test the machinery
       
  3163 using the file.
       
  3164 
       
  3165 Set up.  This creates sdists for demorecipe 1.0 and 1.1b1, and for
       
  3166 demoextension 1.0 and 1.1b1.
       
  3167 
       
  3168     >>> create_sample_recipe_sdists(sample_eggs)
       
  3169     >>> create_sample_extension_sdists(sample_eggs)
       
  3170 
       
  3171 The default is accept-buildout-test-releases = false:
       
  3172 
       
  3173     >>> write('buildout.cfg',
       
  3174     ... '''
       
  3175     ... [buildout]
       
  3176     ... parts = demo
       
  3177     ... find-links = %(link_server)s
       
  3178     ... extensions = demoextension
       
  3179     ...
       
  3180     ... [demo]
       
  3181     ... recipe = demorecipe
       
  3182     ... ''' % globals())
       
  3183 
       
  3184     >>> print system(buildout+' -v'), # doctest: +ELLIPSIS
       
  3185     Installing ...
       
  3186     Picked: demoextension = 1.0
       
  3187     ...
       
  3188     Picked: demorecipe = 1.0
       
  3189     ...
       
  3190 
       
  3191 Here we see that the final versions of demorecipe and demoextension were used.
       
  3192 
       
  3193 We get the same behavior if we explicitly state that
       
  3194 accept-buildout-test-releases = false.
       
  3195 
       
  3196     >>> write('buildout.cfg',
       
  3197     ... '''
       
  3198     ... [buildout]
       
  3199     ... parts = demo
       
  3200     ... find-links = %(link_server)s
       
  3201     ... extensions = demoextension
       
  3202     ... accept-buildout-test-releases = false
       
  3203     ...
       
  3204     ... [demo]
       
  3205     ... recipe = demorecipe
       
  3206     ... ''' % globals())
       
  3207 
       
  3208     >>> print system(buildout+' -v'), # doctest: +ELLIPSIS
       
  3209     Installing ...
       
  3210     Picked: demoextension = 1.0
       
  3211     ...
       
  3212     Picked: demorecipe = 1.0
       
  3213     ...
       
  3214 
       
  3215 If we specify accept-buildout-test-releases = true, we'll get the newest
       
  3216 distributions in the build system:
       
  3217 
       
  3218     >>> write('buildout.cfg',
       
  3219     ... '''
       
  3220     ... [buildout]
       
  3221     ... parts = demo
       
  3222     ... find-links = %(link_server)s
       
  3223     ... extensions = demoextension
       
  3224     ... accept-buildout-test-releases = true
       
  3225     ...
       
  3226     ... [demo]
       
  3227     ... recipe = demorecipe
       
  3228     ... ''' % globals())
       
  3229 
       
  3230     >>> print system(buildout+' -v'), # doctest: +ELLIPSIS
       
  3231     Installing ...
       
  3232     Picked: demoextension = 1.1b1
       
  3233     ...
       
  3234     Picked: demorecipe = 1.1b1
       
  3235     ...
       
  3236 
       
  3237 We get an error if we specify anything but true or false:
       
  3238 
       
  3239     >>> write('buildout.cfg',
       
  3240     ... '''
       
  3241     ... [buildout]
       
  3242     ... parts = demo
       
  3243     ... find-links = %(link_server)s
       
  3244     ... extensions = demoextension
       
  3245     ... accept-buildout-test-releases = no
       
  3246     ...
       
  3247     ... [demo]
       
  3248     ... recipe = demorecipe
       
  3249     ... ''' % globals())
       
  3250 
       
  3251     >>> print system(buildout+' -v'), # doctest: +ELLIPSIS
       
  3252     While:
       
  3253       Initializing.
       
  3254     Error: Invalid value for accept-buildout-test-releases option: no
       
  3255 
       
  3256     """
       
  3257 
       
  3258 def develop_with_modules():
       
  3259     """
       
  3260 Distribution setup scripts can import modules in the distribution directory:
       
  3261 
       
  3262     >>> mkdir('foo')
       
  3263     >>> write('foo', 'bar.py',
       
  3264     ... '''# empty
       
  3265     ... ''')
       
  3266 
       
  3267     >>> write('foo', 'setup.py',
       
  3268     ... '''
       
  3269     ... import bar
       
  3270     ... from setuptools import setup
       
  3271     ... setup(name="foo")
       
  3272     ... ''')
       
  3273 
       
  3274     >>> write('buildout.cfg',
       
  3275     ... '''
       
  3276     ... [buildout]
       
  3277     ... develop = foo
       
  3278     ... parts =
       
  3279     ... ''')
       
  3280 
       
  3281     >>> print system(join('bin', 'buildout')),
       
  3282     Develop: '/sample-buildout/foo'
       
  3283 
       
  3284     >>> ls('develop-eggs')
       
  3285     -  foo.egg-link
       
  3286     -  z3c.recipe.scripts.egg-link
       
  3287     -  zc.recipe.egg.egg-link
       
  3288 
       
  3289     """
       
  3290 
       
  3291 def dont_pick_setuptools_if_version_is_specified_when_required_by_src_dist():
       
  3292     """
       
  3293 When installing a source distribution, we got setuptools without
       
  3294 honoring our version specification.
       
  3295 
       
  3296     >>> mkdir('dist')
       
  3297     >>> write('setup.py',
       
  3298     ... '''
       
  3299     ... from setuptools import setup
       
  3300     ... setup(name='foo', version='1', py_modules=['foo'], zip_safe=True)
       
  3301     ... ''')
       
  3302     >>> write('foo.py', '')
       
  3303     >>> _ = system(buildout+' setup . sdist')
       
  3304 
       
  3305     >>> if zc.buildout.easy_install.is_distribute:
       
  3306     ...     distribute_version = 'distribute = %s' % (
       
  3307     ...         pkg_resources.working_set.find(
       
  3308     ...             pkg_resources.Requirement.parse('distribute')).version,)
       
  3309     ... else:
       
  3310     ...     distribute_version = ''
       
  3311     ...
       
  3312     >>> write('buildout.cfg',
       
  3313     ... '''
       
  3314     ... [buildout]
       
  3315     ... parts = foo
       
  3316     ... find-links = dist
       
  3317     ... versions = versions
       
  3318     ... allow-picked-versions = false
       
  3319     ...
       
  3320     ... [versions]
       
  3321     ... setuptools = %s
       
  3322     ... foo = 1
       
  3323     ... %s
       
  3324     ...
       
  3325     ... [foo]
       
  3326     ... recipe = zc.recipe.egg
       
  3327     ... eggs = foo
       
  3328     ... ''' % (pkg_resources.working_set.find(
       
  3329     ...         pkg_resources.Requirement.parse('setuptools')).version,
       
  3330     ...        distribute_version))
       
  3331 
       
  3332     >>> print system(buildout),
       
  3333     Installing foo.
       
  3334     Getting distribution for 'foo==1'.
       
  3335     Got foo 1.
       
  3336 
       
  3337     """
       
  3338 
       
  3339 def pyc_and_pyo_files_have_correct_paths():
       
  3340     r"""
       
  3341 
       
  3342     >>> write('buildout.cfg',
       
  3343     ... '''
       
  3344     ... [buildout]
       
  3345     ... parts = eggs
       
  3346     ... find-links = %(link_server)s
       
  3347     ... unzip = true
       
  3348     ...
       
  3349     ... [eggs]
       
  3350     ... recipe = zc.recipe.egg
       
  3351     ... eggs = demo
       
  3352     ... interpreter = py
       
  3353     ... ''' % globals())
       
  3354 
       
  3355     >>> _ = system(buildout)
       
  3356 
       
  3357     >>> write('t.py',
       
  3358     ... '''
       
  3359     ... import eggrecipedemo, eggrecipedemoneeded
       
  3360     ... print eggrecipedemo.main.func_code.co_filename
       
  3361     ... print eggrecipedemoneeded.f.func_code.co_filename
       
  3362     ... ''')
       
  3363 
       
  3364     >>> print system(join('bin', 'py')+ ' t.py'),
       
  3365     /sample-buildout/eggs/demo-0.4c1-py2.4.egg/eggrecipedemo.py
       
  3366     /sample-buildout/eggs/demoneeded-1.2c1-py2.4.egg/eggrecipedemoneeded.py
       
  3367 
       
  3368     >>> import os
       
  3369     >>> for name in os.listdir('eggs'):
       
  3370     ...     if name.startswith('demoneeded'):
       
  3371     ...         ls('eggs', name)
       
  3372     d  EGG-INFO
       
  3373     -  eggrecipedemoneeded.py
       
  3374     -  eggrecipedemoneeded.pyc
       
  3375     -  eggrecipedemoneeded.pyo
       
  3376 
       
  3377     """
       
  3378 
       
  3379 def dont_mess_with_standard_dirs_with_variable_refs():
       
  3380     """
       
  3381     >>> write('buildout.cfg',
       
  3382     ... '''
       
  3383     ... [buildout]
       
  3384     ... eggs-directory = ${buildout:directory}/develop-eggs
       
  3385     ... parts =
       
  3386     ... ''' % globals())
       
  3387     >>> print system(buildout),
       
  3388 
       
  3389     """
       
  3390 
       
  3391 def expand_shell_patterns_in_develop_paths():
       
  3392     """
       
  3393     Sometimes we want to include a number of eggs in some directory as
       
  3394     develop eggs, without explicitly listing all of them in our
       
  3395     buildout.cfg
       
  3396 
       
  3397     >>> make_dist_that_requires(sample_buildout, 'sampley')
       
  3398     >>> make_dist_that_requires(sample_buildout, 'samplez')
       
  3399 
       
  3400     Now, let's create a buildout that has a shell pattern that matches
       
  3401     both:
       
  3402 
       
  3403     >>> write('buildout.cfg',
       
  3404     ... '''
       
  3405     ... [buildout]
       
  3406     ... parts = eggs
       
  3407     ... develop = sample*
       
  3408     ... find-links = %(link_server)s
       
  3409     ...
       
  3410     ... [eggs]
       
  3411     ... recipe = zc.recipe.egg
       
  3412     ... eggs = sampley
       
  3413     ...        samplez
       
  3414     ... ''' % globals())
       
  3415 
       
  3416     We can see that both eggs were found:
       
  3417 
       
  3418     >>> print system(buildout),
       
  3419     Develop: '/sample-buildout/sampley'
       
  3420     Develop: '/sample-buildout/samplez'
       
  3421     Installing eggs.
       
  3422 
       
  3423     """
       
  3424 
       
  3425 def warn_users_when_expanding_shell_patterns_yields_no_results():
       
  3426     """
       
  3427     Sometimes shell patterns do not match anything, so we want to warn
       
  3428     our users about it...
       
  3429 
       
  3430     >>> make_dist_that_requires(sample_buildout, 'samplea')
       
  3431 
       
  3432     So if we have 2 patterns, one that has a matching directory, and
       
  3433     another one that does not
       
  3434 
       
  3435     >>> write('buildout.cfg',
       
  3436     ... '''
       
  3437     ... [buildout]
       
  3438     ... parts = eggs
       
  3439     ... develop = samplea grumble*
       
  3440     ... find-links = %(link_server)s
       
  3441     ...
       
  3442     ... [eggs]
       
  3443     ... recipe = zc.recipe.egg
       
  3444     ... eggs = samplea
       
  3445     ... ''' % globals())
       
  3446 
       
  3447     We should get one of the eggs, and a warning for the pattern that
       
  3448     did not match anything.
       
  3449 
       
  3450     >>> print system(buildout),
       
  3451     Develop: '/sample-buildout/samplea'
       
  3452     Couldn't develop '/sample-buildout/grumble*' (not found)
       
  3453     Installing eggs.
       
  3454 
       
  3455     """
       
  3456 
       
  3457 def make_sure_versions_dont_cancel_extras():
       
  3458     """
       
  3459     There was a bug that caused extras in requirements to be lost.
       
  3460 
       
  3461     >>> open('setup.py', 'w').write('''
       
  3462     ... from setuptools import setup
       
  3463     ... setup(name='extraversiondemo', version='1.0',
       
  3464     ...       url='x', author='x', author_email='x',
       
  3465     ...       extras_require=dict(foo=['demo']), py_modules=['t'])
       
  3466     ... ''')
       
  3467     >>> open('README', 'w').close()
       
  3468     >>> open('t.py', 'w').close()
       
  3469 
       
  3470     >>> sdist('.', sample_eggs)
       
  3471     >>> mkdir('dest')
       
  3472     >>> ws = zc.buildout.easy_install.install(
       
  3473     ...     ['extraversiondemo[foo]'], 'dest', links=[sample_eggs],
       
  3474     ...     versions = dict(extraversiondemo='1.0')
       
  3475     ... )
       
  3476     >>> sorted(dist.key for dist in ws)
       
  3477     ['demo', 'demoneeded', 'extraversiondemo']
       
  3478     """
       
  3479 
       
  3480 def increment_buildout_options():
       
  3481     r"""
       
  3482     >>> write('b1.cfg', '''
       
  3483     ... [buildout]
       
  3484     ... parts = p1
       
  3485     ... x = 1
       
  3486     ... y = a
       
  3487     ...     b
       
  3488     ...
       
  3489     ... [p1]
       
  3490     ... recipe = zc.buildout:debug
       
  3491     ... foo = ${buildout:x} ${buildout:y}
       
  3492     ... ''')
       
  3493 
       
  3494     >>> write('buildout.cfg', '''
       
  3495     ... [buildout]
       
  3496     ... extends = b1.cfg
       
  3497     ... parts += p2
       
  3498     ... x += 2
       
  3499     ... y -= a
       
  3500     ...
       
  3501     ... [p2]
       
  3502     ... <= p1
       
  3503     ... ''')
       
  3504 
       
  3505     >>> print system(buildout),
       
  3506     Installing p1.
       
  3507       foo='1\n2 b'
       
  3508       recipe='zc.buildout:debug'
       
  3509     Installing p2.
       
  3510       foo='1\n2 b'
       
  3511       recipe='zc.buildout:debug'
       
  3512     """
       
  3513 
       
  3514 def increment_buildout_with_multiple_extended_files_421022():
       
  3515     r"""
       
  3516     >>> write('foo.cfg', '''
       
  3517     ... [buildout]
       
  3518     ... foo-option = foo
       
  3519     ... [other]
       
  3520     ... foo-option = foo
       
  3521     ... ''')
       
  3522     >>> write('bar.cfg', '''
       
  3523     ... [buildout]
       
  3524     ... bar-option = bar
       
  3525     ... [other]
       
  3526     ... bar-option = bar
       
  3527     ... ''')
       
  3528     >>> write('buildout.cfg', '''
       
  3529     ... [buildout]
       
  3530     ... parts = p other
       
  3531     ... extends = bar.cfg foo.cfg
       
  3532     ... bar-option += baz
       
  3533     ... foo-option += ham
       
  3534     ...
       
  3535     ... [other]
       
  3536     ... recipe = zc.buildout:debug
       
  3537     ... bar-option += baz
       
  3538     ... foo-option += ham
       
  3539     ...
       
  3540     ... [p]
       
  3541     ... recipe = zc.buildout:debug
       
  3542     ... x = ${buildout:bar-option} ${buildout:foo-option}
       
  3543     ... ''')
       
  3544 
       
  3545     >>> print system(buildout),
       
  3546     Installing p.
       
  3547       recipe='zc.buildout:debug'
       
  3548       x='bar\nbaz foo\nham'
       
  3549     Installing other.
       
  3550       bar-option='bar\nbaz'
       
  3551       foo-option='foo\nham'
       
  3552       recipe='zc.buildout:debug'
       
  3553     """
       
  3554 
       
  3555 def increment_on_command_line():
       
  3556     r"""
       
  3557     >>> write('buildout.cfg', '''
       
  3558     ... [buildout]
       
  3559     ... parts = p1
       
  3560     ... x = 1
       
  3561     ... y = a
       
  3562     ...     b
       
  3563     ...
       
  3564     ... [p1]
       
  3565     ... recipe = zc.buildout:debug
       
  3566     ... foo = ${buildout:x} ${buildout:y}
       
  3567     ...
       
  3568     ... [p2]
       
  3569     ... <= p1
       
  3570     ... ''')
       
  3571 
       
  3572     >>> print system(buildout+' buildout:parts+=p2 p1:foo+=bar'),
       
  3573     Installing p1.
       
  3574       foo='1 a\nb\nbar'
       
  3575       recipe='zc.buildout:debug'
       
  3576     Installing p2.
       
  3577       foo='1 a\nb\nbar'
       
  3578       recipe='zc.buildout:debug'
       
  3579     """
       
  3580 
       
  3581 ######################################################################
       
  3582 
       
  3583 def make_py_with_system_install(make_py, sample_eggs):
       
  3584     py_path, site_packages_path = make_py()
       
  3585     create_sample_namespace_eggs(sample_eggs, site_packages_path)
       
  3586     return py_path
       
  3587 
       
  3588 def create_sample_namespace_eggs(dest, site_packages_path=None):
       
  3589     from zc.buildout.testing import write, mkdir
       
  3590     for pkg, version in (('version', '1.0'), ('version', '1.1'),
       
  3591                          ('fortune', '1.0')):
       
  3592         tmp = tempfile.mkdtemp()
       
  3593         try:
       
  3594             write(tmp, 'README.txt', '')
       
  3595             mkdir(tmp, 'src')
       
  3596             mkdir(tmp, 'src', 'tellmy')
       
  3597             write(tmp, 'src', 'tellmy', '__init__.py',
       
  3598                 "__import__("
       
  3599                 "'pkg_resources').declare_namespace(__name__)\n")
       
  3600             mkdir(tmp, 'src', 'tellmy', pkg)
       
  3601             write(tmp, 'src', 'tellmy', pkg,
       
  3602                   '__init__.py', '__version__=%r\n' % version)
       
  3603             write(
       
  3604                 tmp, 'setup.py',
       
  3605                 "from setuptools import setup\n"
       
  3606                 "setup(\n"
       
  3607                 " name='tellmy.%(pkg)s',\n"
       
  3608                 " package_dir = {'': 'src'},\n"
       
  3609                 " packages = ['tellmy', 'tellmy.%(pkg)s'],\n"
       
  3610                 " install_requires = ['setuptools'],\n"
       
  3611                 " namespace_packages=['tellmy'],\n"
       
  3612                 " zip_safe=True, version=%(version)r,\n"
       
  3613                 " author='bob', url='bob', author_email='bob')\n"
       
  3614                 % locals()
       
  3615                 )
       
  3616             zc.buildout.testing.sdist(tmp, dest)
       
  3617             if (site_packages_path and pkg == 'version' and version == '1.1'):
       
  3618                 # We install the 1.1 version in site packages the way a
       
  3619                 # system packaging system (debs, rpms) would do it.
       
  3620                 zc.buildout.testing.sys_install(tmp, site_packages_path)
       
  3621         finally:
       
  3622             shutil.rmtree(tmp)
       
  3623 
       
  3624 def create_sample_extension_sdists(dest):
       
  3625     from zc.buildout.testing import write, mkdir
       
  3626     name = 'demoextension'
       
  3627     for version in ('1.0', '1.1b1'):
       
  3628         tmp = tempfile.mkdtemp()
       
  3629         try:
       
  3630             write(tmp, 'README.txt', '')
       
  3631             write(tmp, name + '.py',
       
  3632                   "def ext(buildout):\n"
       
  3633                   "    pass\n"
       
  3634                   "def unload(buildout):\n"
       
  3635                   "    pass\n"
       
  3636                   % locals())
       
  3637             write(tmp, 'setup.py',
       
  3638                   "from setuptools import setup\n"
       
  3639                   "setup(\n"
       
  3640                   "    name = %(name)r,\n"
       
  3641                   "    py_modules = [%(name)r],\n"
       
  3642                   "    entry_points = {\n"
       
  3643                   "       'zc.buildout.extension': "
       
  3644                               "['ext = %(name)s:ext'],\n"
       
  3645                   "       'zc.buildout.unloadextension': "
       
  3646                               "['ext = %(name)s:unload'],\n"
       
  3647                   "       },\n"
       
  3648                   "    zip_safe=True, version=%(version)r,\n"
       
  3649                   "    author='bob', url='bob', author_email='bob')\n"
       
  3650                   % locals())
       
  3651             zc.buildout.testing.sdist(tmp, dest)
       
  3652         finally:
       
  3653             shutil.rmtree(tmp)
       
  3654 
       
  3655 def create_sample_recipe_sdists(dest):
       
  3656     from zc.buildout.testing import write, mkdir
       
  3657     name = 'demorecipe'
       
  3658     for version in ('1.0', '1.1b1'):
       
  3659         tmp = tempfile.mkdtemp()
       
  3660         try:
       
  3661             write(tmp, 'README.txt', '')
       
  3662             write(tmp, name + '.py',
       
  3663                   "import logging, os, zc.buildout\n"
       
  3664                   "class Demorecipe:\n"
       
  3665                   "    def __init__(self, buildout, name, options):\n"
       
  3666                   "        self.name, self.options = name, options\n"
       
  3667                   "    def install(self):\n"
       
  3668                   "        return ()\n"
       
  3669                   "    def update(self):\n"
       
  3670                   "        pass\n"
       
  3671                   % locals())
       
  3672             write(tmp, 'setup.py',
       
  3673                   "from setuptools import setup\n"
       
  3674                   "setup(\n"
       
  3675                   "    name = %(name)r,\n"
       
  3676                   "    py_modules = [%(name)r],\n"
       
  3677                   "    entry_points = {'zc.buildout': "
       
  3678                                        "['default = %(name)s:Demorecipe']},\n"
       
  3679                   "    zip_safe=True, version=%(version)r,\n"
       
  3680                   "    author='bob', url='bob', author_email='bob')\n"
       
  3681                   % locals())
       
  3682             zc.buildout.testing.sdist(tmp, dest)
       
  3683         finally:
       
  3684             shutil.rmtree(tmp)
       
  3685 
       
  3686 def _write_eggrecipedemoneeded(tmp, minor_version, suffix=''):
       
  3687     from zc.buildout.testing import write
       
  3688     write(tmp, 'README.txt', '')
       
  3689     write(tmp, 'eggrecipedemoneeded.py',
       
  3690           'y=%s\ndef f():\n  pass' % minor_version)
       
  3691     write(
       
  3692         tmp, 'setup.py',
       
  3693         "from setuptools import setup\n"
       
  3694         "setup(name='demoneeded', py_modules=['eggrecipedemoneeded'],"
       
  3695         " zip_safe=True, version='1.%s%s', author='bob', url='bob', "
       
  3696         "author_email='bob')\n"
       
  3697         % (minor_version, suffix)
       
  3698         )
       
  3699 
       
  3700 def _write_eggrecipedemo(tmp, minor_version, suffix=''):
       
  3701     from zc.buildout.testing import write
       
  3702     write(tmp, 'README.txt', '')
       
  3703     write(
       
  3704         tmp, 'eggrecipedemo.py',
       
  3705         'import eggrecipedemoneeded\n'
       
  3706         'x=%s\n'
       
  3707         'def main(): print x, eggrecipedemoneeded.y\n'
       
  3708         % minor_version)
       
  3709     write(
       
  3710         tmp, 'setup.py',
       
  3711         "from setuptools import setup\n"
       
  3712         "setup(name='demo', py_modules=['eggrecipedemo'],"
       
  3713         " install_requires = 'demoneeded',"
       
  3714         " entry_points={'console_scripts': "
       
  3715              "['demo = eggrecipedemo:main']},"
       
  3716         " zip_safe=True, version='0.%s%s')\n" % (minor_version, suffix)
       
  3717         )
       
  3718 
       
  3719 def create_sample_sys_install(site_packages_path):
       
  3720     for creator, minor_version in (
       
  3721         (_write_eggrecipedemoneeded, 1),
       
  3722         (_write_eggrecipedemo, 3)):
       
  3723         # Write the files and install in site_packages_path.
       
  3724         tmp = tempfile.mkdtemp()
       
  3725         try:
       
  3726             creator(tmp, minor_version)
       
  3727             zc.buildout.testing.sys_install(tmp, site_packages_path)
       
  3728         finally:
       
  3729             shutil.rmtree(tmp)
       
  3730 
       
  3731 def create_sample_eggs(test, executable=sys.executable):
       
  3732     from zc.buildout.testing import write
       
  3733     dest = test.globs['sample_eggs']
       
  3734     tmp = tempfile.mkdtemp()
       
  3735     try:
       
  3736         for i in (0, 1, 2):
       
  3737             suffix = i==2 and 'c1' or ''
       
  3738             _write_eggrecipedemoneeded(tmp, i, suffix)
       
  3739             zc.buildout.testing.sdist(tmp, dest)
       
  3740 
       
  3741         write(
       
  3742             tmp, 'setup.py',
       
  3743             "from setuptools import setup\n"
       
  3744             "setup(name='other', zip_safe=False, version='1.0', "
       
  3745             "py_modules=['eggrecipedemoneeded'])\n"
       
  3746             )
       
  3747         zc.buildout.testing.bdist_egg(tmp, executable, dest)
       
  3748 
       
  3749         os.remove(os.path.join(tmp, 'eggrecipedemoneeded.py'))
       
  3750 
       
  3751         for i in (1, 2, 3, 4):
       
  3752             suffix = i==4 and 'c1' or ''
       
  3753             _write_eggrecipedemo(tmp, i, suffix)
       
  3754             zc.buildout.testing.bdist_egg(tmp, executable, dest)
       
  3755 
       
  3756         write(tmp, 'eggrecipebigdemo.py', 'import eggrecipedemo')
       
  3757         write(
       
  3758             tmp, 'setup.py',
       
  3759             "from setuptools import setup\n"
       
  3760             "setup(name='bigdemo', "
       
  3761             " install_requires = 'demo',"
       
  3762             " py_modules=['eggrecipebigdemo'], "
       
  3763             " zip_safe=True, version='0.1')\n"
       
  3764             )
       
  3765         zc.buildout.testing.bdist_egg(tmp, executable, dest)
       
  3766 
       
  3767     finally:
       
  3768         shutil.rmtree(tmp)
       
  3769 
       
  3770 extdemo_c = """
       
  3771 #include <Python.h>
       
  3772 #include <extdemo.h>
       
  3773 
       
  3774 static PyMethodDef methods[] = {{NULL}};
       
  3775 
       
  3776 PyMODINIT_FUNC
       
  3777 initextdemo(void)
       
  3778 {
       
  3779     PyObject *m;
       
  3780     m = Py_InitModule3("extdemo", methods, "");
       
  3781 #ifdef TWO
       
  3782     PyModule_AddObject(m, "val", PyInt_FromLong(2));
       
  3783 #else
       
  3784     PyModule_AddObject(m, "val", PyInt_FromLong(EXTDEMO));
       
  3785 #endif
       
  3786 }
       
  3787 """
       
  3788 
       
  3789 extdemo_setup_py = """
       
  3790 import os
       
  3791 from distutils.core import setup, Extension
       
  3792 
       
  3793 if os.environ.get('test-variable'):
       
  3794     print "Have environment test-variable:", os.environ['test-variable']
       
  3795 
       
  3796 setup(name = "extdemo", version = "%s", url="http://www.zope.org",
       
  3797       author="Demo", author_email="demo@demo.com",
       
  3798       ext_modules = [Extension('extdemo', ['extdemo.c'])],
       
  3799       )
       
  3800 """
       
  3801 
       
  3802 def add_source_dist(test, version=1.4):
       
  3803 
       
  3804     if 'extdemo' not in test.globs:
       
  3805         test.globs['extdemo'] = test.globs['tmpdir']('extdemo')
       
  3806 
       
  3807     tmp = test.globs['extdemo']
       
  3808     write = test.globs['write']
       
  3809     try:
       
  3810         write(tmp, 'extdemo.c', extdemo_c);
       
  3811         write(tmp, 'setup.py', extdemo_setup_py % version);
       
  3812         write(tmp, 'README', "");
       
  3813         write(tmp, 'MANIFEST.in', "include *.c\n");
       
  3814         test.globs['sdist'](tmp, test.globs['sample_eggs'])
       
  3815     except:
       
  3816         shutil.rmtree(tmp)
       
  3817 
       
  3818 def easy_install_SetUp(test):
       
  3819     zc.buildout.testing.buildoutSetUp(test)
       
  3820     sample_eggs = test.globs['tmpdir']('sample_eggs')
       
  3821     test.globs['sample_eggs'] = sample_eggs
       
  3822     os.mkdir(os.path.join(sample_eggs, 'index'))
       
  3823     create_sample_eggs(test)
       
  3824     add_source_dist(test)
       
  3825     test.globs['link_server'] = test.globs['start_server'](
       
  3826         test.globs['sample_eggs'])
       
  3827     test.globs['update_extdemo'] = lambda : add_source_dist(test, 1.5)
       
  3828     zc.buildout.testing.install_develop('zc.recipe.egg', test)
       
  3829     zc.buildout.testing.install_develop('z3c.recipe.scripts', test)
       
  3830 
       
  3831 egg_parse = re.compile('([0-9a-zA-Z_.]+)-([0-9a-zA-Z_.]+)-py(\d[.]\d).egg$'
       
  3832                        ).match
       
  3833 def makeNewRelease(project, ws, dest, version='99.99'):
       
  3834     dist = ws.find(pkg_resources.Requirement.parse(project))
       
  3835     eggname, oldver, pyver = egg_parse(
       
  3836         os.path.basename(dist.location)
       
  3837         ).groups()
       
  3838     dest = os.path.join(dest, "%s-%s-py%s.egg" % (eggname, version, pyver))
       
  3839     if os.path.isfile(dist.location):
       
  3840         shutil.copy(dist.location, dest)
       
  3841         zip = zipfile.ZipFile(dest, 'a')
       
  3842         zip.writestr(
       
  3843             'EGG-INFO/PKG-INFO',
       
  3844             zip.read('EGG-INFO/PKG-INFO').replace("Version: %s" % oldver,
       
  3845                                                   "Version: %s" % version)
       
  3846             )
       
  3847         zip.close()
       
  3848     else:
       
  3849         shutil.copytree(dist.location, dest)
       
  3850         info_path = os.path.join(dest, 'EGG-INFO', 'PKG-INFO')
       
  3851         info = open(info_path).read().replace("Version: %s" % oldver,
       
  3852                                               "Version: %s" % version)
       
  3853         open(info_path, 'w').write(info)
       
  3854 
       
  3855 def getWorkingSetWithBuildoutEgg(test):
       
  3856     sample_buildout = test.globs['sample_buildout']
       
  3857     eggs = os.path.join(sample_buildout, 'eggs')
       
  3858 
       
  3859     # If the zc.buildout dist is a develop dist, convert it to a
       
  3860     # regular egg in the sample buildout
       
  3861     req = pkg_resources.Requirement.parse('zc.buildout')
       
  3862     dist = pkg_resources.working_set.find(req)
       
  3863     if dist.precedence == pkg_resources.DEVELOP_DIST:
       
  3864         # We have a develop egg, create a real egg for it:
       
  3865         here = os.getcwd()
       
  3866         os.chdir(os.path.dirname(dist.location))
       
  3867         assert os.spawnle(
       
  3868             os.P_WAIT, sys.executable,
       
  3869             zc.buildout.easy_install._safe_arg(sys.executable),
       
  3870             os.path.join(os.path.dirname(dist.location), 'setup.py'),
       
  3871             '-q', 'bdist_egg', '-d', eggs,
       
  3872             dict(os.environ,
       
  3873                  PYTHONPATH=pkg_resources.working_set.find(
       
  3874                                pkg_resources.Requirement.parse('setuptools')
       
  3875                                ).location,
       
  3876                  ),
       
  3877             ) == 0
       
  3878         os.chdir(here)
       
  3879         os.remove(os.path.join(eggs, 'zc.buildout.egg-link'))
       
  3880 
       
  3881         # Rebuild the buildout script
       
  3882         ws = pkg_resources.WorkingSet([eggs])
       
  3883         ws.require('zc.buildout')
       
  3884         zc.buildout.easy_install.scripts(
       
  3885             ['zc.buildout'], ws, sys.executable,
       
  3886             os.path.join(sample_buildout, 'bin'))
       
  3887     else:
       
  3888         ws = pkg_resources.working_set
       
  3889     return ws
       
  3890 
       
  3891 def updateSetup(test):
       
  3892     zc.buildout.testing.buildoutSetUp(test)
       
  3893     new_releases = test.globs['tmpdir']('new_releases')
       
  3894     test.globs['new_releases'] = new_releases
       
  3895     ws = getWorkingSetWithBuildoutEgg(test)
       
  3896     # now let's make the new releases
       
  3897     makeNewRelease('zc.buildout', ws, new_releases)
       
  3898     makeNewRelease('zc.buildout', ws, new_releases, '100.0b1')
       
  3899     os.mkdir(os.path.join(new_releases, 'zc.buildout'))
       
  3900     if zc.buildout.easy_install.is_distribute:
       
  3901         makeNewRelease('distribute', ws, new_releases)
       
  3902         os.mkdir(os.path.join(new_releases, 'distribute'))
       
  3903     else:
       
  3904         makeNewRelease('setuptools', ws, new_releases)
       
  3905         os.mkdir(os.path.join(new_releases, 'setuptools'))
       
  3906 
       
  3907 def bootstrapSetup(test):
       
  3908     easy_install_SetUp(test)
       
  3909     sample_eggs = test.globs['sample_eggs']
       
  3910     ws = getWorkingSetWithBuildoutEgg(test)
       
  3911     makeNewRelease('zc.buildout', ws, sample_eggs)
       
  3912     makeNewRelease('zc.buildout', ws, sample_eggs, '100.0b1')
       
  3913     os.environ['bootstrap-testing-find-links'] = test.globs['link_server']
       
  3914 
       
  3915 normalize_bang = (
       
  3916     re.compile(re.escape('#!'+
       
  3917                          zc.buildout.easy_install._safe_arg(sys.executable))),
       
  3918     '#!/usr/local/bin/python2.4',
       
  3919     )
       
  3920 
       
  3921 hide_distribute_additions = (re.compile('install_dir .+\n'), '')
       
  3922 hide_zip_safe_message = (
       
  3923     # This comes in a different place in the output in Python 2.7.  It's not
       
  3924     # important to our tests.  Hide it.
       
  3925     re.compile(
       
  3926         '((?<=\n)\n)?zip_safe flag not set; analyzing archive contents...\n'),
       
  3927     '')
       
  3928 hide_first_index_page_message = (
       
  3929     # This comes in a different place in the output in Python 2.7.  It's not
       
  3930     # important to our tests.  Hide it.
       
  3931     re.compile(
       
  3932         "Couldn't find index page for '[^']+' \(maybe misspelled\?\)\n"),
       
  3933     '')
       
  3934 def test_suite():
       
  3935     test_suite = [
       
  3936         doctest.DocFileSuite(
       
  3937             'buildout.txt', 'runsetup.txt', 'repeatable.txt', 'setup.txt',
       
  3938             setUp=zc.buildout.testing.buildoutSetUp,
       
  3939             tearDown=zc.buildout.testing.buildoutTearDown,
       
  3940             checker=renormalizing.RENormalizing([
       
  3941                 zc.buildout.testing.normalize_path,
       
  3942                 zc.buildout.testing.normalize_endings,
       
  3943                 zc.buildout.testing.normalize_script,
       
  3944                 zc.buildout.testing.normalize_egg_py,
       
  3945                 zc.buildout.tests.hide_distribute_additions,
       
  3946                 hide_zip_safe_message,
       
  3947                 (re.compile('__buildout_signature__ = recipes-\S+'),
       
  3948                  '__buildout_signature__ = recipes-SSSSSSSSSSS'),
       
  3949                 (re.compile('executable = [\S ]+python\S*', re.I),
       
  3950                  'executable = python'),
       
  3951                 (re.compile('[-d]  (setuptools|distribute)-\S+[.]egg'),
       
  3952                  'setuptools.egg'),
       
  3953                 (re.compile('zc.buildout(-\S+)?[.]egg(-link)?'),
       
  3954                  'zc.buildout.egg'),
       
  3955                 (re.compile('creating \S*setup.cfg'), 'creating setup.cfg'),
       
  3956                 (re.compile('hello\%ssetup' % os.path.sep), 'hello/setup'),
       
  3957                 (re.compile('Picked: (\S+) = \S+'),
       
  3958                  'Picked: \\1 = V.V'),
       
  3959                 (re.compile(r'We have a develop egg: zc.buildout (\S+)'),
       
  3960                  'We have a develop egg: zc.buildout X.X.'),
       
  3961                 (re.compile(r'\\[\\]?'), '/'),
       
  3962                 (re.compile('WindowsError'), 'OSError'),
       
  3963                 (re.compile(r'\[Error \d+\] Cannot create a file '
       
  3964                             r'when that file already exists: '),
       
  3965                  '[Errno 17] File exists: '
       
  3966                  ),
       
  3967                 (re.compile('distribute'), 'setuptools'),
       
  3968                 ])
       
  3969             ),
       
  3970         doctest.DocFileSuite(
       
  3971             'debugging.txt',
       
  3972             setUp=zc.buildout.testing.buildoutSetUp,
       
  3973             tearDown=zc.buildout.testing.buildoutTearDown,
       
  3974             checker=renormalizing.RENormalizing([
       
  3975                 zc.buildout.testing.normalize_path,
       
  3976                 zc.buildout.testing.normalize_endings,
       
  3977                 zc.buildout.tests.hide_distribute_additions,
       
  3978                 (re.compile(r'\S+buildout.py'), 'buildout.py'),
       
  3979                 (re.compile(r'line \d+'), 'line NNN'),
       
  3980                 (re.compile(r'py\(\d+\)'), 'py(NNN)'),
       
  3981                 ])
       
  3982             ),
       
  3983 
       
  3984         doctest.DocFileSuite(
       
  3985             'update.txt',
       
  3986             setUp=updateSetup,
       
  3987             tearDown=zc.buildout.testing.buildoutTearDown,
       
  3988             checker=renormalizing.RENormalizing([
       
  3989                 zc.buildout.testing.normalize_path,
       
  3990                 zc.buildout.testing.normalize_endings,
       
  3991                 zc.buildout.testing.normalize_script,
       
  3992                 zc.buildout.testing.normalize_egg_py,
       
  3993                 normalize_bang,
       
  3994                 zc.buildout.tests.hide_distribute_additions,
       
  3995                 (re.compile('99[.]99'), 'NINETYNINE.NINETYNINE'),
       
  3996                 (re.compile('(zc.buildout|setuptools)-\d+[.]\d+\S*'
       
  3997                             '-py\d.\d.egg'),
       
  3998                  '\\1.egg'),
       
  3999                 (re.compile('distribute-\d+[.]\d+\S*'
       
  4000                             '-py\d.\d.egg'),
       
  4001                  'setuptools.egg'),
       
  4002                 (re.compile('(zc.buildout|setuptools)( version)? \d+[.]\d+\S*'),
       
  4003                  '\\1 V.V'),
       
  4004                 (re.compile('distribute( version)? \d+[.]\d+\S*'),
       
  4005                  'setuptools V.V'),
       
  4006                 (re.compile('[-d]  (setuptools|distribute)'), '-  setuptools'),
       
  4007                 (re.compile('distribute'), 'setuptools'),
       
  4008                 (re.compile("\nUnused options for buildout: "
       
  4009                             "'(distribute|setuptools)\-version'\."),
       
  4010                  '')
       
  4011                 ])
       
  4012             ),
       
  4013 
       
  4014         doctest.DocFileSuite(
       
  4015             'easy_install.txt', 'downloadcache.txt', 'dependencylinks.txt',
       
  4016             'allowhosts.txt', 'unzip.txt', 'upgrading_distribute.txt',
       
  4017             setUp=easy_install_SetUp,
       
  4018             tearDown=zc.buildout.testing.buildoutTearDown,
       
  4019             checker=renormalizing.RENormalizing([
       
  4020                 zc.buildout.testing.normalize_path,
       
  4021                 zc.buildout.testing.normalize_endings,
       
  4022                 zc.buildout.testing.normalize_script,
       
  4023                 zc.buildout.testing.normalize_egg_py,
       
  4024                 normalize_bang,
       
  4025                 hide_first_index_page_message,
       
  4026                 zc.buildout.tests.hide_distribute_additions,
       
  4027                 (re.compile('extdemo[.]pyd'), 'extdemo.so'),
       
  4028                 (re.compile('[-d]  (setuptools|distribute)-\S+[.]egg'),
       
  4029                  'setuptools.egg'),
       
  4030                 (re.compile(r'\\[\\]?'), '/'),
       
  4031                 (re.compile(r'\#!\S+\bpython\S*'), '#!/usr/bin/python'),
       
  4032                 # Normalize generate_script's Windows interpreter to UNIX:
       
  4033                 (re.compile(r'\nimport subprocess\n'), '\n'),
       
  4034                 (re.compile('subprocess\\.call\\(argv, env=environ\\)'),
       
  4035                  'os.execve(sys.executable, argv, environ)'),
       
  4036                 (re.compile('distribute'), 'setuptools'),
       
  4037                 # Distribute unzips eggs by default.
       
  4038                 (re.compile('\-  demoneeded'), 'd  demoneeded'),
       
  4039                 ]+(sys.version_info < (2, 5) and [
       
  4040                    (re.compile('.*No module named runpy.*', re.S), ''),
       
  4041                    (re.compile('.*usage: pdb.py scriptfile .*', re.S), ''),
       
  4042                    (re.compile('.*Error: what does not exist.*', re.S), ''),
       
  4043                    ] or [])),
       
  4044             ),
       
  4045 
       
  4046         doctest.DocFileSuite(
       
  4047             'download.txt', 'extends-cache.txt',
       
  4048             setUp=easy_install_SetUp,
       
  4049             tearDown=zc.buildout.testing.buildoutTearDown,
       
  4050             optionflags=doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS,
       
  4051             checker=renormalizing.RENormalizing([
       
  4052                (re.compile(' at -?0x[^>]+'), '<MEM ADDRESS>'),
       
  4053                (re.compile('http://localhost:[0-9]{4,5}/'),
       
  4054                 'http://localhost/'),
       
  4055                (re.compile('[0-9a-f]{32}'), '<MD5 CHECKSUM>'),
       
  4056                zc.buildout.testing.normalize_path,
       
  4057                ]),
       
  4058             ),
       
  4059 
       
  4060         doctest.DocTestSuite(
       
  4061             setUp=easy_install_SetUp,
       
  4062             tearDown=zc.buildout.testing.buildoutTearDown,
       
  4063             checker=renormalizing.RENormalizing([
       
  4064                 zc.buildout.testing.normalize_path,
       
  4065                 zc.buildout.testing.normalize_endings,
       
  4066                 zc.buildout.testing.normalize_script,
       
  4067                 zc.buildout.testing.normalize_egg_py,
       
  4068                 zc.buildout.tests.hide_distribute_additions,
       
  4069                 hide_first_index_page_message,
       
  4070                 (re.compile("buildout: Running \S*setup.py"),
       
  4071                  'buildout: Running setup.py'),
       
  4072                 (re.compile('(setuptools|distribute)-\S+-'),
       
  4073                  'setuptools.egg'),
       
  4074                 (re.compile('zc.buildout-\S+-'),
       
  4075                  'zc.buildout.egg'),
       
  4076                 (re.compile('File "\S+one.py"'),
       
  4077                  'File "one.py"'),
       
  4078                 (re.compile(r'We have a develop egg: (\S+) (\S+)'),
       
  4079                  r'We have a develop egg: \1 V'),
       
  4080                 (re.compile('Picked: (setuptools|distribute) = \S+'),
       
  4081                  'Picked: setuptools = V'),
       
  4082                 (re.compile(r'\\[\\]?'), '/'),
       
  4083                 (re.compile(
       
  4084                     '-q develop -mxN -d "/sample-buildout/develop-eggs'),
       
  4085                     '-q develop -mxN -d /sample-buildout/develop-eggs'
       
  4086                  ),
       
  4087                 (re.compile(r'^[*]...'), '...'),
       
  4088                 # for bug_92891_bootstrap_crashes_with_egg_recipe_in_buildout_section
       
  4089                 (re.compile(r"Unused options for buildout: 'eggs' 'scripts'\."),
       
  4090                  "Unused options for buildout: 'scripts' 'eggs'."),
       
  4091                 (re.compile('distribute'), 'setuptools'),
       
  4092                 # Distribute unzips eggs by default.
       
  4093                 (re.compile('\-  demoneeded'), 'd  demoneeded'),
       
  4094                 ]),
       
  4095             ),
       
  4096         zc.buildout.testselectingpython.test_suite(),
       
  4097         zc.buildout.rmtree.test_suite(),
       
  4098         doctest.DocFileSuite(
       
  4099             'windows.txt',
       
  4100             setUp=zc.buildout.testing.buildoutSetUp,
       
  4101             tearDown=zc.buildout.testing.buildoutTearDown,
       
  4102             checker=renormalizing.RENormalizing([
       
  4103                 zc.buildout.testing.normalize_path,
       
  4104                 zc.buildout.testing.normalize_endings,
       
  4105                 zc.buildout.testing.normalize_script,
       
  4106                 zc.buildout.testing.normalize_egg_py,
       
  4107                 zc.buildout.tests.hide_distribute_additions,
       
  4108                 (re.compile('__buildout_signature__ = recipes-\S+'),
       
  4109                  '__buildout_signature__ = recipes-SSSSSSSSSSS'),
       
  4110                 (re.compile('[-d]  setuptools-\S+[.]egg'), 'setuptools.egg'),
       
  4111                 (re.compile('zc.buildout(-\S+)?[.]egg(-link)?'),
       
  4112                  'zc.buildout.egg'),
       
  4113                 (re.compile('creating \S*setup.cfg'), 'creating setup.cfg'),
       
  4114                 (re.compile('hello\%ssetup' % os.path.sep), 'hello/setup'),
       
  4115                 (re.compile('Picked: (\S+) = \S+'),
       
  4116                  'Picked: \\1 = V.V'),
       
  4117                 (re.compile(r'We have a develop egg: zc.buildout (\S+)'),
       
  4118                  'We have a develop egg: zc.buildout X.X.'),
       
  4119                 (re.compile(r'\\[\\]?'), '/'),
       
  4120                 (re.compile('WindowsError'), 'OSError'),
       
  4121                 (re.compile(r'\[Error 17\] Cannot create a file '
       
  4122                             r'when that file already exists: '),
       
  4123                  '[Errno 17] File exists: '
       
  4124                  ),
       
  4125                 ])
       
  4126             ),
       
  4127         doctest.DocFileSuite(
       
  4128             'testing_bugfix.txt',
       
  4129             checker=renormalizing.RENormalizing([
       
  4130                 # Python 2.7
       
  4131                 (re.compile(
       
  4132                     re.escape(
       
  4133                         'testrunner.logsupport.NullHandler instance at')),
       
  4134                  'testrunner.logsupport.NullHandler object at'),
       
  4135                 (re.compile(re.escape('logging.StreamHandler instance at')),
       
  4136                  'logging.StreamHandler object at'),
       
  4137                 ])
       
  4138             ),
       
  4139     ]
       
  4140 
       
  4141     # adding bootstrap.txt doctest to the suite
       
  4142     # only if bootstrap.py is present
       
  4143     bootstrap_py = os.path.join(
       
  4144        os.path.dirname(
       
  4145           os.path.dirname(
       
  4146              os.path.dirname(
       
  4147                 os.path.dirname(zc.buildout.__file__)
       
  4148                 )
       
  4149              )
       
  4150           ),
       
  4151        'bootstrap', 'bootstrap.py')
       
  4152 
       
  4153     if os.path.exists(bootstrap_py):
       
  4154         test_suite.append(doctest.DocFileSuite(
       
  4155             'bootstrap.txt',
       
  4156             setUp=bootstrapSetup,
       
  4157             tearDown=zc.buildout.testing.buildoutTearDown,
       
  4158             checker=renormalizing.RENormalizing([
       
  4159                 zc.buildout.testing.normalize_path,
       
  4160                 zc.buildout.testing.normalize_endings,
       
  4161                 zc.buildout.testing.normalize_script,
       
  4162                 zc.buildout.testing.normalize_egg_py,
       
  4163                 normalize_bang,
       
  4164                 (re.compile('Downloading.*setuptools.*egg\n'), ''),
       
  4165                 (re.compile('options:'), 'Options:'),
       
  4166                 (re.compile('usage:'), 'Usage:'),
       
  4167                 ]),
       
  4168             ))
       
  4169         test_suite.append(doctest.DocFileSuite(
       
  4170             'virtualenv.txt',
       
  4171             setUp=easy_install_SetUp,
       
  4172             tearDown=zc.buildout.testing.buildoutTearDown,
       
  4173             checker=renormalizing.RENormalizing([
       
  4174                 zc.buildout.testing.normalize_path,
       
  4175                 zc.buildout.testing.normalize_endings,
       
  4176                 zc.buildout.testing.normalize_script,
       
  4177                 zc.buildout.testing.normalize_egg_py,
       
  4178                 zc.buildout.tests.hide_distribute_additions,
       
  4179                 (re.compile('(setuptools|distribute)-\S+-'),
       
  4180                  'setuptools.egg'),
       
  4181                 (re.compile('zc.buildout-\S+-'),
       
  4182                  'zc.buildout.egg'),
       
  4183                 (re.compile(re.escape('#!"/executable_buildout/bin/py"')),
       
  4184                  '#!/executable_buildout/bin/py'), # Windows.
       
  4185                 (re.compile(re.escape('/broken_s/')),
       
  4186                  '/broken_S/'), # Windows.
       
  4187                 ]),
       
  4188             ))
       
  4189 
       
  4190     return unittest.TestSuite(test_suite)