PageRenderTime 105ms CodeModel.GetById 50ms app.highlight 37ms RepoModel.GetById 14ms app.codeStats 0ms

/ez_setup.py

https://bitbucket.org/bbangert/kai/
Python | 272 lines | 220 code | 44 blank | 8 comment | 15 complexity | 94ce3ba3f5933e3915e999c26da9563b MD5 | raw file
  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.6c8"
 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}
 52
 53import sys, os
 54
 55def _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
 68def 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    """
 83    was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules
 84    def do_download():
 85        egg = download_setuptools(version, download_base, to_dir, download_delay)
 86        sys.path.insert(0, egg)
 87        import setuptools; setuptools.bootstrap_install_from = egg
 88    try:
 89        import pkg_resources
 90    except ImportError:
 91        return do_download()       
 92    try:
 93        pkg_resources.require("setuptools>="+version); return
 94    except pkg_resources.VersionConflict, e:
 95        if was_imported:
 96            print >>sys.stderr, (
 97            "The required version of setuptools (>=%s) is not available, and\n"
 98            "can't be installed while this script is running. Please install\n"
 99            " a more recent version first, using 'easy_install -U setuptools'."
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()
108
109def 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---------------------------------------------------------------------------
131This script requires setuptools version %s to run (even to display
132help).  I will attempt to download it for you (from
133%s), but
134you may need to enable firewall access for this script first.
135I 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
141and 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
156
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
191def main(argv, version=DEFAULT_VERSION):
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':
207            print >>sys.stderr, (
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)
212
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
232def 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
263if __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