From 3817ad5f7fbed607aff1dab2b583dd2488220d03 Mon Sep 17 00:00:00 2001 From: rlacko Date: Mon, 5 May 2014 14:13:36 +0200 Subject: Update setuptools bootstrap script to latest version --- ez_setup.py | 153 ++++++++++++++++++++++++------------------------------------ 1 file changed, 62 insertions(+), 91 deletions(-) (limited to 'ez_setup.py') diff --git a/ez_setup.py b/ez_setup.py index 2aa994b33..23ea9a2b7 100644 --- a/ez_setup.py +++ b/ez_setup.py @@ -1,4 +1,4 @@ -#!python +#!/usr/bin/env python """Bootstrap setuptools installation To use setuptools in your package's setup.py, include this @@ -17,11 +17,12 @@ import os import shutil import sys import tempfile -import tarfile +import zipfile import optparse import subprocess import platform import textwrap +import contextlib from distutils import log @@ -30,29 +31,19 @@ try: except ImportError: USER_SITE = None -DEFAULT_VERSION = "2.0" +DEFAULT_VERSION = "3.5.1" DEFAULT_URL = "https://pypi.python.org/packages/source/s/setuptools/" def _python_cmd(*args): + """ + Return True if the command succeeded. + """ args = (sys.executable,) + args return subprocess.call(args) == 0 -def _install(tarball, install_args=()): - # extracting the tarball - tmpdir = tempfile.mkdtemp() - log.warn('Extracting in %s', tmpdir) - old_wd = os.getcwd() - try: - os.chdir(tmpdir) - tar = tarfile.open(tarball) - _extractall(tar) - tar.close() - - # going in the directory - subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0]) - os.chdir(subdir) - log.warn('Now working in %s', subdir) +def _install(archive_filename, install_args=()): + with archive_context(archive_filename): # installing log.warn('Installing Setuptools') if not _python_cmd('setup.py', 'install', *install_args): @@ -60,47 +51,61 @@ def _install(tarball, install_args=()): log.warn('See the error message above.') # exitcode will be 2 return 2 - finally: - os.chdir(old_wd) - shutil.rmtree(tmpdir) -def _build_egg(egg, tarball, to_dir): - # extracting the tarball +def _build_egg(egg, archive_filename, to_dir): + with archive_context(archive_filename): + # building an egg + log.warn('Building a Setuptools egg in %s', to_dir) + _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir) + # returning the result + log.warn(egg) + if not os.path.exists(egg): + raise IOError('Could not build the egg.') + + +def get_zip_class(): + """ + Supplement ZipFile class to support context manager for Python 2.6 + """ + class ContextualZipFile(zipfile.ZipFile): + def __enter__(self): + return self + def __exit__(self, type, value, traceback): + self.close + return zipfile.ZipFile if hasattr(zipfile.ZipFile, '__exit__') else \ + ContextualZipFile + + +@contextlib.contextmanager +def archive_context(filename): + # extracting the archive tmpdir = tempfile.mkdtemp() log.warn('Extracting in %s', tmpdir) old_wd = os.getcwd() try: os.chdir(tmpdir) - tar = tarfile.open(tarball) - _extractall(tar) - tar.close() + with get_zip_class()(filename) as archive: + archive.extractall() # going in the directory subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0]) os.chdir(subdir) log.warn('Now working in %s', subdir) - - # building an egg - log.warn('Building a Setuptools egg in %s', to_dir) - _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir) + yield finally: os.chdir(old_wd) shutil.rmtree(tmpdir) - # returning the result - log.warn(egg) - if not os.path.exists(egg): - raise IOError('Could not build the egg.') def _do_download(version, download_base, to_dir, download_delay): egg = os.path.join(to_dir, 'setuptools-%s-py%d.%d.egg' % (version, sys.version_info[0], sys.version_info[1])) if not os.path.exists(egg): - tarball = download_setuptools(version, download_base, + archive = download_setuptools(version, download_base, to_dir, download_delay) - _build_egg(egg, tarball, to_dir) + _build_egg(egg, archive, to_dir) sys.path.insert(0, egg) # Remove previously-imported pkg_resources if present (see @@ -113,7 +118,7 @@ def _do_download(version, download_base, to_dir, download_delay): def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, - to_dir=os.curdir, download_delay=15): + to_dir=os.curdir, download_delay=15): to_dir = os.path.abspath(to_dir) rep_modules = 'pkg_resources', 'setuptools' imported = set(sys.modules).intersection(rep_modules) @@ -176,7 +181,7 @@ def has_powershell(): try: try: subprocess.check_call(cmd, stdout=devnull, stderr=devnull) - except: + except Exception: return False finally: devnull.close() @@ -194,7 +199,7 @@ def has_curl(): try: try: subprocess.check_call(cmd, stdout=devnull, stderr=devnull) - except: + except Exception: return False finally: devnull.close() @@ -212,7 +217,7 @@ def has_wget(): try: try: subprocess.check_call(cmd, stdout=devnull, stderr=devnull) - except: + except Exception: return False finally: devnull.close() @@ -258,9 +263,9 @@ def get_best_downloader(): return dl def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, - to_dir=os.curdir, delay=15, - downloader_factory=get_best_downloader): - """Download setuptools from a specified location and return its filename + to_dir=os.curdir, delay=15, downloader_factory=get_best_downloader): + """ + 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 @@ -273,56 +278,15 @@ def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, """ # making sure we use the absolute path to_dir = os.path.abspath(to_dir) - tgz_name = "setuptools-%s.tar.gz" % version - url = download_base + tgz_name - saveto = os.path.join(to_dir, tgz_name) + zip_name = "setuptools-%s.zip" % version + url = download_base + zip_name + saveto = os.path.join(to_dir, zip_name) if not os.path.exists(saveto): # Avoid repeated downloads log.warn("Downloading %s", url) downloader = downloader_factory() downloader(url, saveto) return os.path.realpath(saveto) - -def _extractall(self, path=".", members=None): - """Extract all members from the archive to the current working - directory and set owner, modification time and permissions on - directories afterwards. `path' specifies a different directory - to extract to. `members' is optional and must be a subset of the - list returned by getmembers(). - """ - import copy - import operator - from tarfile import ExtractError - directories = [] - - if members is None: - members = self - - for tarinfo in members: - if tarinfo.isdir(): - # Extract directories with a safe mode. - directories.append(tarinfo) - tarinfo = copy.copy(tarinfo) - tarinfo.mode = 448 # decimal for oct 0700 - self.extract(tarinfo, path) - - # Reverse sort directories. - directories.sort(key=operator.attrgetter('name'), reverse=True) - - # Set correct owner, mtime and filemode on directories. - for tarinfo in directories: - dirpath = os.path.join(path, tarinfo.name) - try: - self.chown(tarinfo, dirpath) - self.utime(tarinfo, dirpath) - self.chmod(tarinfo, dirpath) - except ExtractError as e: - if self.errorlevel > 1: - raise - else: - self._dbg(1, "tarfile: %s" % e) - - def _build_install_args(options): """ Build the arguments to 'python setup.py install' on the setuptools package @@ -346,16 +310,23 @@ def _parse_args(): const=lambda: download_file_insecure, default=get_best_downloader, help='Use internal, non-validating downloader' ) + parser.add_option( + '--version', help="Specify which version to download", + default=DEFAULT_VERSION, + ) options, args = parser.parse_args() # positional arguments are ignored return options -def main(version=DEFAULT_VERSION): +def main(): """Install or upgrade setuptools and EasyInstall""" options = _parse_args() - tarball = download_setuptools(download_base=options.download_base, - downloader_factory=options.downloader_factory) - return _install(tarball, _build_install_args(options)) + archive = download_setuptools( + version=options.version, + download_base=options.download_base, + downloader_factory=options.downloader_factory, + ) + return _install(archive, _build_install_args(options)) if __name__ == '__main__': sys.exit(main()) -- cgit v1.2.3