SWU Fix: properly sanitize version strings for comparison

This commit is contained in:
Gina Häußge 2015-07-05 10:04:06 +02:00
parent 19b4a0f403
commit 29d49179a9

View file

@ -44,35 +44,71 @@ def _get_latest_release(user, repo, include_prerelease=False):
return latest["name"], latest["tag_name"]
def _is_current(release_information, compare_type, custom=None):
def _get_sanitized_version(version_string):
if "-" in version_string:
version_string = version_string[:version_string.find("-")]
return version_string
def _get_comparable_version_pkg_resources(version_string, force_base=True):
import pkg_resources
version = pkg_resources.parse_version(version_string)
if force_base:
if isinstance(version, tuple):
# old setuptools
base_version = []
for part in version:
if part.startswith("*"):
break
base_version.append(part)
version = tuple(base_version)
else:
# new setuptools
version = pkg_resources.parse_version(version.base_version)
return version
def _get_comparable_version_semantic(version_string, force_base=True):
import semantic_version
version = semantic_version.Version.coerce(version_string, partial=False)
if force_base:
version_string = "{}.{}.{}".format(version.major, version.minor, version.patch)
version = semantic_version.Version.coerce(version_string, partial=False)
return version
def _is_current(release_information, compare_type, custom=None, force_base=True):
if release_information["remote"]["value"] is None:
return True
if not compare_type in ("python", "semantic", "unequal", "custom") or compare_type == "custom" and custom is None:
compare_type = "python"
sanitized_local = _get_sanitized_version(release_information["local"]["value"])
sanitized_remote = _get_sanitized_version(release_information["remote"]["value"])
try:
if compare_type == "python":
import pkg_resources
local_version = pkg_resources.parse_version(release_information["local"]["value"])
remote_version = pkg_resources.parse_version(release_information["remote"]["value"])
local_version = _get_comparable_version_pkg_resources(sanitized_local, force_base=force_base)
remote_version = _get_comparable_version_pkg_resources(sanitized_remote, force_base=force_base)
return local_version >= remote_version
elif compare_type == "semantic":
import semantic_version
local_version = semantic_version.Version(release_information["local"]["value"])
remote_version = semantic_version.Version(release_information["remote"]["value"])
local_version = _get_comparable_version_semantic(sanitized_local, force_base=force_base)
remote_version = _get_comparable_version_semantic(sanitized_remote, force_base=force_base)
return local_version >= remote_version
elif compare_type == "custom":
return custom(release_information["local"], release_information["remote"])
return custom(sanitized_local, sanitized_remote)
else:
return release_information["local"]["value"] == release_information["remote"]["value"]
return sanitized_local == sanitized_remote
except:
logger.exception("Could not check if version is current due to an error, assuming it is")
return True
@ -82,11 +118,13 @@ def get_latest(target, check, custom_compare=None):
if not "user" in check or not "repo" in check:
raise ConfigurationInvalid("github_release update configuration for %s needs user and repo set" % target)
current = None
if "current" in check:
current = check["current"]
current = check.get("current", None)
include_prerelease = check.get("prerelease", False)
force_base = check.get("force_base", True)
remote_name, remote_tag = _get_latest_release(check["user"], check["repo"], include_prerelease=check["prerelease"] == True if "prerelease" in check else False)
remote_name, remote_tag = _get_latest_release(check["user"],
check["repo"],
include_prerelease=include_prerelease)
compare_type = check["release_compare"] if "release_compare" in check else "python"
information =dict(
@ -96,4 +134,7 @@ def get_latest(target, check, custom_compare=None):
logger.debug("Target: %s, local: %s, remote: %s" % (target, current, remote_tag))
return information, _is_current(information, compare_type, custom=custom_compare)
return information, _is_current(information,
compare_type,
custom=custom_compare,
force_base=force_base)