modified: pixi.toml
[GalaxyCodeBases.git] / BioInfo / BS-Seq / bwa-meth / ez_setup.py
blobb8abb6f4ea8e6ade36d0939f77d4df9532d77b6b
1 #!python
2 """Bootstrap setuptools installation
4 To use setuptools in your package's setup.py, include this
5 file in the same directory and add this to the top of your setup.py::
7 from ez_setup import use_setuptools
8 use_setuptools()
10 To require a specific version of setuptools, set a download
11 mirror, or use an alternate download directory, simply supply
12 the appropriate options to ``use_setuptools()``.
14 This file can also be run as a script to install or upgrade setuptools.
15 """
16 import os
17 import shutil
18 import sys
19 import tempfile
20 import tarfile
21 import optparse
22 import subprocess
23 import platform
24 import textwrap
26 from distutils import log
28 try:
29 from site import USER_SITE
30 except ImportError:
31 USER_SITE = None
33 DEFAULT_VERSION = "2.0.1"
34 DEFAULT_URL = "https://pypi.python.org/packages/source/s/setuptools/"
36 def _python_cmd(*args):
37 args = (sys.executable,) + args
38 return subprocess.call(args) == 0
40 def _install(tarball, install_args=()):
41 # extracting the tarball
42 tmpdir = tempfile.mkdtemp()
43 log.warn('Extracting in %s', tmpdir)
44 old_wd = os.getcwd()
45 try:
46 os.chdir(tmpdir)
47 tar = tarfile.open(tarball)
48 _extractall(tar)
49 tar.close()
51 # going in the directory
52 subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
53 os.chdir(subdir)
54 log.warn('Now working in %s', subdir)
56 # installing
57 log.warn('Installing Setuptools')
58 if not _python_cmd('setup.py', 'install', *install_args):
59 log.warn('Something went wrong during the installation.')
60 log.warn('See the error message above.')
61 # exitcode will be 2
62 return 2
63 finally:
64 os.chdir(old_wd)
65 shutil.rmtree(tmpdir)
68 def _build_egg(egg, tarball, to_dir):
69 # extracting the tarball
70 tmpdir = tempfile.mkdtemp()
71 log.warn('Extracting in %s', tmpdir)
72 old_wd = os.getcwd()
73 try:
74 os.chdir(tmpdir)
75 tar = tarfile.open(tarball)
76 _extractall(tar)
77 tar.close()
79 # going in the directory
80 subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
81 os.chdir(subdir)
82 log.warn('Now working in %s', subdir)
84 # building an egg
85 log.warn('Building a Setuptools egg in %s', to_dir)
86 _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir)
88 finally:
89 os.chdir(old_wd)
90 shutil.rmtree(tmpdir)
91 # returning the result
92 log.warn(egg)
93 if not os.path.exists(egg):
94 raise IOError('Could not build the egg.')
97 def _do_download(version, download_base, to_dir, download_delay):
98 egg = os.path.join(to_dir, 'setuptools-%s-py%d.%d.egg'
99 % (version, sys.version_info[0], sys.version_info[1]))
100 if not os.path.exists(egg):
101 tarball = download_setuptools(version, download_base,
102 to_dir, download_delay)
103 _build_egg(egg, tarball, to_dir)
104 sys.path.insert(0, egg)
106 # Remove previously-imported pkg_resources if present (see
107 # https://bitbucket.org/pypa/setuptools/pull-request/7/ for details).
108 if 'pkg_resources' in sys.modules:
109 del sys.modules['pkg_resources']
111 import setuptools
112 setuptools.bootstrap_install_from = egg
115 def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
116 to_dir=os.curdir, download_delay=15):
117 to_dir = os.path.abspath(to_dir)
118 rep_modules = 'pkg_resources', 'setuptools'
119 imported = set(sys.modules).intersection(rep_modules)
120 try:
121 import pkg_resources
122 except ImportError:
123 return _do_download(version, download_base, to_dir, download_delay)
124 try:
125 pkg_resources.require("setuptools>=" + version)
126 return
127 except pkg_resources.DistributionNotFound:
128 return _do_download(version, download_base, to_dir, download_delay)
129 except pkg_resources.VersionConflict as VC_err:
130 if imported:
131 msg = textwrap.dedent("""
132 The required version of setuptools (>={version}) is not available,
133 and can't be installed while this script is running. Please
134 install a more recent version first, using
135 'easy_install -U setuptools'.
137 (Currently using {VC_err.args[0]!r})
138 """).format(VC_err=VC_err, version=version)
139 sys.stderr.write(msg)
140 sys.exit(2)
142 # otherwise, reload ok
143 del pkg_resources, sys.modules['pkg_resources']
144 return _do_download(version, download_base, to_dir, download_delay)
146 def _clean_check(cmd, target):
148 Run the command to download target. If the command fails, clean up before
149 re-raising the error.
151 try:
152 subprocess.check_call(cmd)
153 except subprocess.CalledProcessError:
154 if os.access(target, os.F_OK):
155 os.unlink(target)
156 raise
158 def download_file_powershell(url, target):
160 Download the file at url to target using Powershell (which will validate
161 trust). Raise an exception if the command cannot complete.
163 target = os.path.abspath(target)
164 cmd = [
165 'powershell',
166 '-Command',
167 "(new-object System.Net.WebClient).DownloadFile(%(url)r, %(target)r)" % vars(),
169 _clean_check(cmd, target)
171 def has_powershell():
172 if platform.system() != 'Windows':
173 return False
174 cmd = ['powershell', '-Command', 'echo test']
175 devnull = open(os.path.devnull, 'wb')
176 try:
177 try:
178 subprocess.check_call(cmd, stdout=devnull, stderr=devnull)
179 except:
180 return False
181 finally:
182 devnull.close()
183 return True
185 download_file_powershell.viable = has_powershell
187 def download_file_curl(url, target):
188 cmd = ['curl', url, '--silent', '--output', target]
189 _clean_check(cmd, target)
191 def has_curl():
192 cmd = ['curl', '--version']
193 devnull = open(os.path.devnull, 'wb')
194 try:
195 try:
196 subprocess.check_call(cmd, stdout=devnull, stderr=devnull)
197 except:
198 return False
199 finally:
200 devnull.close()
201 return True
203 download_file_curl.viable = has_curl
205 def download_file_wget(url, target):
206 cmd = ['wget', url, '--quiet', '--output-document', target]
207 _clean_check(cmd, target)
209 def has_wget():
210 cmd = ['wget', '--version']
211 devnull = open(os.path.devnull, 'wb')
212 try:
213 try:
214 subprocess.check_call(cmd, stdout=devnull, stderr=devnull)
215 except:
216 return False
217 finally:
218 devnull.close()
219 return True
221 download_file_wget.viable = has_wget
223 def download_file_insecure(url, target):
225 Use Python to download the file, even though it cannot authenticate the
226 connection.
228 try:
229 from urllib.request import urlopen
230 except ImportError:
231 from urllib2 import urlopen
232 src = dst = None
233 try:
234 src = urlopen(url)
235 # Read/write all in one block, so we don't create a corrupt file
236 # if the download is interrupted.
237 data = src.read()
238 dst = open(target, "wb")
239 dst.write(data)
240 finally:
241 if src:
242 src.close()
243 if dst:
244 dst.close()
246 download_file_insecure.viable = lambda: True
248 def get_best_downloader():
249 downloaders = [
250 download_file_powershell,
251 download_file_curl,
252 download_file_wget,
253 download_file_insecure,
256 for dl in downloaders:
257 if dl.viable():
258 return dl
260 def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
261 to_dir=os.curdir, delay=15,
262 downloader_factory=get_best_downloader):
263 """Download setuptools from a specified location and return its filename
265 `version` should be a valid setuptools version number that is available
266 as an egg for download under the `download_base` URL (which should end
267 with a '/'). `to_dir` is the directory where the egg will be downloaded.
268 `delay` is the number of seconds to pause before an actual download
269 attempt.
271 ``downloader_factory`` should be a function taking no arguments and
272 returning a function for downloading a URL to a target.
274 # making sure we use the absolute path
275 to_dir = os.path.abspath(to_dir)
276 tgz_name = "setuptools-%s.tar.gz" % version
277 url = download_base + tgz_name
278 saveto = os.path.join(to_dir, tgz_name)
279 if not os.path.exists(saveto): # Avoid repeated downloads
280 log.warn("Downloading %s", url)
281 downloader = downloader_factory()
282 downloader(url, saveto)
283 return os.path.realpath(saveto)
286 def _extractall(self, path=".", members=None):
287 """Extract all members from the archive to the current working
288 directory and set owner, modification time and permissions on
289 directories afterwards. `path' specifies a different directory
290 to extract to. `members' is optional and must be a subset of the
291 list returned by getmembers().
293 import copy
294 import operator
295 from tarfile import ExtractError
296 directories = []
298 if members is None:
299 members = self
301 for tarinfo in members:
302 if tarinfo.isdir():
303 # Extract directories with a safe mode.
304 directories.append(tarinfo)
305 tarinfo = copy.copy(tarinfo)
306 tarinfo.mode = 448 # decimal for oct 0700
307 self.extract(tarinfo, path)
309 # Reverse sort directories.
310 directories.sort(key=operator.attrgetter('name'), reverse=True)
312 # Set correct owner, mtime and filemode on directories.
313 for tarinfo in directories:
314 dirpath = os.path.join(path, tarinfo.name)
315 try:
316 self.chown(tarinfo, dirpath)
317 self.utime(tarinfo, dirpath)
318 self.chmod(tarinfo, dirpath)
319 except ExtractError as e:
320 if self.errorlevel > 1:
321 raise
322 else:
323 self._dbg(1, "tarfile: %s" % e)
326 def _build_install_args(options):
328 Build the arguments to 'python setup.py install' on the setuptools package
330 return ['--user'] if options.user_install else []
332 def _parse_args():
334 Parse the command line for options
336 parser = optparse.OptionParser()
337 parser.add_option(
338 '--user', dest='user_install', action='store_true', default=False,
339 help='install in user site package (requires Python 2.6 or later)')
340 parser.add_option(
341 '--download-base', dest='download_base', metavar="URL",
342 default=DEFAULT_URL,
343 help='alternative URL from where to download the setuptools package')
344 parser.add_option(
345 '--insecure', dest='downloader_factory', action='store_const',
346 const=lambda: download_file_insecure, default=get_best_downloader,
347 help='Use internal, non-validating downloader'
349 options, args = parser.parse_args()
350 # positional arguments are ignored
351 return options
353 def main(version=DEFAULT_VERSION):
354 """Install or upgrade setuptools and EasyInstall"""
355 options = _parse_args()
356 tarball = download_setuptools(download_base=options.download_base,
357 downloader_factory=options.downloader_factory)
358 return _install(tarball, _build_install_args(options))
360 if __name__ == '__main__':
361 sys.exit(main())