Skip to content

Commit

Permalink
More robustness and improved diagnostics in os_setup.py.
Browse files Browse the repository at this point in the history
This change solves the `IndexError` raised in `os_setup.py` that was
reported in issue #556, and it makes the code more robust against
unexpected output of installer commands, and improves the diagnostics
in cases of unexpected output.

This change does not necessarily solve the root cause of the problem,
though.
  • Loading branch information
andy-maier committed Dec 13, 2016
1 parent 3058b8d commit e77e21a
Showing 1 changed file with 77 additions and 32 deletions.
109 changes: 77 additions & 32 deletions os_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -866,9 +866,18 @@ def is_installed(self, pkg_name, version_reqs=None):
return (False, False, None)

lines = out.splitlines()
version_line = [line for line in lines
if line.startswith("Version:")][0]
version = version_line.split()[1]
version_lines = [line for line in lines
if line.startswith("Version:")]
if len(version_lines) == 0:
raise DistutilsSetupError(
"Unexpected output from command '%s': No version line:\n%s" %
(cmd, out))
version_words = version_lines[0].split()
if len(version_words) < 2:
raise DistutilsSetupError(
"Unexpected output from command '%s': Version line has less "
"than two words:\n%s" % (cmd, out))
version = version_words[1]
version_sufficient = self.version_matches_req(version, version_reqs) \
if version_reqs else True
return (True, version_sufficient, version)
Expand Down Expand Up @@ -1241,13 +1250,16 @@ def is_installed(self, pkg_name, version_reqs=None):
rc, out, err = shell(cmd)
if rc != 0:
return (False, False, None)

info = out.splitlines()[-1].strip("\n").split()
if not info[0].startswith(pkg_name + "."):
info_words = out.splitlines()[-1].strip("\n").split()
if len(info_words) < 2:
raise DistutilsSetupError(
"Unexpected output from command '%s':\n%s%s" %
(cmd, out, err))
version = info[1].split("-")[0]
"Unexpected output from command '%s': Last line has less "
"than two words:\n%s" % (cmd, out))
if not info_words[0].startswith(pkg_name + "."):
raise DistutilsSetupError(
"Unexpected output from command '%s': Last line does not "
"begin with 'package-name.':\n%s" % (cmd, out))
version = info_words[1].split("-")[0]
version_sufficient = self.version_matches_req(version, version_reqs) \
if version_reqs else True
return (True, version_sufficient, version)
Expand All @@ -1265,13 +1277,16 @@ def is_available(self, pkg_name, version_reqs=None):
rc, out, err = shell(cmd)
if rc != 0:
return (False, False, None)

info = out.splitlines()[-1].strip("\n").split()
if not info[0].startswith(pkg_name + "."):
info_words = out.splitlines()[-1].strip("\n").split()
if len(info_words) < 2:
raise DistutilsSetupError(
"Unexpected output from command '%s': Last line has less "
"than two words:\n%s" % (cmd, out))
if not info_words[0].startswith(pkg_name + "."):
raise DistutilsSetupError(
"Unexpected output from command '%s':\n%s%s" %
(cmd, out, err))
version = info[1].split("-")[0]
"Unexpected output from command '%s': Last line does not "
"begin with 'package-name.':\n%s" % (cmd, out))
version = info_words[1].split("-")[0]
version_sufficient = self.version_matches_req(version, version_reqs) \
if version_reqs else True
return (True, version_sufficient, [version])
Expand Down Expand Up @@ -1312,14 +1327,27 @@ def is_installed(self, pkg_name, version_reqs=None):
return (False, False, None)

lines = out.splitlines()
status_line = [line for line in lines if line.startswith("Status:")][0]
version_line = [line for line in lines
if line.startswith("Version:")][0]
if status_line != "Status: install ok installed":
status_lines = [line for line in lines if line.startswith("Status:")]
if len(status_lines) < 1:
raise DistutilsSetupError(
"Unexpected output from command '%s': No status line:\n%s" %
(cmd, out))
if status_lines[0] != "Status: install ok installed":
raise DistutilsSetupError(
"Unexpected status output from command '%s':\n"
"%s%s" % (cmd, out, err))
version = version_line.split()[1].split("-")[0]
"%s" % (cmd, out))
version_lines = [line for line in lines
if line.startswith("Version:")]
if len(version_lines) < 1:
raise DistutilsSetupError(
"Unexpected output from command '%s': No version line:\n%s" %
(cmd, out))
version_words = version_lines[0].split()
if len(version_words) < 2:
raise DistutilsSetupError(
"Unexpected output from command '%s': Version line has less "
"than two words:\n%s" % (cmd, out))
version = version_words[1].split("-")[0]
if ":" in version:
version = version.split(":")[1]
# TODO: Add support for epoch number in the version
Expand All @@ -1342,9 +1370,18 @@ def is_available(self, pkg_name, version_reqs=None):
return (False, False, None)

lines = out.splitlines()
version_line = [line for line in lines
if line.startswith("Version:")][0]
version = version_line.split()[1].split("-")[0]
version_lines = [line for line in lines
if line.startswith("Version:")]
if len(version_lines) < 1:
raise DistutilsSetupError(
"Unexpected output from command '%s': No version line:\n%s" %
(cmd, out))
version_words = version_lines[0].split()
if len(version_words) < 2:
raise DistutilsSetupError(
"Unexpected output from command '%s': Version line has less "
"than two words:\n%s" % (cmd, out))
version = version_words[1].split("-")[0]
version_sufficient = self.version_matches_req(version, version_reqs) \
if version_reqs else True
return (True, version_sufficient, [version])
Expand Down Expand Up @@ -1384,12 +1421,16 @@ def is_installed(self, pkg_name, version_reqs=None):
if rc != 0:
return (False, False, None)

info = out.splitlines()[-1].strip("\n").split()
if not info[0].startswith(pkg_name + "."):
info_words = out.splitlines()[-1].strip("\n").split()
if len(info_words) < 2:
raise DistutilsSetupError(
"Unexpected output from command '%s': Last line has less "
"than two words:\n%s" % (cmd, out))
if not info_words[0].startswith(pkg_name + "."):
raise DistutilsSetupError(
"Unexpected output from command '%s':\n%s%s" %
(cmd, out, err))
version = info[1].split("-")[0]
"Unexpected output from command '%s': Last line does not "
"begin with 'package-name.':\n%s" % (cmd, out))
version = info_words[1].split("-")[0]
version_sufficient = self.version_matches_req(version, version_reqs) \
if version_reqs else True
return (True, version_sufficient, version)
Expand All @@ -1411,8 +1452,12 @@ def is_available(self, pkg_name, version_reqs=None):
if len(version_lines) == 0:
return (False, False, None)

version_line = version_lines[0]
version = version_line.split()[1].split("-")[0]
version_words = version_lines[0].split()
if len(version_words) < 2:
raise DistutilsSetupError(
"Unexpected output from command '%s': Version line has less "
"than two words:\n%s" % (cmd, out))
version = version_words[1].split("-")[0]
version_sufficient = self.version_matches_req(version, version_reqs) \
if version_reqs else True
return (True, version_sufficient, [version])
Expand Down Expand Up @@ -1542,7 +1587,7 @@ def import_setuptools(min_version="12.0"):
else:
if setuptools.__version__.split(".") < min_version.split("."):
raise DistutilsSetupError(
"The required version of setuptools (>=%s) is not available, "
"The required version of setuptools (>=%s) is not installed "
"and can't be\n"
"installed while this script is running. Please install the "
"required version\n"
Expand Down

0 comments on commit e77e21a

Please sign in to comment.