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