bootstrap.py
branchZTK-1.1
changeset 251 bb37ceec4298
parent 0 712d20d2751e
child 275 2027d75ae843
equal deleted inserted replaced
250:16a535e0eb92 251:bb37ceec4298
     1 ##############################################################################
     1 ##############################################################################
     2 #
     2 #
     3 # Copyright (c) 2006 Zope Corporation and Contributors.
     3 # Copyright (c) 2006 Zope Foundation and Contributors.
     4 # All Rights Reserved.
     4 # All Rights Reserved.
     5 #
     5 #
     6 # This software is subject to the provisions of the Zope Public License,
     6 # This software is subject to the provisions of the Zope Public License,
     7 # Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
     7 # Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
     8 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
     8 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
    14 """Bootstrap a buildout-based project
    14 """Bootstrap a buildout-based project
    15 
    15 
    16 Simply run this script in a directory containing a buildout.cfg.
    16 Simply run this script in a directory containing a buildout.cfg.
    17 The script accepts buildout command-line options, so you can
    17 The script accepts buildout command-line options, so you can
    18 use the -c option to specify an alternate configuration file.
    18 use the -c option to specify an alternate configuration file.
    19 
       
    20 $Id$
       
    21 """
    19 """
    22 
    20 
    23 import os, shutil, sys, tempfile, urllib2
    21 import os
       
    22 import shutil
       
    23 import sys
       
    24 import tempfile
       
    25 
       
    26 from optparse import OptionParser
    24 
    27 
    25 tmpeggs = tempfile.mkdtemp()
    28 tmpeggs = tempfile.mkdtemp()
    26 
    29 
       
    30 usage = '''\
       
    31 [DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
       
    32 
       
    33 Bootstraps a buildout-based project.
       
    34 
       
    35 Simply run this script in a directory containing a buildout.cfg, using the
       
    36 Python that you want bin/buildout to use.
       
    37 
       
    38 Note that by using --find-links to point to local resources, you can keep 
       
    39 this script from going over the network.
       
    40 '''
       
    41 
       
    42 parser = OptionParser(usage=usage)
       
    43 parser.add_option("-v", "--version", help="use a specific zc.buildout version")
       
    44 
       
    45 parser.add_option("-t", "--accept-buildout-test-releases",
       
    46                   dest='accept_buildout_test_releases',
       
    47                   action="store_true", default=False,
       
    48                   help=("Normally, if you do not specify a --version, the "
       
    49                         "bootstrap script and buildout gets the newest "
       
    50                         "*final* versions of zc.buildout and its recipes and "
       
    51                         "extensions for you.  If you use this flag, "
       
    52                         "bootstrap and buildout will get the newest releases "
       
    53                         "even if they are alphas or betas."))
       
    54 parser.add_option("-c", "--config-file",
       
    55                   help=("Specify the path to the buildout configuration "
       
    56                         "file to be used."))
       
    57 parser.add_option("-f", "--find-links",
       
    58                   help=("Specify a URL to search for buildout releases"))
       
    59 parser.add_option("--allow-site-packages",
       
    60                   action="store_true", default=False,
       
    61                   help=("Let bootstrap.py use existing site packages"))
       
    62 
       
    63 
       
    64 options, args = parser.parse_args()
       
    65 
       
    66 ######################################################################
       
    67 # load/install setuptools
       
    68 
       
    69 try:
       
    70     if options.allow_site_packages:
       
    71         import setuptools
       
    72         import pkg_resources
       
    73     from urllib.request import urlopen
       
    74 except ImportError:
       
    75     from urllib2 import urlopen
       
    76 
    27 ez = {}
    77 ez = {}
    28 exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
    78 exec(urlopen('https://bootstrap.pypa.io/ez_setup.py').read(), ez)
    29                      ).read() in ez
       
    30 ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
       
    31 
    79 
       
    80 if not options.allow_site_packages:
       
    81     # ez_setup imports site, which adds site packages
       
    82     # this will remove them from the path to ensure that incompatible versions 
       
    83     # of setuptools are not in the path
       
    84     import site
       
    85     # inside a virtualenv, there is no 'getsitepackages'. 
       
    86     # We can't remove these reliably
       
    87     if hasattr(site, 'getsitepackages'):
       
    88         for sitepackage_path in site.getsitepackages():
       
    89             sys.path[:] = [x for x in sys.path if sitepackage_path not in x]
       
    90 
       
    91 setup_args = dict(to_dir=tmpeggs, download_delay=0)
       
    92 ez['use_setuptools'](**setup_args)
       
    93 import setuptools
    32 import pkg_resources
    94 import pkg_resources
    33 
    95 
    34 cmd = 'from setuptools.command.easy_install import main; main()'
    96 # This does not (always?) update the default working set.  We will
    35 if sys.platform == 'win32':
    97 # do it.
    36     cmd = '"%s"' % cmd # work around spawn lamosity on windows
    98 for path in sys.path:
       
    99     if path not in pkg_resources.working_set.entries:
       
   100         pkg_resources.working_set.add_entry(path)
       
   101 
       
   102 ######################################################################
       
   103 # Install buildout
    37 
   104 
    38 ws = pkg_resources.working_set
   105 ws = pkg_resources.working_set
    39 assert os.spawnle(
   106 
    40     os.P_WAIT, sys.executable, sys.executable,
   107 cmd = [sys.executable, '-c',
    41     '-c', cmd, '-mqNxd', tmpeggs, 'zc.buildout',
   108        'from setuptools.command.easy_install import main; main()',
    42     dict(os.environ,
   109        '-mZqNxd', tmpeggs]
    43          PYTHONPATH=
   110 
    44          ws.find(pkg_resources.Requirement.parse('setuptools')).location
   111 find_links = os.environ.get(
    45          ),
   112     'bootstrap-testing-find-links',
    46     ) == 0
   113     options.find_links or
       
   114     ('http://downloads.buildout.org/'
       
   115      if options.accept_buildout_test_releases else None)
       
   116     )
       
   117 if find_links:
       
   118     cmd.extend(['-f', find_links])
       
   119 
       
   120 setuptools_path = ws.find(
       
   121     pkg_resources.Requirement.parse('setuptools')).location
       
   122 
       
   123 requirement = 'zc.buildout'
       
   124 version = options.version
       
   125 if version is None and not options.accept_buildout_test_releases:
       
   126     # Figure out the most recent final version of zc.buildout.
       
   127     import setuptools.package_index
       
   128     _final_parts = '*final-', '*final'
       
   129 
       
   130     def _final_version(parsed_version):
       
   131         for part in parsed_version:
       
   132             if (part[:1] == '*') and (part not in _final_parts):
       
   133                 return False
       
   134         return True
       
   135     index = setuptools.package_index.PackageIndex(
       
   136         search_path=[setuptools_path])
       
   137     if find_links:
       
   138         index.add_find_links((find_links,))
       
   139     req = pkg_resources.Requirement.parse(requirement)
       
   140     if index.obtain(req) is not None:
       
   141         best = []
       
   142         bestv = None
       
   143         for dist in index[req.project_name]:
       
   144             distv = dist.parsed_version
       
   145             if _final_version(distv):
       
   146                 if bestv is None or distv > bestv:
       
   147                     best = [dist]
       
   148                     bestv = distv
       
   149                 elif distv == bestv:
       
   150                     best.append(dist)
       
   151         if best:
       
   152             best.sort()
       
   153             version = best[-1].version
       
   154 if version:
       
   155     requirement = '=='.join((requirement, version))
       
   156 cmd.append(requirement)
       
   157 
       
   158 import subprocess
       
   159 if subprocess.call(cmd, env=dict(os.environ, PYTHONPATH=setuptools_path)) != 0:
       
   160     raise Exception(
       
   161         "Failed to execute command:\n%s" % repr(cmd)[1:-1])
       
   162 
       
   163 ######################################################################
       
   164 # Import and run buildout
    47 
   165 
    48 ws.add_entry(tmpeggs)
   166 ws.add_entry(tmpeggs)
    49 ws.require('zc.buildout')
   167 ws.require(requirement)
    50 import zc.buildout.buildout
   168 import zc.buildout.buildout
    51 zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap'])
   169 
       
   170 if not [a for a in args if '=' not in a]:
       
   171     args.append('bootstrap')
       
   172 
       
   173 # if -c was provided, we push it back into args for buildout' main function
       
   174 if options.config_file is not None:
       
   175     args[0:0] = ['-c', options.config_file]
       
   176 
       
   177 zc.buildout.buildout.main(args)
    52 shutil.rmtree(tmpeggs)
   178 shutil.rmtree(tmpeggs)
    53