From 1a46416ebc462142e3faa6129e88a9187144eb14 Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Fri, 6 Dec 2019 19:51:11 +0100 Subject: [PATCH 1/4] Fix mulled version comparison Mulled tags are composed like this: `-- where `` ends with `_build_number`. To get the last build this sorts by build build string, then by build number and finally by build version. --- lib/galaxy/tool_util/deps/mulled/util.py | 31 ++++++++++++++++--- .../unit/tool_util/mulled/test_mulled_util.py | 12 +++++++ 2 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 test/unit/tool_util/mulled/test_mulled_util.py diff --git a/lib/galaxy/tool_util/deps/mulled/util.py b/lib/galaxy/tool_util/deps/mulled/util.py index f394a907278..7eaea481a53 100644 --- a/lib/galaxy/tool_util/deps/mulled/util.py +++ b/lib/galaxy/tool_util/deps/mulled/util.py @@ -3,6 +3,7 @@ from __future__ import print_function import collections import hashlib +import re import sys import threading import time @@ -13,7 +14,9 @@ try: except ImportError: requests = None +BUILD_NUMBER_REGEX = re.compile(r'\d+$') MULLED_TAG_CACHE = collections.defaultdict(dict) +PARSED_TAG = collections.namedtuple('ParsedTag', 'tag version build_string build_number') def create_repository(namespace, repo_name, oauth_token): @@ -38,7 +41,7 @@ def quay_versions(namespace, pkg_name): if 'tags' not in data: raise Exception("Unexpected response from quay.io - not tags description found [%s]" % data) - return [tag for tag in data['tags'] if tag != 'latest'] + return [tag for tag in data['tags'].keys() if tag != 'latest'] def quay_repository(namespace, pkg_name): @@ -79,14 +82,32 @@ def mulled_tags_for(namespace, image, tag_prefix=None): def split_tag(tag): """Split mulled image name into conda version and conda build.""" - version = tag.split('--', 1)[0] - build = tag.split('--', 1)[1] - return version, build + return tag.split('--', 1) + + +def parse_tag(tag): + """Split mulled image name into version and build number.""" + version = tag + build_string = "-1" + if '--' in tag: + version, build_string = tag.rsplit('--', 1) + elif '-' in tag: + # Should be mulled multi-container image tag + version, build_string = tag.rsplit('-', 1) + build_number = int(BUILD_NUMBER_REGEX.search(tag).group(0)) + return PARSED_TAG(tag=tag, + version=packaging.version.parse(version), + build_string=packaging.version.parse(build_string), + build_number=build_number) def version_sorted(elements): """Sort iterable based on loose description of "version" from newest to oldest.""" - return sorted(elements, key=packaging.version.parse, reverse=True) + elements = (parse_tag(tag) for tag in elements) + elements = sorted(elements, key=lambda tag: tag.build_string, reverse=True) + elements = sorted(elements, key=lambda tag: tag.build_number, reverse=True) + elements = sorted(elements, key=lambda tag: tag.version) + return [e.tag for e in elements] Target = collections.namedtuple("Target", ["package_name", "version", "build"]) diff --git a/test/unit/tool_util/mulled/test_mulled_util.py b/test/unit/tool_util/mulled/test_mulled_util.py new file mode 100644 index 00000000000..1ccf73dffed --- /dev/null +++ b/test/unit/tool_util/mulled/test_mulled_util.py @@ -0,0 +1,12 @@ +import pytest + +from galaxy.tool_util.deps.mulled.util import version_sorted + + +@pytest.mark.parametrize("tags,tag", [ + (["2.22--he941832_1", "2.22--he860b03_2", "2.22--hdbcaa40_3"], "2.22--hdbcaa40_3"), + (["1.1.2--py27_0", "1.1.2--py36_0", "1.1.2--py35_0"], "1.1.2--py36_0"), + (["6725cda82000b8e514baddcbf8c2dce054e3f797-1", "6725cda82000b8e514baddcbf8c2dce054e3f797-0"], "6725cda82000b8e514baddcbf8c2dce054e3f797-1") +]) +def test_version_sorted(tags, tag): + assert version_sorted(tags)[0] == tag From 77526dbcc34e548d8ff6e2790004196a93064b62 Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Sun, 8 Dec 2019 12:44:31 +0100 Subject: [PATCH 2/4] Fix docstring of parse_tag method Thanks @bgruening! --- lib/galaxy/tool_util/deps/mulled/util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/galaxy/tool_util/deps/mulled/util.py b/lib/galaxy/tool_util/deps/mulled/util.py index 7eaea481a53..93966573539 100644 --- a/lib/galaxy/tool_util/deps/mulled/util.py +++ b/lib/galaxy/tool_util/deps/mulled/util.py @@ -86,7 +86,7 @@ def split_tag(tag): def parse_tag(tag): - """Split mulled image name into version and build number.""" + """Decompose tag of mulled images into version, build string and build number.""" version = tag build_string = "-1" if '--' in tag: From 35c8794ac1807d08e617d67ab1f1f63ab2f05333 Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Sun, 8 Dec 2019 12:46:22 +0100 Subject: [PATCH 3/4] Use rsplit in split_tag method --- lib/galaxy/tool_util/deps/mulled/util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/galaxy/tool_util/deps/mulled/util.py b/lib/galaxy/tool_util/deps/mulled/util.py index 93966573539..2888e05830f 100644 --- a/lib/galaxy/tool_util/deps/mulled/util.py +++ b/lib/galaxy/tool_util/deps/mulled/util.py @@ -82,7 +82,7 @@ def mulled_tags_for(namespace, image, tag_prefix=None): def split_tag(tag): """Split mulled image name into conda version and conda build.""" - return tag.split('--', 1) + return tag.rsplit('--', 1) def parse_tag(tag): From ad0d8e7eee9dc7648dedde30c499b04115206940 Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Mon, 9 Dec 2019 17:16:22 +0100 Subject: [PATCH 4/4] Fix split_tag docstring --- lib/galaxy/tool_util/deps/mulled/util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/galaxy/tool_util/deps/mulled/util.py b/lib/galaxy/tool_util/deps/mulled/util.py index 2888e05830f..226b6dd9811 100644 --- a/lib/galaxy/tool_util/deps/mulled/util.py +++ b/lib/galaxy/tool_util/deps/mulled/util.py @@ -81,7 +81,7 @@ def mulled_tags_for(namespace, image, tag_prefix=None): def split_tag(tag): - """Split mulled image name into conda version and conda build.""" + """Split mulled image tag into conda version and conda build.""" return tag.rsplit('--', 1)