From 6f5c6f5404a611589a77210d9c153fb656a6923b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Thu, 23 Jul 2015 15:00:47 +0200 Subject: [PATCH] PipCaller now manages special parameters on its own The class knows about which pip versions support --process-dependency-links, which need --no-use-wheel and which are broken altogether and adds/removes these parameters accordingly or outright reports the broken pip version. --- .../plugins/pluginmanager/__init__.py | 3 --- .../plugins/softwareupdate/updaters/pip.py | 2 +- src/octoprint/util/pip.py | 25 ++++++++++++++++--- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/octoprint/plugins/pluginmanager/__init__.py b/src/octoprint/plugins/pluginmanager/__init__.py index 34b2a717..4e086a70 100644 --- a/src/octoprint/plugins/pluginmanager/__init__.py +++ b/src/octoprint/plugins/pluginmanager/__init__.py @@ -39,7 +39,6 @@ class PluginManagerPlugin(octoprint.plugin.SimpleApiPlugin, self._pending_uninstall = set() self._pip_caller = None - self._pip_version_dependency_links = pkg_resources.parse_version("1.5") self._repository_available = False self._repository_plugins = [] @@ -430,8 +429,6 @@ class PluginManagerPlugin(octoprint.plugin.SimpleApiPlugin, if "--process-dependency-links" in args: self._log_message(u"Installation needs to process external dependencies, that might make it take a bit longer than usual depending on the pip version") - if self._pip_caller < self._pip_version_dependency_links: - args.remove("--process-dependency-links") return self._pip_caller.execute(*args) diff --git a/src/octoprint/plugins/softwareupdate/updaters/pip.py b/src/octoprint/plugins/softwareupdate/updaters/pip.py index c72f2c4c..be15b7e6 100644 --- a/src/octoprint/plugins/softwareupdate/updaters/pip.py +++ b/src/octoprint/plugins/softwareupdate/updaters/pip.py @@ -67,7 +67,7 @@ def perform_update(target, check, target_version, log_cb=None): logger.debug(u"Target: %s, executing pip install %s" % (target, install_arg)) pip_args = ["install", check["pip"].format(target_version=target_version, target=target_version)] - if "dependency_links" in check and check["dependency_links"] and pip_caller >= _pip_version_dependency_links: + if "dependency_links" in check and check["dependency_links"]: pip_args += ["--process-dependency-links"] pip_caller.execute(*pip_args) diff --git a/src/octoprint/util/pip.py b/src/octoprint/util/pip.py index 4117546d..c805c21f 100644 --- a/src/octoprint/util/pip.py +++ b/src/octoprint/util/pip.py @@ -10,6 +10,8 @@ import sarge import sys import logging +import pkg_resources + from .commandline import CommandlineCaller @@ -17,6 +19,10 @@ class UnknownPip(Exception): pass class PipCaller(CommandlineCaller): + process_dependency_links = pkg_resources.parse_requirements("pip>=1.5") + no_use_wheel = pkg_resources.parse_requirements("pip==1.5.0") + broken = pkg_resources.parse_requirements("pip>=6.0.1,<=6.0.3") + def __init__(self, configured=None): CommandlineCaller.__init__(self) self._logger = logging.getLogger(__name__) @@ -62,7 +68,16 @@ class PipCaller(CommandlineCaller): if self._command is None: raise UnknownPip() - command = [self._command] + list(args) + arg_list = list(args) + if "install" in arg_list: + if not self.version in self.__class__.process_dependency_links and "--process-dependency-links" in arg_list: + self._logger.debug("Found --process-dependency-links flag, version {} doesn't need that yet though, removing.".format(self.version)) + arg_list.remove("--process-dependency-links") + if self.version in self.__class__.no_use_wheel and not "--no-use-wheel" in arg_list: + self._logger.debug("Version {} needs --no-use-wheel to properly work.".format(self.version)) + arg_list.append("--no-use-wheel") + + command = [self._command] + arg_list return self.call(command) def _find_pip(self): @@ -121,12 +136,16 @@ class PipCaller(CommandlineCaller): version_segment = split_output[1] - from pkg_resources import parse_version try: - pip_version = parse_version(version_segment) + pip_version = pkg_resources.parse_version(version_segment) except: self._logger.exception("Error while trying to parse version string from pip command") + return None, None else: self._logger.info("Found pip at {}, version is {}".format(pip_command, version_segment)) + if pip_version in self.__class__.broken: + self._logger.error("This version of pip is known to have errors that make it incompatible with how it needs to be used by OctoPrint. Please upgrade your pip version.") + return None, None + return pip_command, pip_version