From 5948858a72fa03beaf11554e2a1e3ef9750be02b Mon Sep 17 00:00:00 2001 From: Eric Coissac Date: Mon, 25 May 2015 16:55:09 +0200 Subject: [PATCH] Patch few bugs in distutils.ext. This version seems able to install at list the empty package --- distutils.ext/obidistutils/command/install.py | 7 +- distutils.ext/obidistutils/core.py | 93 +++++++++------ .../obidistutils/serenity/__init__.py | 108 ++++++++++++++++++ .../obidistutils/serenity/checkpython.py | 61 +++++++++- distutils.ext/obidistutils/serenity/rerun.py | 2 + distutils.ext/obidistutils/serenity/util.py | 27 +++++ .../obidistutils/serenity/virtual.py | 68 +++++++++++ 7 files changed, 326 insertions(+), 40 deletions(-) create mode 100644 distutils.ext/obidistutils/serenity/util.py create mode 100644 distutils.ext/obidistutils/serenity/virtual.py diff --git a/distutils.ext/obidistutils/command/install.py b/distutils.ext/obidistutils/command/install.py index 23641b0..62bf05e 100644 --- a/distutils.ext/obidistutils/command/install.py +++ b/distutils.ext/obidistutils/command/install.py @@ -4,12 +4,7 @@ Created on 6 oct. 2014 @author: coissac ''' -try: - from setuptools.command.install import install as install_ori - has_setuptools=True -except ImportError: - from distutils.command.install import install as install_ori - has_setuptools=False +from distutils.command.install import install as install_ori class install(install_ori): diff --git a/distutils.ext/obidistutils/core.py b/distutils.ext/obidistutils/core.py index beb7d65..8235b4c 100644 --- a/distutils.ext/obidistutils/core.py +++ b/distutils.ext/obidistutils/core.py @@ -23,22 +23,7 @@ from distutils import log from obidistutils.dist import Distribution -from obidistutils.command.build import build -from obidistutils.command.littlebigman import littlebigman -from obidistutils.command.build_cexe import build_cexe -from obidistutils.command.build_sphinx import build_sphinx -from obidistutils.command import build_ext -from obidistutils.command.build_ctools import build_ctools -from obidistutils.command.build_files import build_files -from obidistutils.command.build_scripts import build_scripts -from obidistutils.command.install_scripts import install_scripts -from obidistutils.command.install_sphinx import install_sphinx -from obidistutils.command.install import install -from obidistutils.command.pidname import pidname -from obidistutils.command.sdist import sdist - - def findPackage(root,base=None): modules=[] if base is None: @@ -89,19 +74,37 @@ def findCython(root,base=None,pyrexs=None): def rootname(x): return os.path.splitext(x.sources[0])[0] -COMMANDS = {'build':build, - 'littlebigman':littlebigman, - 'pidname':pidname, - 'build_ctools':build_ctools, - 'build_files':build_files, - 'build_cexe':build_cexe, - 'build_ext': build_ext, - 'build_scripts':build_scripts, - 'build_sphinx':build_sphinx, - 'install_scripts':install_scripts, - 'install_sphinx':install_sphinx, - 'install':install, - 'sdist':sdist} + +def prepare_commands(): + from obidistutils.command.build import build + from obidistutils.command.littlebigman import littlebigman + from obidistutils.command.build_cexe import build_cexe + from obidistutils.command.build_sphinx import build_sphinx + from obidistutils.command import build_ext + from obidistutils.command.build_ctools import build_ctools + from obidistutils.command.build_files import build_files + from obidistutils.command.build_scripts import build_scripts + from obidistutils.command.install_scripts import install_scripts + from obidistutils.command.install_sphinx import install_sphinx + from obidistutils.command.install import install + from obidistutils.command.pidname import pidname + from obidistutils.command.sdist import sdist + + COMMANDS = {'build':build, + 'littlebigman':littlebigman, + 'pidname':pidname, + 'build_ctools':build_ctools, + 'build_files':build_files, + 'build_cexe':build_cexe, + 'build_ext': build_ext, + 'build_scripts':build_scripts, + 'build_sphinx':build_sphinx, + 'install_scripts':install_scripts, + 'install_sphinx':install_sphinx, + 'install':install, + 'sdist':sdist} + + return COMMANDS CTOOLS =[] @@ -110,16 +113,40 @@ FILES =[] def setup(**attrs): - minversion = attrs.get("PYTHONMIN",'3.4') - maxversion = attrs.get('PYTHONMAX',None) - fork = attrs.get('FORK',False) - requirementfile = attrs.get('REQUIREMENTS','requirements.txt') + log.set_threshold(log.INFO) + + minversion = attrs.get("pythonmin",'3.4') + maxversion = attrs.get('pythonmax',None) + fork = attrs.get('fork',False) + requirementfile = attrs.get('requirements','requirements.txt') + + try: + del attrs['pythonmin'] + except KeyError: + pass + + try: + del attrs['pythonmax'] + except KeyError: + pass + + try: + del attrs['fork'] + except KeyError: + pass + + try: + del attrs['requirements'] + except KeyError: + pass + enforce_good_python(minversion, maxversion, fork) if (install_requirements(requirementfile)): rerun_with_anothe_python(sys.executable,minversion,maxversion,fork) + try: check_requirements(requirementfile) except RequirementError as e : @@ -145,7 +172,7 @@ def setup(**attrs): attrs['packages'] = findPackage(SRC) if 'cmdclass' not in attrs: - attrs['cmdclass'] = COMMANDS + attrs['cmdclass'] = prepare_commands() if 'ctools' not in attrs: attrs['ctools'] = CTOOLS diff --git a/distutils.ext/obidistutils/serenity/__init__.py b/distutils.ext/obidistutils/serenity/__init__.py index e69de29..02763fa 100644 --- a/distutils.ext/obidistutils/serenity/__init__.py +++ b/distutils.ext/obidistutils/serenity/__init__.py @@ -0,0 +1,108 @@ +import sys + +from distutils import util +from distutils import sysconfig +from distutils import log +from distutils.version import LooseVersion, StrictVersion +import glob +import os +import subprocess +import re +from distutils.errors import DistutilsError +import tempfile + +import importlib +import imp +import zipimport + +import argparse + +import base64 + +from .checkpython import is_python_version + + +from obidistutils.serenity.rerun import enforce_good_python +from obidistutils.serenity.rerun import rerun_with_anothe_python + +from obidistutils.serenity.virtual import serenity_virtualenv + +from obidistutils.serenity.checksystem import is_mac_system, \ + is_windows_system + +from obidistutils.serenity.checkpackage import install_requirements +from obidistutils.serenity.checkpackage import check_requirements + +from obidistutils.serenity.util import save_argv + +from obidistutils.serenity.snake import snake + + +def serenity_snake(envname,package,version): + old = log.set_threshold(log.INFO) + + log.info("Installing %s (%s) in serenity mode" % (package,version)) + + enforce_good_python() + + virtualpython=serenity_virtualenv(envname,package,version) + + if virtualpython!=os.path.realpath(sys.executable): + log.info("Restarting installation within the %s virtualenv" % (envname)) + rerun_with_anothe_python(virtualpython) + + log.info("%s will be installed with python : %s" % (package,virtualpython)) + + if install_requirements(): + log.info("Restarting installation with all dependencies ok") + rerun_with_anothe_python(virtualpython) + + log.set_threshold(old) + +def serenity_assert(version): + check_requirements() + + +def is_serenity(): + from obidistutils.serenity.globals import local_serenity + return local_serenity and local_serenity[0] + +def serenity_mode(package,version): + + save_argv() + + + from obidistutils.serenity.globals import saved_args + from obidistutils.serenity.globals import local_serenity + + + old = log.set_threshold(log.INFO) + + argparser = argparse.ArgumentParser(add_help=False) + argparser.add_argument('--serenity', + dest='serenity', + action='store_true', + default=False, + help='Switch the installer in serenity mode. Everythings are installed in a virtualenv') + + argparser.add_argument('--virtualenv', + dest='virtual', + type=str, + action='store', + default="%s-%s" % (package,version), + help='Specify the name of the virtualenv used by the serenity mode [default: %s-%s]' % (package,version)) + + args, unknown = argparser.parse_known_args() + sys.argv = [sys.argv[0]] + unknown + + if args.serenity: + local_serenity.append(True) + serenity_snake(args.virtual,package,version) + else: + local_serenity.append(False) + + log.set_threshold(old) + + return args.serenity + + diff --git a/distutils.ext/obidistutils/serenity/checkpython.py b/distutils.ext/obidistutils/serenity/checkpython.py index f1a5afe..333c28e 100644 --- a/distutils.ext/obidistutils/serenity/checkpython.py +++ b/distutils.ext/obidistutils/serenity/checkpython.py @@ -11,6 +11,7 @@ import glob import re from obidistutils.serenity.checksystem import is_windows_system +import sys def is_python_version(path=None,minversion='3.4',maxversion=None): @@ -75,5 +76,63 @@ def lookfor_good_python(minversion='3.4',maxversion=None,followLink=False): return exe - +def is_a_virtualenv_python(path=None): + ''' + Check if the python is belonging a virtualenv + + @param path: the path pointing to the python executable. + if path is None then the running python is + considered. + @param path: str or None + + @return: True if the python belongs a virtualenv + False otherwise + @rtype: bool + + ''' + if path is None: + rep = sys.base_exec_prefix == sys.exec_prefix + else: + command = """'%s' -c 'import sys; print(sys.base_exec_prefix == sys.exec_prefix)'""" % path + p = subprocess.Popen(command, + shell=True, + stdout=subprocess.PIPE) + rep = eval(str(p.communicate()[0],'utf8')) + + return rep + + +def which_virtualenv(path=None,full=False): + ''' + Returns the name of the virtualenv. + @param path: the path to a python binary or None + if you want to consider the running python + @type path: str or None + + @param full: if set to True, returns the absolute path, + otherwise only return a simple directory name + @type full: bool + + @return: the virtual environment name or None if the + path does not belong a virtualenv + @rtype: str or None + ''' + if path is None: + path = sys.executable + + if is_a_virtualenv_python(path): + parts = path.split(os.sep) + try: + if full: + rep = os.sep.join(parts[0:parts.index('bin')]) + rep = os.path.realpath(rep) + else: + rep = parts[parts.index('bin')-1] + except ValueError: + rep = None + else: + rep=None + + return rep + diff --git a/distutils.ext/obidistutils/serenity/rerun.py b/distutils.ext/obidistutils/serenity/rerun.py index 1d334ad..7a295f8 100644 --- a/distutils.ext/obidistutils/serenity/rerun.py +++ b/distutils.ext/obidistutils/serenity/rerun.py @@ -37,10 +37,12 @@ def rerun_with_anothe_python(path, minversion='3.4',maxversion=None, fork=False) log.info('External process ended') sys.exit(0) else: + log.info('Install script restarting...') os.execv(path,list(args)) def enforce_good_python(minversion='3.4',maxversion=None, fork=False): if is_python_version(minversion=minversion,maxversion=maxversion): + log.info('You are running the good python') return True goodpython = lookfor_good_python(minversion,maxversion) diff --git a/distutils.ext/obidistutils/serenity/util.py b/distutils.ext/obidistutils/serenity/util.py new file mode 100644 index 0000000..14c0283 --- /dev/null +++ b/distutils.ext/obidistutils/serenity/util.py @@ -0,0 +1,27 @@ +''' +Created on 2 oct. 2014 + +@author: coissac +''' + +import sys +import tempfile + + +from obidistutils.serenity.globals import tmpdir # @UnusedImport +from obidistutils.serenity.globals import saved_args # @UnusedImport + +def get_serenity_dir(): + global tmpdir + + if not tmpdir: + tmpdir.append(tempfile.mkdtemp()) + return tmpdir[0] + +def save_argv(): + global saved_args + + del saved_args[:] + saved_args.extend(list(sys.argv)) + + diff --git a/distutils.ext/obidistutils/serenity/virtual.py b/distutils.ext/obidistutils/serenity/virtual.py new file mode 100644 index 0000000..bd83949 --- /dev/null +++ b/distutils.ext/obidistutils/serenity/virtual.py @@ -0,0 +1,68 @@ +''' +Created on 2 oct. 2014 + +@author: coissac +''' + +import os +import sys +import venv + +from distutils.errors import DistutilsError +from obidistutils.serenity.globals import local_virtualenv # @UnusedImport +from obidistutils.serenity.checkpython import which_virtualenv,\ + is_python_version, \ + is_a_virtualenv_python + + + + +def serenity_virtualenv(envname,package,version,minversion='3.4',maxversion=None): + + # + # Checks if we are already running under the good virtualenv + # + ve = which_virtualenv(full=True) + if ve == os.path.realpath(envname) and is_python_version(minversion=minversion,maxversion=maxversion): + return sys.executable + + # + # Check if the virtualenv exist + # + + python = None + + if os.path.isdir(envname): + python = os.path.join(envname,'bin','python') + ok = (is_python_version(python, + minversion=minversion, + maxversion=maxversion) and + is_a_virtualenv_python(python)) + + # + # The virtualenv already exist but it is not ok + # + if not ok: + raise DistutilsError("A virtualenv %s already exists but not with the required python") + + else: + ok = False + + + # + # Creates a new virtualenv + # + if not ok: + venv.create(envname, + system_site_packages=False, + clear=True, + symlinks=False, + with_pip=True) + + # check the newly created virtualenv + return serenity_virtualenv(envname,package,version) + + return os.path.realpath(python) + + + \ No newline at end of file