]> git.rkrishnan.org Git - tahoe-lafs/zfec.git/blob - zfec/ez_setup.py
setup: remove bundled zipped egg of zetuptoolz-0.6c12dev (we're going to upgrade...
[tahoe-lafs/zfec.git] / zfec / ez_setup.py
1 #!/usr/bin/env 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 os, sys
17 DEFAULT_VERSION = "0.6c12dev"
18 DEFAULT_DIR     = "misc/dependencies/"
19 DEFAULT_URL     = "file:"+DEFAULT_DIR
20
21 md5_data = {
22     'setuptools-0.6c12dev.egg': '770da1c9e5446cf04273f0f1cdb8c09a',
23 }
24
25 import sys, os
26
27 def _validate_md5(egg_name, data):
28     if egg_name in md5_data:
29         from md5 import md5
30         digest = md5(data).hexdigest()
31         if digest != md5_data[egg_name]:
32             print >>sys.stderr, (
33                 "md5 validation of %s failed!  (Possible download problem?)"
34                 % egg_name
35             )
36             sys.exit(2)
37     return data
38
39
40 def use_setuptools(
41     version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
42     min_version="0.6c12dev", download_delay=15
43 ):
44     """Automatically find/download setuptools and make it available on sys.path
45
46     `version` should be a valid setuptools version number that is available as
47     an egg for download under the `download_base` URL (which should end with a
48     '/').  `to_dir` is the directory where setuptools will be downloaded, if it
49     is not already available.  If `download_delay` is specified, it is the
50     number of seconds that will be paused before initiating a download, should
51     one be required.  If an older version of setuptools is installed but hasn't
52     been imported yet, this routine will go ahead and install the required
53     version and then use it.  If an older version of setuptools has already been
54     imported then we can't upgrade to the new one, so this routine will print a
55     message to ``sys.stderr`` and raise SystemExit in an attempt to abort the
56     calling script.
57     """
58     if min_version is None:
59         min_version = version
60
61     was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules
62     def do_download():
63         egg = download_setuptools(version, download_base, to_dir, download_delay)
64         sys.path.insert(0, egg)
65         import setuptools; setuptools.bootstrap_install_from = egg
66     try:
67         import pkg_resources
68     except ImportError:
69         return do_download()       
70     try:
71         pkg_resources.require("setuptools>="+min_version); return
72     except pkg_resources.VersionConflict, e:
73         if was_imported:
74             print >>sys.stderr, (
75             "The required version of setuptools (>=%s) is not available, and\n"
76             "can't be installed while this script is running. Please install\n"
77             " a more recent version first, using 'easy_install -U setuptools'."
78             "\n\n(Currently using %r)\n"
79             "Proceeding to attempt to build with the current version...\n"
80             ) % (min_version, e.args[0])
81             return
82         else:
83             del pkg_resources, sys.modules['pkg_resources']    # reload ok
84             return do_download()
85     except pkg_resources.DistributionNotFound:
86         return do_download()
87
88 def download_setuptools(
89     version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
90     delay = 15
91 ):
92     """Download setuptools from a specified location and return its filename
93
94     `version` should be a valid setuptools version number that is available
95     as an egg for download under the `download_base` URL (which should end
96     with a '/'). `to_dir` is the directory where the egg will be downloaded.
97     `delay` is the number of seconds to pause before an actual download attempt.
98     """
99     import urllib2, shutil
100     egg_name = "setuptools-%s.egg" % (version,)
101     url = download_base + egg_name
102     saveto = os.path.join(to_dir, egg_name)
103     src = dst = None
104     if not os.path.exists(saveto):  # Avoid repeated downloads
105         try:
106             from distutils import log
107             if delay:
108                 log.warn("""
109 ---------------------------------------------------------------------------
110 This script requires setuptools version %s to run (even to display
111 help).  I will attempt to download it for you (from
112 %s), but
113 you may need to enable firewall access for this script first.
114 I will start the download in %d seconds.
115
116 (Note: if this machine does not have network access, please obtain the file
117
118    %s
119
120 and place it in this directory before rerunning this script.)
121 ---------------------------------------------------------------------------""",
122                     version, download_base, delay, url
123                 ); from time import sleep; sleep(delay)
124             log.warn("Downloading %s", url)
125             src = urllib2.urlopen(url)
126             # Read/write all in one block, so we don't create a corrupt file
127             # if the download is interrupted.
128             data = _validate_md5(egg_name, src.read())
129             dst = open(saveto,"wb"); dst.write(data)
130         finally:
131             if src: src.close()
132             if dst: dst.close()
133     return os.path.realpath(saveto)
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170 def main(argv, version=DEFAULT_VERSION):
171     """Install or upgrade setuptools and EasyInstall"""
172     try:
173         import setuptools
174     except ImportError:
175         egg = None
176         try:
177             egg = download_setuptools(version, delay=0)
178             sys.path.insert(0,egg)
179             from setuptools.command.easy_install import main
180             return main(list(argv)+[egg])   # we're done here
181         finally:
182             if egg and os.path.exists(egg):
183                 os.unlink(egg)
184     else:
185         if setuptools.__version__ == '0.0.1':
186             print >>sys.stderr, (
187             "You have an obsolete version of setuptools installed.  Please\n"
188             "remove it from your system entirely before rerunning this script."
189             )
190             sys.exit(2)
191
192     req = "setuptools>="+version
193     import pkg_resources
194     try:
195         pkg_resources.require(req)
196     except pkg_resources.VersionConflict:
197         try:
198             from setuptools.command.easy_install import main
199         except ImportError:
200             from easy_install import main
201         main(list(argv)+[download_setuptools(delay=0)])
202         sys.exit(0) # try to force an exit
203     else:
204         if argv:
205             from setuptools.command.easy_install import main
206             main(argv)
207         else:
208             print "Setuptools version",version,"or greater has been installed."
209             print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
210
211 def update_md5(filenames):
212     """Update our built-in md5 registry"""
213
214     import re
215     from md5 import md5
216
217     for name in filenames:
218         base = os.path.basename(name)
219         f = open(name,'rb')
220         md5_data[base] = md5(f.read()).hexdigest()
221         f.close()
222
223     data = ["    %r: %r,\n" % it for it in md5_data.items()]
224     data.sort()
225     repl = "".join(data)
226
227     import inspect
228     srcfile = inspect.getsourcefile(sys.modules[__name__])
229     f = open(srcfile, 'rb'); src = f.read(); f.close()
230
231     match = re.search("\nmd5_data = {\n([^}]+)}", src)
232     if not match:
233         print >>sys.stderr, "Internal error!"
234         sys.exit(2)
235
236     src = src[:match.start(1)] + repl + src[match.end(1):]
237     f = open(srcfile,'w')
238     f.write(src)
239     f.close()
240
241
242 if __name__=='__main__':
243     if len(sys.argv)>2 and sys.argv[1]=='--md5update':
244         update_md5(sys.argv[2:])
245     else:
246         main(sys.argv[1:])
247
248
249
250
251