Project

General

Profile

Download (7.29 KB) Statistics
| Branch: | Tag: | Revision:

root / bootstrap.py

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

    
21
import os
22
import shutil
23
import sys
24
import tempfile
25

    
26
from optparse import OptionParser
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 --buildout-version, "
53
                        "the 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)