Size: 13453
Comment:
|
Size: 9990
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 1: | Line 1: |
#!/usr/bin/env python # -*- coding: iso-8859-1 -*- |
#!python """Bootstrap setuptools installation If you want to use setuptools in your package's setup.py, just include this file in the same directory with it, and add this to the top of your setup.py:: from ez_setup import use_setuptools use_setuptools() If you want to require a specific version of setuptools, set a download mirror, or use an alternate download directory, you can do so by supplying the appropriate options to ``use_setuptools()``. This file can also be run as a script to install or upgrade setuptools. |
Line 4: | Line 16: |
MoinMoin installer @copyright: 2001-2005 by Jürgen Hermann <jh@web.de>, 2006-2007 by MoinMoin:ThomasWaldmann @license: GNU GPL, see COPYING for details. """ import os, sys, glob import distutils from distutils.core import setup from distutils.command.build_scripts import build_scripts from MoinMoin.version import release, revision # we need this for distutils from python 2.3 compatibility, python 2.4 has the # 'package_data' keyword to the 'setup' function to install data in packages # see http://wiki.python.org/moin/DistutilsInstallDataScattered from distutils.command.install_data import install_data class smart_install_data(install_data): def run(self): i18n_data_files = [(target, files) for (target, files) in self.data_files if target.startswith('MoinMoin/i18n')] share_data_files = [(target, files) for (target, files) in self.data_files if target.startswith('share/moin')] # first install the share/moin stuff: self.data_files = share_data_files install_data.run(self) # now we need to install the *.po files to the package dir: # need to change self.install_dir to the library dir install_cmd = self.get_finalized_command('install') self.install_dir = getattr(install_cmd, 'install_lib') self.data_files = i18n_data_files return install_data.run(self) ############################################################################# ### Helpers ############################################################################# def isbad(name): """ Whether name should not be installed """ return (name.startswith('.') or name.startswith('#') or name.endswith('.pickle') or name == 'CVS') def isgood(name): """ Whether name should be installed """ return not isbad(name) def makeDataFiles(prefix, dir): """ Create distutils data_files structure from dir distutil will copy all file rooted under dir into prefix, excluding dir itself, just like 'ditto src dst' works, and unlike 'cp -r src dst, which copy src into dst'. Typical usage: # install the contents of 'wiki' under sys.prefix+'share/moin' data_files = makeDataFiles('share/moin', 'wiki') For this directory structure: root file1 file2 dir file subdir file makeDataFiles('prefix', 'root') will create this distutil data_files structure: [('prefix', ['file1', 'file2']), ('prefix/dir', ['file']), ('prefix/dir/subdir', ['file'])] |
import sys DEFAULT_VERSION = "0.6c9" DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3] md5_data = { 'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca', 'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb', 'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b', 'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a', 'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618', 'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac', 'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5', 'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4', 'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c', 'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b', 'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27', 'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277', 'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa', 'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e', 'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e', 'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f', 'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2', 'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc', 'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167', 'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64', 'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d', 'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20', 'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab', 'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53', 'setuptools-0.6c7-py2.3.egg': '209fdf9adc3a615e5115b725658e13e2', 'setuptools-0.6c7-py2.4.egg': '5a8f954807d46a0fb67cf1f26c55a82e', 'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372', 'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902', 'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de', 'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b', 'setuptools-0.6c9-py2.3.egg': 'a83c4020414807b496e4cfbe08507c03', 'setuptools-0.6c9-py2.4.egg': '260a2be2e5388d66bdaee06abec6342a', 'setuptools-0.6c9-py2.5.egg': 'fe67c3e5a17b12c0e7c541b7ea43a8e6', 'setuptools-0.6c9-py2.6.egg': 'ca37b1ff16fa2ede6e19383e7b59245a', } import sys, os try: from hashlib import md5 except ImportError: from md5 import md5 def _validate_md5(egg_name, data): if egg_name in md5_data: digest = md5(data).hexdigest() if digest != md5_data[egg_name]: print >>sys.stderr, ( "md5 validation of %s failed! (Possible download problem?)" % egg_name ) sys.exit(2) return data def use_setuptools( version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, download_delay=15 ): """Automatically find/download setuptools and make it available on sys.path `version` should be a valid setuptools version number that is available as an egg for download under the `download_base` URL (which should end with a '/'). `to_dir` is the directory where setuptools will be downloaded, if it is not already available. If `download_delay` is specified, it should be the number of seconds that will be paused before initiating a download, should one be required. If an older version of setuptools is installed, this routine will print a message to ``sys.stderr`` and raise SystemExit in an attempt to abort the calling script. |
Line 78: | Line 87: |
# Strip 'dir/' from of path before joining with prefix dir = dir.rstrip('/') strip = len(dir) + 1 found = [] os.path.walk(dir, visit, (prefix, strip, found)) return found def visit((prefix, strip, found), dirname, names): """ Visit directory, create distutil tuple Add distutil tuple for each directory using this format: (destination, [dirname/file1, dirname/file2, ...]) distutil will copy later file1, file2, ... info destination. |
was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules def do_download(): egg = download_setuptools(version, download_base, to_dir, download_delay) sys.path.insert(0, egg) import setuptools; setuptools.bootstrap_install_from = egg try: import pkg_resources except ImportError: return do_download() try: pkg_resources.require("setuptools>="+version); return except pkg_resources.VersionConflict, e: if was_imported: print >>sys.stderr, ( "The required version of setuptools (>=%s) is not available, and\n" "can't be installed while this script is running. Please install\n" " a more recent version first, using 'easy_install -U setuptools'." "\n\n(Currently using %r)" ) % (version, e.args[0]) sys.exit(2) else: del pkg_resources, sys.modules['pkg_resources'] # reload ok return do_download() except pkg_resources.DistributionNotFound: return do_download() def download_setuptools( version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, delay = 15 ): """Download setuptools from a specified location and return its filename `version` should be a valid setuptools version number that is available as an egg for download under the `download_base` URL (which should end with a '/'). `to_dir` is the directory where the egg will be downloaded. `delay` is the number of seconds to pause before an actual download attempt. |
Line 93: | Line 124: |
files = [] # Iterate over a copy of names, modify names for name in names[:]: path = os.path.join(dirname, name) # Ignore directories - we will visit later if os.path.isdir(path): # Remove directories we don't want to visit later if isbad(name): names.remove(name) continue elif isgood(name): files.append(path) destination = os.path.join(prefix, dirname[strip:]) found.append((destination, files)) ############################################################################# ### Build script files ############################################################################# class build_scripts_create(build_scripts): """ Overload the build_scripts command and create the scripts from scratch, depending on the target platform. You have to define the name of your package in an inherited class (due to the delayed instantiation of command classes in distutils, this cannot be passed to __init__). The scripts are created in an uniform scheme: they start the run() function in the module <packagename>.script.<mangled_scriptname> The mangling of script names replaces '-' and '/' characters with '-' and '.', so that they are valid module paths. """ package_name = None def copy_scripts(self): """ Create each script listed in 'self.scripts' """ if not self.package_name: raise Exception("You have to inherit build_scripts_create and" " provide a package name") self.mkpath(self.build_dir) for script in self.scripts: outfile = os.path.join(self.build_dir, os.path.basename(script)) #if not self.force and not newer(script, outfile): # self.announce("not copying %s (up-to-date)" % script) # continue if self.dry_run: self.announce("would create %s" % outfile) continue module = os.path.splitext(os.path.basename(script))[0] module = module.replace('-', '_').replace('/', '.') script_vars = { 'python': os.path.normpath(sys.executable), 'package': self.package_name, 'module': module, 'package_location': '/usr/lib/python/site-packages', # FIXME: we need to know the correct path } self.announce("creating %s" % outfile) file = open(outfile, 'w') try: if sys.platform == "win32": file.write('@echo off\n' 'if NOT "%%_4ver%%" == "" %(python)s -c "from %(package)s.script.%(module)s import run; run()" %%$\n' 'if "%%_4ver%%" == "" %(python)s -c "from %(package)s.script.%(module)s import run; run()" %%*\n' % script_vars) else: file.write("#! %(python)s\n" "#Fix and uncomment those 2 lines if your moin command doesn't find the MoinMoin package:\n" "#import sys\n" "#sys.path.insert(0, '%(package_location)s')\n" "from %(package)s.script.%(module)s import run\n" "run()\n" % script_vars) finally: file.close() os.chmod(outfile, 0755) class build_scripts_moin(build_scripts_create): package_name = 'MoinMoin' def scriptname(path): """ Helper for building a list of script names from a list of module files. """ script = os.path.splitext(os.path.basename(path))[0] script = script.replace('_', '-') if sys.platform == "win32": script = script + ".bat" return script # build list of scripts from their implementation modules moin_scripts = [scriptname(fn) for fn in glob.glob('MoinMoin/script/[!_]*.py')] ############################################################################# ### Call setup() ############################################################################# setup_args = { 'name': "moin", 'version': release, 'description': "MoinMoin %s is an easy to use, full-featured and extensible wiki software package" % (release, ), 'author': "Juergen Hermann et al.", 'author_email': "moin-user@lists.sourceforge.net", # maintainer(_email) not active because distutils/register can't handle author and maintainer at once 'download_url': 'http://static.moinmo.in/files/moin-%s.tar.gz' % (release, ), 'url': "http://moinmo.in/", 'license': "GNU GPL", 'long_description': """ MoinMoin is an easy to use, full-featured and extensible wiki software package written in Python. It can fulfill a wide range of roles, such as a personal notes organizer deployed on a laptop or home web server, a company knowledge base deployed on an intranet, or an Internet server open to individuals sharing the same interests, goals or projects.""", 'classifiers': """Development Status :: 5 - Production/Stable Environment :: No Input/Output (Daemon) Environment :: Web Environment Environment :: Win32 (MS Windows) Intended Audience :: Customer Service Intended Audience :: Developers Intended Audience :: Education Intended Audience :: End Users/Desktop Intended Audience :: Financial and Insurance Industry Intended Audience :: Healthcare Industry Intended Audience :: Information Technology Intended Audience :: Legal Industry Intended Audience :: Manufacturing Intended Audience :: Other Audience Intended Audience :: Religion Intended Audience :: Science/Research Intended Audience :: System Administrators Intended Audience :: Telecommunications Industry License :: OSI Approved :: GNU General Public License (GPL) Natural Language :: Chinese (Simplified) Natural Language :: Chinese (Traditional) Natural Language :: Danish Natural Language :: Dutch Natural Language :: English Natural Language :: French Natural Language :: German Natural Language :: Hebrew Natural Language :: Hungarian Natural Language :: Italian Natural Language :: Javanese Natural Language :: Korean Natural Language :: Norwegian Natural Language :: Russian Natural Language :: Serbian Natural Language :: Spanish Natural Language :: Vietnamese Operating System :: MacOS :: MacOS X Operating System :: Microsoft :: Windows Operating System :: Microsoft :: Windows :: Windows 95/98/2000 Operating System :: Microsoft :: Windows :: Windows NT/2000 Operating System :: OS Independent Operating System :: POSIX Operating System :: POSIX :: BSD :: FreeBSD Operating System :: POSIX :: Linux Operating System :: Unix Programming Language :: Python Topic :: Communications :: Conferencing Topic :: Internet :: WWW/HTTP :: Dynamic Content Topic :: Office/Business :: Groupware Topic :: Text Processing :: Markup""".splitlines(), 'packages': [ 'jabberbot', 'MoinMoin', 'MoinMoin.action', 'MoinMoin.auth', 'MoinMoin.config', 'MoinMoin.converter', 'MoinMoin.events', 'MoinMoin.filter', 'MoinMoin.formatter', 'MoinMoin.i18n', 'MoinMoin.i18n.tools', 'MoinMoin.logfile', 'MoinMoin.macro', 'MoinMoin.mail', 'MoinMoin.parser', 'MoinMoin.request', 'MoinMoin.script', 'MoinMoin.script.account', 'MoinMoin.script.cli', 'MoinMoin.script.export', 'MoinMoin.script.import', 'MoinMoin.script.index', 'MoinMoin.script.maint', 'MoinMoin.script.migration', 'MoinMoin.script.old', 'MoinMoin.script.old.migration', 'MoinMoin.script.old.xmlrpc-tools', 'MoinMoin.script.server', 'MoinMoin.script.xmlrpc', 'MoinMoin.search', 'MoinMoin.security', 'MoinMoin.server', 'MoinMoin.stats', 'MoinMoin.support', 'MoinMoin.support.xapwrap', 'MoinMoin.support.parsedatetime', 'MoinMoin.theme', 'MoinMoin.userform', 'MoinMoin.userprefs', 'MoinMoin.util', 'MoinMoin.widget', 'MoinMoin.wikixml', 'MoinMoin.xmlrpc', # all other _tests are missing here, either we have all or nothing: #'MoinMoin._tests', ], # We can use package_* instead of the smart_install_data hack when we # require Python 2.4. #'package_dir': { 'MoinMoin.i18n': 'MoinMoin/i18n', }, #'package_data': { 'MoinMoin.i18n': ['README', 'Makefile', 'MoinMoin.pot', 'POTFILES.in', # '*.po', # 'tools/*',], }, # Override certain command classes with our own ones 'cmdclass': { 'build_scripts': build_scripts_moin, 'install_data': smart_install_data, # hack needed for 2.3 }, 'scripts': moin_scripts, # This copies the contents of wiki dir under sys.prefix/share/moin # Do not put files that should not be installed in the wiki dir, or # clean the dir before you make the distribution tarball. 'data_files': makeDataFiles('share/moin', 'wiki') + makeDataFiles('MoinMoin/i18n', 'MoinMoin/i18n') } if hasattr(distutils.dist.DistributionMetadata, 'get_keywords'): setup_args['keywords'] = "wiki web" if hasattr(distutils.dist.DistributionMetadata, 'get_platforms'): setup_args['platforms'] = "any" try: setup(**setup_args) except distutils.errors.DistutilsPlatformError, ex: print str(ex) print """ POSSIBLE CAUSE "distutils" often needs developer support installed to work correctly, which is usually located in a separate package called "python%d.%d-dev(el)". Please contact the system administrator to have it installed. """ % sys.version_info[:2] sys.exit(1) |
import urllib2, shutil egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3]) url = download_base + egg_name saveto = os.path.join(to_dir, egg_name) src = dst = None if not os.path.exists(saveto): # Avoid repeated downloads try: from distutils import log if delay: log.warn(""" --------------------------------------------------------------------------- This script requires setuptools version %s to run (even to display help). I will attempt to download it for you (from %s), but you may need to enable firewall access for this script first. I will start the download in %d seconds. (Note: if this machine does not have network access, please obtain the file %s and place it in this directory before rerunning this script.) ---------------------------------------------------------------------------""", version, download_base, delay, url ); from time import sleep; sleep(delay) log.warn("Downloading %s", url) src = urllib2.urlopen(url) # Read/write all in one block, so we don't create a corrupt file # if the download is interrupted. data = _validate_md5(egg_name, src.read()) dst = open(saveto,"wb"); dst.write(data) finally: if src: src.close() if dst: dst.close() return os.path.realpath(saveto) def main(argv, version=DEFAULT_VERSION): """Install or upgrade setuptools and EasyInstall""" try: import setuptools except ImportError: egg = None try: egg = download_setuptools(version, delay=0) sys.path.insert(0,egg) from setuptools.command.easy_install import main return main(list(argv)+[egg]) # we're done here finally: if egg and os.path.exists(egg): os.unlink(egg) else: if setuptools.__version__ == '0.0.1': print >>sys.stderr, ( "You have an obsolete version of setuptools installed. Please\n" "remove it from your system entirely before rerunning this script." ) sys.exit(2) req = "setuptools>="+version import pkg_resources try: pkg_resources.require(req) except pkg_resources.VersionConflict: try: from setuptools.command.easy_install import main except ImportError: from easy_install import main main(list(argv)+[download_setuptools(delay=0)]) sys.exit(0) # try to force an exit else: if argv: from setuptools.command.easy_install import main main(argv) else: print "Setuptools version",version,"or greater has been installed." print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)' def update_md5(filenames): """Update our built-in md5 registry""" import re for name in filenames: base = os.path.basename(name) f = open(name,'rb') md5_data[base] = md5(f.read()).hexdigest() f.close() data = [" %r: %r,\n" % it for it in md5_data.items()] data.sort() repl = "".join(data) import inspect srcfile = inspect.getsourcefile(sys.modules[__name__]) f = open(srcfile, 'rb'); src = f.read(); f.close() match = re.search("\nmd5_data = {\n([^}]+)}", src) if not match: print >>sys.stderr, "Internal error!" sys.exit(2) src = src[:match.start(1)] + repl + src[match.end(1):] f = open(srcfile,'w') f.write(src) f.close() if __name__=='__main__': if len(sys.argv)>2 and sys.argv[1]=='--md5update': update_md5(sys.argv[2:]) else: main(sys.argv[1:]) |
"""Bootstrap setuptools installation
If you want to use setuptools in your package's setup.py, just include this file in the same directory with it, and add this to the top of your setup.py::
- from ez_setup import use_setuptools use_setuptools()
If you want to require a specific version of setuptools, set a download mirror, or use an alternate download directory, you can do so by supplying the appropriate options to use_setuptools().
This file can also be run as a script to install or upgrade setuptools. """ import sys DEFAULT_VERSION = "0.6c9" DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3]
md5_data = {
- 'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca', 'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb', 'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b', 'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a', 'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618', 'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac', 'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5', 'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4', 'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c', 'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b', 'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27', 'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277', 'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa', 'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e', 'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e', 'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f', 'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2', 'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc', 'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167', 'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64', 'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d', 'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20', 'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab', 'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53', 'setuptools-0.6c7-py2.3.egg': '209fdf9adc3a615e5115b725658e13e2', 'setuptools-0.6c7-py2.4.egg': '5a8f954807d46a0fb67cf1f26c55a82e', 'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372', 'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902', 'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de', 'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b', 'setuptools-0.6c9-py2.3.egg': 'a83c4020414807b496e4cfbe08507c03', 'setuptools-0.6c9-py2.4.egg': '260a2be2e5388d66bdaee06abec6342a', 'setuptools-0.6c9-py2.5.egg': 'fe67c3e5a17b12c0e7c541b7ea43a8e6', 'setuptools-0.6c9-py2.6.egg': 'ca37b1ff16fa2ede6e19383e7b59245a',
}
import sys, os try: from hashlib import md5 except ImportError: from md5 import md5
def _validate_md5(egg_name, data):
- if egg_name in md5_data:
- digest = md5(data).hexdigest() if digest != md5_data[egg_name]:
print >>sys.stderr, (
- "md5 validation of %s failed! (Possible download problem?)" % egg_name
- digest = md5(data).hexdigest() if digest != md5_data[egg_name]:
def use_setuptools(
- version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, download_delay=15
):
- """Automatically find/download setuptools and make it available on sys.path
version should be a valid setuptools version number that is available as an egg for download under the download_base URL (which should end with a '/'). to_dir is the directory where setuptools will be downloaded, if it is not already available. If download_delay is specified, it should be the number of seconds that will be paused before initiating a download, should one be required. If an older version of setuptools is installed, this routine will print a message to sys.stderr and raise SystemExit in an attempt to abort the calling script. """ was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules def do_download():
- egg = download_setuptools(version, download_base, to_dir, download_delay) sys.path.insert(0, egg) import setuptools; setuptools.bootstrap_install_from = egg
- import pkg_resources
except ImportError:
- return do_download()
pkg_resources.require("setuptools>="+version); return
except pkg_resources.VersionConflict, e:
- if was_imported:
print >>sys.stderr, ( "The required version of setuptools (>=%s) is not available, and\n" "can't be installed while this script is running. Please install\n" " a more recent version first, using 'easy_install -U setuptools'." "\n\n(Currently using %r)" ) % (version, e.args[0]) sys.exit(2)
- del pkg_resources, sys.modules['pkg_resources'] # reload ok return do_download()
except pkg_resources.DistributionNotFound:
- return do_download()
def download_setuptools(
- version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, delay = 15
):
- """Download setuptools from a specified location and return its filename
version should be a valid setuptools version number that is available as an egg for download under the download_base URL (which should end with a '/'). to_dir is the directory where the egg will be downloaded. delay is the number of seconds to pause before an actual download attempt. """ import urllib2, shutil egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3]) url = download_base + egg_name saveto = os.path.join(to_dir, egg_name) src = dst = None if not os.path.exists(saveto): # Avoid repeated downloads
- try:
- from distutils import log if delay:
- log.warn("""
- from distutils import log if delay:
- try:
This script requires setuptools version %s to run (even to display help). I will attempt to download it for you (from %s), but you may need to enable firewall access for this script first. I will start the download in %d seconds.
(Note: if this machine does not have network access, please obtain the file
- %s
and place it in this directory before rerunning this script.)
""",
- version, download_base, delay, url
- ); from time import sleep; sleep(delay)
- log.warn("Downloading %s", url) src = urllib2.urlopen(url) # Read/write all in one block, so we don't create a corrupt file # if the download is interrupted. data = _validate_md5(egg_name, src.read()) dst = open(saveto,"wb"); dst.write(data)
- finally:
- if src: src.close() if dst: dst.close()
- return os.path.realpath(saveto)
def main(argv, version=DEFAULT_VERSION):
"""Install or upgrade setuptools and EasyInstall""" try:
- import setuptools
except ImportError:
- egg = None try:
- egg = download_setuptools(version, delay=0) sys.path.insert(0,egg) from setuptools.command.easy_install import main return main(list(argv)+[egg]) # we're done here
- if egg and os.path.exists(egg):
- os.unlink(egg)
if setuptools.version == '0.0.1':
print >>sys.stderr, ( "You have an obsolete version of setuptools installed. Please\n" "remove it from your system entirely before rerunning this script." ) sys.exit(2)
req = "setuptools>="+version import pkg_resources try:
- pkg_resources.require(req)
except pkg_resources.VersionConflict:
- try:
- from setuptools.command.easy_install import main
except ImportError:
- from easy_install import main
- if argv:
- from setuptools.command.easy_install import main main(argv)
- print "Setuptools version",version,"or greater has been installed." print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
def update_md5(filenames):
- """Update our built-in md5 registry""" import re for name in filenames:
- base = os.path.basename(name) f = open(name,'rb') md5_data[base] = md5(f.read()).hexdigest() f.close()
srcfile = inspect.getsourcefile(sys.modules[name]) f = open(srcfile, 'rb'); src = f.read(); f.close() match = re.search("\nmd5_data = {\n([^}]+)}", src) if not match:
print >>sys.stderr, "Internal error!" sys.exit(2)
if name=='main':
if len(sys.argv)>2 and sys.argv[1]=='--md5update':
- update_md5(sys.argv[2:])
- main(sys.argv[1:])