~launchpad-pqm/launchpad/devel

8234.1.2 by Gary Poster
checkpoint: this initial buildout variant has several parts working, including run, start, stop, and harness.
1
#!python
8329.1.4 by Gary Poster
respond to reviews; in particular, add doc.
2
3
# NOTE TO LAUNCHPAD DEVELOPERS: This is a bootstrapping file from the
4
# setuptools project.  It is imported by our setup.py.
5
8357.5.17 by Gary Poster
hack bootstrap.py to take better advantage of our local copies of files; update to newer ez_setup.py
6
#!python
8234.1.2 by Gary Poster
checkpoint: this initial buildout variant has several parts working, including run, start, stop, and harness.
7
"""Bootstrap setuptools installation
8
9
If you want to use setuptools in your package's setup.py, just include this
10
file in the same directory with it, and add this to the top of your setup.py::
11
12
    from ez_setup import use_setuptools
13
    use_setuptools()
14
15
If you want to require a specific version of setuptools, set a download
16
mirror, or use an alternate download directory, you can do so by supplying
17
the appropriate options to ``use_setuptools()``.
18
19
This file can also be run as a script to install or upgrade setuptools.
20
"""
21
import sys
8357.5.17 by Gary Poster
hack bootstrap.py to take better advantage of our local copies of files; update to newer ez_setup.py
22
DEFAULT_VERSION = "0.6c9"
8234.1.2 by Gary Poster
checkpoint: this initial buildout variant has several parts working, including run, start, stop, and harness.
23
DEFAULT_URL     = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3]
24
25
md5_data = {
26
    'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca',
27
    'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb',
28
    'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b',
29
    'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a',
30
    'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618',
31
    'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac',
32
    'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5',
33
    'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4',
34
    'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c',
35
    'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b',
36
    'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27',
37
    'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277',
38
    'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa',
39
    'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e',
40
    'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e',
41
    'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f',
42
    'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2',
43
    'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc',
44
    'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167',
45
    'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64',
46
    'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d',
47
    'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20',
48
    'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab',
49
    'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53',
50
    'setuptools-0.6c7-py2.3.egg': '209fdf9adc3a615e5115b725658e13e2',
51
    'setuptools-0.6c7-py2.4.egg': '5a8f954807d46a0fb67cf1f26c55a82e',
52
    'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372',
53
    'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902',
54
    'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de',
55
    'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b',
8357.5.17 by Gary Poster
hack bootstrap.py to take better advantage of our local copies of files; update to newer ez_setup.py
56
    'setuptools-0.6c9-py2.3.egg': 'a83c4020414807b496e4cfbe08507c03',
57
    'setuptools-0.6c9-py2.4.egg': '260a2be2e5388d66bdaee06abec6342a',
58
    'setuptools-0.6c9-py2.5.egg': 'fe67c3e5a17b12c0e7c541b7ea43a8e6',
59
    'setuptools-0.6c9-py2.6.egg': 'ca37b1ff16fa2ede6e19383e7b59245a',
8234.1.2 by Gary Poster
checkpoint: this initial buildout variant has several parts working, including run, start, stop, and harness.
60
}
61
62
import sys, os
8357.5.17 by Gary Poster
hack bootstrap.py to take better advantage of our local copies of files; update to newer ez_setup.py
63
try: from hashlib import md5
64
except ImportError: from md5 import md5
8234.1.2 by Gary Poster
checkpoint: this initial buildout variant has several parts working, including run, start, stop, and harness.
65
66
def _validate_md5(egg_name, data):
67
    if egg_name in md5_data:
68
        digest = md5(data).hexdigest()
69
        if digest != md5_data[egg_name]:
70
            print >>sys.stderr, (
71
                "md5 validation of %s failed!  (Possible download problem?)"
72
                % egg_name
73
            )
74
            sys.exit(2)
75
    return data
76
77
def use_setuptools(
78
    version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
8357.5.17 by Gary Poster
hack bootstrap.py to take better advantage of our local copies of files; update to newer ez_setup.py
79
    download_delay=15
8234.1.2 by Gary Poster
checkpoint: this initial buildout variant has several parts working, including run, start, stop, and harness.
80
):
81
    """Automatically find/download setuptools and make it available on sys.path
82
83
    `version` should be a valid setuptools version number that is available
84
    as an egg for download under the `download_base` URL (which should end with
85
    a '/').  `to_dir` is the directory where setuptools will be downloaded, if
86
    it is not already available.  If `download_delay` is specified, it should
87
    be the number of seconds that will be paused before initiating a download,
88
    should one be required.  If an older version of setuptools is installed,
89
    this routine will print a message to ``sys.stderr`` and raise SystemExit in
90
    an attempt to abort the calling script.
91
    """
92
    was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules
93
    def do_download():
94
        egg = download_setuptools(version, download_base, to_dir, download_delay)
95
        sys.path.insert(0, egg)
96
        import setuptools; setuptools.bootstrap_install_from = egg
97
    try:
98
        import pkg_resources
99
    except ImportError:
100
        return do_download()       
101
    try:
102
        pkg_resources.require("setuptools>="+version); return
103
    except pkg_resources.VersionConflict, e:
104
        if was_imported:
105
            print >>sys.stderr, (
106
            "The required version of setuptools (>=%s) is not available, and\n"
107
            "can't be installed while this script is running. Please install\n"
108
            " a more recent version first, using 'easy_install -U setuptools'."
109
            "\n\n(Currently using %r)"
110
            ) % (version, e.args[0])
111
            sys.exit(2)
112
        else:
113
            del pkg_resources, sys.modules['pkg_resources']    # reload ok
114
            return do_download()
115
    except pkg_resources.DistributionNotFound:
116
        return do_download()
117
118
def download_setuptools(
119
    version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
120
    delay = 15
121
):
122
    """Download setuptools from a specified location and return its filename
123
124
    `version` should be a valid setuptools version number that is available
125
    as an egg for download under the `download_base` URL (which should end
126
    with a '/'). `to_dir` is the directory where the egg will be downloaded.
127
    `delay` is the number of seconds to pause before an actual download attempt.
128
    """
129
    import urllib2, shutil
130
    egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
131
    url = download_base + egg_name
132
    saveto = os.path.join(to_dir, egg_name)
133
    src = dst = None
134
    if not os.path.exists(saveto):  # Avoid repeated downloads
135
        try:
136
            from distutils import log
137
            if delay:
138
                log.warn("""
139
---------------------------------------------------------------------------
140
This script requires setuptools version %s to run (even to display
141
help).  I will attempt to download it for you (from
142
%s), but
143
you may need to enable firewall access for this script first.
144
I will start the download in %d seconds.
145
146
(Note: if this machine does not have network access, please obtain the file
147
148
   %s
149
150
and place it in this directory before rerunning this script.)
151
---------------------------------------------------------------------------""",
152
                    version, download_base, delay, url
153
                ); from time import sleep; sleep(delay)
154
            log.warn("Downloading %s", url)
155
            src = urllib2.urlopen(url)
156
            # Read/write all in one block, so we don't create a corrupt file
157
            # if the download is interrupted.
158
            data = _validate_md5(egg_name, src.read())
159
            dst = open(saveto,"wb"); dst.write(data)
160
        finally:
161
            if src: src.close()
162
            if dst: dst.close()
163
    return os.path.realpath(saveto)
164
8357.5.17 by Gary Poster
hack bootstrap.py to take better advantage of our local copies of files; update to newer ez_setup.py
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
8234.1.2 by Gary Poster
checkpoint: this initial buildout variant has several parts working, including run, start, stop, and harness.
200
def main(argv, version=DEFAULT_VERSION):
201
    """Install or upgrade setuptools and EasyInstall"""
202
    try:
203
        import setuptools
204
    except ImportError:
205
        egg = None
206
        try:
207
            egg = download_setuptools(version, delay=0)
208
            sys.path.insert(0,egg)
209
            from setuptools.command.easy_install import main
210
            return main(list(argv)+[egg])   # we're done here
211
        finally:
212
            if egg and os.path.exists(egg):
213
                os.unlink(egg)
214
    else:
215
        if setuptools.__version__ == '0.0.1':
216
            print >>sys.stderr, (
217
            "You have an obsolete version of setuptools installed.  Please\n"
218
            "remove it from your system entirely before rerunning this script."
219
            )
220
            sys.exit(2)
221
222
    req = "setuptools>="+version
223
    import pkg_resources
224
    try:
225
        pkg_resources.require(req)
226
    except pkg_resources.VersionConflict:
227
        try:
228
            from setuptools.command.easy_install import main
229
        except ImportError:
230
            from easy_install import main
231
        main(list(argv)+[download_setuptools(delay=0)])
232
        sys.exit(0) # try to force an exit
233
    else:
234
        if argv:
235
            from setuptools.command.easy_install import main
236
            main(argv)
237
        else:
238
            print "Setuptools version",version,"or greater has been installed."
239
            print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
240
241
def update_md5(filenames):
242
    """Update our built-in md5 registry"""
243
244
    import re
245
246
    for name in filenames:
247
        base = os.path.basename(name)
248
        f = open(name,'rb')
249
        md5_data[base] = md5(f.read()).hexdigest()
250
        f.close()
251
252
    data = ["    %r: %r,\n" % it for it in md5_data.items()]
253
    data.sort()
254
    repl = "".join(data)
255
256
    import inspect
257
    srcfile = inspect.getsourcefile(sys.modules[__name__])
258
    f = open(srcfile, 'rb'); src = f.read(); f.close()
259
260
    match = re.search("\nmd5_data = {\n([^}]+)}", src)
261
    if not match:
262
        print >>sys.stderr, "Internal error!"
263
        sys.exit(2)
264
265
    src = src[:match.start(1)] + repl + src[match.end(1):]
266
    f = open(srcfile,'w')
267
    f.write(src)
268
    f.close()
269
270
271
if __name__=='__main__':
272
    if len(sys.argv)>2 and sys.argv[1]=='--md5update':
273
        update_md5(sys.argv[2:])
274
    else:
275
        main(sys.argv[1:])
276
277
278
279
280