source: pyyaml/trunk/ez_setup.py @ 281

Revision 281, 9.4 KB checked in by xi, 6 years ago (diff)

Added a setuptools installer 'ez_setup.py'.

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