2 """Bootstrap setuptools installation
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::
7 from ez_setup import use_setuptools
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()``.
14 This file can also be run as a script to install or upgrade setuptools.
17 DEFAULT_VERSION = "0.6c12dev"
18 DEFAULT_DIR = "misc/dependencies/"
19 DEFAULT_URL = "file:"+DEFAULT_DIR
22 'setuptools-0.6c12dev.egg': '770da1c9e5446cf04273f0f1cdb8c09a',
27 def _validate_md5(egg_name, data):
28 if egg_name in md5_data:
30 digest = md5(data).hexdigest()
31 if digest != md5_data[egg_name]:
33 "md5 validation of %s failed! (Possible download problem?)"
41 version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
42 min_version="0.6c12dev", download_delay=15
44 """Automatically find/download setuptools and make it available on sys.path
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
58 if min_version is None:
61 was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules
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
71 pkg_resources.require("setuptools>="+min_version); return
72 except pkg_resources.VersionConflict, e:
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])
83 del pkg_resources, sys.modules['pkg_resources'] # reload ok
85 except pkg_resources.DistributionNotFound:
88 def download_setuptools(
89 version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
92 """Download setuptools from a specified location and return its filename
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.
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)
104 if not os.path.exists(saveto): # Avoid repeated downloads
106 from distutils import log
109 ---------------------------------------------------------------------------
110 This script requires setuptools version %s to run (even to display
111 help). I will attempt to download it for you (from
113 you may need to enable firewall access for this script first.
114 I will start the download in %d seconds.
116 (Note: if this machine does not have network access, please obtain the file
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)
133 return os.path.realpath(saveto)
170 def main(argv, version=DEFAULT_VERSION):
171 """Install or upgrade setuptools and EasyInstall"""
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
182 if egg and os.path.exists(egg):
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."
192 req = "setuptools>="+version
195 pkg_resources.require(req)
196 except pkg_resources.VersionConflict:
198 from setuptools.command.easy_install import main
200 from easy_install import main
201 main(list(argv)+[download_setuptools(delay=0)])
202 sys.exit(0) # try to force an exit
205 from setuptools.command.easy_install import main
208 print "Setuptools version",version,"or greater has been installed."
209 print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
211 def update_md5(filenames):
212 """Update our built-in md5 registry"""
217 for name in filenames:
218 base = os.path.basename(name)
220 md5_data[base] = md5(f.read()).hexdigest()
223 data = [" %r: %r,\n" % it for it in md5_data.items()]
228 srcfile = inspect.getsourcefile(sys.modules[__name__])
229 f = open(srcfile, 'rb'); src = f.read(); f.close()
231 match = re.search("\nmd5_data = {\n([^}]+)}", src)
233 print >>sys.stderr, "Internal error!"
236 src = src[:match.start(1)] + repl + src[match.end(1):]
237 f = open(srcfile,'w')
242 if __name__=='__main__':
243 if len(sys.argv)>2 and sys.argv[1]=='--md5update':
244 update_md5(sys.argv[2:])