~lamont/maas/bug-1599223-2.0

4489.5.6 by Gavin Panella
Begin migration to Python 3.5.
1
##############################################################################
2
#
3
# Copyright (c) 2006 Zope Foundation and Contributors.
4
# All Rights Reserved.
5
#
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.
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
"""Bootstrap a buildout-based project
15
16
Simply run this script in a directory containing a buildout.cfg.
17
The script accepts buildout command-line options, so you can
18
use the -c option to specify an alternate configuration file.
19
"""
20
4489.6.3 by Blake Rouse
Fix review.
21
from optparse import OptionParser
4489.5.6 by Gavin Panella
Begin migration to Python 3.5.
22
import os
23
import shutil
24
import sys
25
import tempfile
26
27
28
__version__ = '2015-07-01'
29
# See zc.buildout's changelog if this version is up to date.
30
31
tmpeggs = tempfile.mkdtemp(prefix='bootstrap-')
32
33
usage = '''\
34
[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
35
36
Bootstraps a buildout-based project.
37
38
Simply run this script in a directory containing a buildout.cfg, using the
39
Python that you want bin/buildout to use.
40
41
Note that by using --find-links to point to local resources, you can keep
42
this script from going over the network.
43
'''
44
45
parser = OptionParser(usage=usage)
46
parser.add_option("--version",
47
                  action="store_true", default=False,
48
                  help=("Return bootstrap.py version."))
49
parser.add_option("-t", "--accept-buildout-test-releases",
50
                  dest='accept_buildout_test_releases',
51
                  action="store_true", default=False,
52
                  help=("Normally, if you do not specify a --version, the "
53
                        "bootstrap script and buildout gets the newest "
54
                        "*final* versions of zc.buildout and its recipes and "
55
                        "extensions for you.  If you use this flag, "
56
                        "bootstrap and buildout will get the newest releases "
57
                        "even if they are alphas or betas."))
58
parser.add_option("-c", "--config-file",
59
                  help=("Specify the path to the buildout configuration "
60
                        "file to be used."))
61
parser.add_option("-f", "--find-links",
62
                  help=("Specify a URL to search for buildout releases"))
63
parser.add_option("--allow-site-packages",
64
                  action="store_true", default=False,
65
                  help=("Let bootstrap.py use existing site packages"))
66
parser.add_option("--buildout-version",
67
                  help="Use a specific zc.buildout version")
68
parser.add_option("--setuptools-version",
69
                  help="Use a specific setuptools version")
70
parser.add_option("--setuptools-to-dir",
71
                  help=("Allow for re-use of existing directory of "
72
                        "setuptools versions"))
73
74
options, args = parser.parse_args()
75
if options.version:
76
    print("bootstrap.py version %s" % __version__)
77
    sys.exit(0)
78
79
80
######################################################################
81
# load/install setuptools
82
83
try:
84
    from urllib.request import urlopen
85
except ImportError:
86
    from urllib2 import urlopen
87
88
ez = {}
89
if os.path.exists('ez_setup.py'):
90
    exec(open('ez_setup.py').read(), ez)
91
else:
92
    exec(urlopen('https://bootstrap.pypa.io/ez_setup.py').read(), ez)
93
94
if not options.allow_site_packages:
95
    # ez_setup imports site, which adds site packages
96
    # this will remove them from the path to ensure that incompatible versions
97
    # of setuptools are not in the path
98
    import site
99
    # inside a virtualenv, there is no 'getsitepackages'.
100
    # We can't remove these reliably
101
    if hasattr(site, 'getsitepackages'):
102
        for sitepackage_path in site.getsitepackages():
103
            # Strip all site-packages directories from sys.path that
104
            # are not sys.prefix; this is because on Windows
105
            # sys.prefix is a site-package directory.
106
            if sitepackage_path != sys.prefix:
107
                sys.path[:] = [x for x in sys.path
108
                               if sitepackage_path not in x]
109
110
setup_args = dict(to_dir=tmpeggs, download_delay=0)
111
112
if options.setuptools_version is not None:
113
    setup_args['version'] = options.setuptools_version
114
if options.setuptools_to_dir is not None:
115
    setup_args['to_dir'] = options.setuptools_to_dir
116
117
ez['use_setuptools'](**setup_args)
118
import setuptools
119
import pkg_resources
120
121
# This does not (always?) update the default working set.  We will
122
# do it.
123
for path in sys.path:
124
    if path not in pkg_resources.working_set.entries:
125
        pkg_resources.working_set.add_entry(path)
126
127
######################################################################
128
# Install buildout
129
130
ws = pkg_resources.working_set
131
132
setuptools_path = ws.find(
133
    pkg_resources.Requirement.parse('setuptools')).location
134
135
# Fix sys.path here as easy_install.pth added before PYTHONPATH
136
cmd = [sys.executable, '-c',
137
       'import sys; sys.path[0:0] = [%r]; ' % setuptools_path +
138
       'from setuptools.command.easy_install import main; main()',
139
       '-mZqNxd', tmpeggs]
140
141
find_links = os.environ.get(
142
    'bootstrap-testing-find-links',
143
    options.find_links or
144
    ('http://downloads.buildout.org/'
145
     if options.accept_buildout_test_releases else None)
146
    )
147
if find_links:
148
    cmd.extend(['-f', find_links])
149
150
requirement = 'zc.buildout'
151
version = options.buildout_version
152
if version is None and not options.accept_buildout_test_releases:
153
    # Figure out the most recent final version of zc.buildout.
154
    import setuptools.package_index
155
    _final_parts = '*final-', '*final'
156
157
    def _final_version(parsed_version):
158
        try:
159
            return not parsed_version.is_prerelease
160
        except AttributeError:
161
            # Older setuptools
162
            for part in parsed_version:
163
                if (part[:1] == '*') and (part not in _final_parts):
164
                    return False
165
            return True
166
167
    index = setuptools.package_index.PackageIndex(
168
        search_path=[setuptools_path])
169
    if find_links:
170
        index.add_find_links((find_links,))
171
    req = pkg_resources.Requirement.parse(requirement)
172
    if index.obtain(req) is not None:
173
        best = []
174
        bestv = None
175
        for dist in index[req.project_name]:
176
            distv = dist.parsed_version
177
            if _final_version(distv):
178
                if bestv is None or distv > bestv:
179
                    best = [dist]
180
                    bestv = distv
181
                elif distv == bestv:
182
                    best.append(dist)
183
        if best:
184
            best.sort()
185
            version = best[-1].version
186
if version:
187
    requirement = '=='.join((requirement, version))
188
cmd.append(requirement)
189
190
import subprocess
191
if subprocess.call(cmd) != 0:
192
    raise Exception(
193
        "Failed to execute command:\n%s" % repr(cmd)[1:-1])
194
195
######################################################################
196
# Import and run buildout
197
198
ws.add_entry(tmpeggs)
199
ws.require(requirement)
200
import zc.buildout.buildout
201
202
if not [a for a in args if '=' not in a]:
203
    args.append('bootstrap')
204
205
# if -c was provided, we push it back into args for buildout' main function
206
if options.config_file is not None:
207
    args[0:0] = ['-c', options.config_file]
208
209
zc.buildout.buildout.main(args)
210
shutil.rmtree(tmpeggs)