Completed
Push — master ( aae51d...35b80c )
by Daniel
01:56
created

_final_version()   B

Complexity

Conditions 5

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
c 1
b 0
f 0
dl 0
loc 9
rs 8.5454
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
tmpeggs = tempfile.mkdtemp()
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
parser.add_option("--setuptools-version",
63
                  help="use a specific setuptools version")
64
65
66
options, args = parser.parse_args()
67
68
######################################################################
69
# load/install setuptools
70
71
try:
72
    if options.allow_site_packages:
73
        import setuptools
74
        import pkg_resources
75
    from urllib.request import urlopen
76
except ImportError:
77
    from urllib2 import urlopen
78
79
ez = {}
80
exec(urlopen('https://bootstrap.pypa.io/ez_setup.py').read(), ez)
81
82
if not options.allow_site_packages:
83
    # ez_setup imports site, which adds site packages
84
    # this will remove them from the path to ensure that incompatible versions
85
    # of setuptools are not in the path
86
    import site
87
    # inside a virtualenv, there is no 'getsitepackages'.
88
    # We can't remove these reliably
89
    if hasattr(site, 'getsitepackages'):
90
        for sitepackage_path in site.getsitepackages():
91
            sys.path[:] = [x for x in sys.path if sitepackage_path not in x]
92
93
setup_args = dict(to_dir=tmpeggs, download_delay=0)
94
95
if options.setuptools_version is not None:
96
    setup_args['version'] = options.setuptools_version
97
98
ez['use_setuptools'](**setup_args)
99
import setuptools
100
import pkg_resources
101
102
# This does not (always?) update the default working set.  We will
103
# do it.
104
for path in sys.path:
105
    if path not in pkg_resources.working_set.entries:
106
        pkg_resources.working_set.add_entry(path)
107
108
######################################################################
109
# Install buildout
110
111
ws = pkg_resources.working_set
112
113
cmd = [sys.executable, '-c',
114
       'from setuptools.command.easy_install import main; main()',
115
       '-mZqNxd', tmpeggs]
116
117
find_links = os.environ.get(
118
    'bootstrap-testing-find-links',
119
    options.find_links or
120
    ('http://downloads.buildout.org/'
121
     if options.accept_buildout_test_releases else None)
122
    )
123
if find_links:
124
    cmd.extend(['-f', find_links])
125
126
setuptools_path = ws.find(
127
    pkg_resources.Requirement.parse('setuptools')).location
128
129
requirement = 'zc.buildout'
130
version = options.version
131
if version is None and not options.accept_buildout_test_releases:
132
    # Figure out the most recent final version of zc.buildout.
133
    import setuptools.package_index
134
    _final_parts = '*final-', '*final'
135
136
    def _final_version(parsed_version):
137
        try:
138
            return not parsed_version.is_prerelease
139
        except AttributeError:
140
            # Older setuptools
141
            for part in parsed_version:
142
                if (part[:1] == '*') and (part not in _final_parts):
143
                    return False
144
            return True
145
146
    index = setuptools.package_index.PackageIndex(
147
        search_path=[setuptools_path])
148
    if find_links:
149
        index.add_find_links((find_links,))
150
    req = pkg_resources.Requirement.parse(requirement)
151
    if index.obtain(req) is not None:
152
        best = []
153
        bestv = None
154
        for dist in index[req.project_name]:
155
            distv = dist.parsed_version
156
            if _final_version(distv):
157
                if bestv is None or distv > bestv:
158
                    best = [dist]
159
                    bestv = distv
160
                elif distv == bestv:
161
                    best.append(dist)
162
        if best:
163
            best.sort()
164
            version = best[-1].version
165
if version:
166
    requirement = '=='.join((requirement, version))
167
cmd.append(requirement)
168
169
import subprocess
170
if subprocess.call(cmd, env=dict(os.environ, PYTHONPATH=setuptools_path)) != 0:
171
    raise Exception(
172
        "Failed to execute command:\n%s" % repr(cmd)[1:-1])
173
174
######################################################################
175
# Import and run buildout
176
177
ws.add_entry(tmpeggs)
178
ws.require(requirement)
179
import zc.buildout.buildout
180
181
if not [a for a in args if '=' not in a]:
182
    args.append('bootstrap')
183
184
# if -c was provided, we push it back into args for buildout' main function
185
if options.config_file is not None:
186
    args[0:0] = ['-c', options.config_file]
187
188
zc.buildout.buildout.main(args)
189
shutil.rmtree(tmpeggs)
190