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