1#!python
2
3# This file was obtained from:
4#   http://peak.telecommunity.com/dist/ez_setup.py
5# on 2009/4/17.
6
7"""Bootstrap setuptools installation
8
9If you want to use setuptools in your package's setup.py, just include this
10file 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
15If you want to require a specific version of setuptools, set a download
16mirror, or use an alternate download directory, you can do so by supplying
17the appropriate options to ``use_setuptools()``.
18
19This file can also be run as a script to install or upgrade setuptools.
20"""
21import sys
22DEFAULT_VERSION = "0.6c9"
23DEFAULT_URL     = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3]
24
25md5_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',
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',
60}
61
62import sys, os
63try: from hashlib import md5
64except ImportError: from md5 import md5
65
66def _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
77def use_setuptools(
78    version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
79    download_delay=15
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
118def 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---------------------------------------------------------------------------
140This script requires setuptools version %s to run (even to display
141help).  I will attempt to download it for you (from
142%s), but
143you may need to enable firewall access for this script first.
144I 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
150and 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
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
200def 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
241def 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
271if __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
281
282