get version comparison from semver

since Python is removing version string parsing from the standard library

moves Julia-specific semver utilities to top-level
pull/1122/head
Min RK 2022-01-26 09:29:21 +01:00
rodzic 8ab5c81245
commit d728a64dd9
6 zmienionych plików z 49 dodań i 5 usunięć

Wyświetl plik

@ -3,7 +3,7 @@ Base information for using R in BuildPacks.
Keeping this in r.py would lead to cyclic imports. Keeping this in r.py would lead to cyclic imports.
""" """
from distutils.version import LooseVersion as V from ..semver import parse_version as V
def rstudio_base_scripts(r_version): def rstudio_base_scripts(r_version):

Wyświetl plik

@ -1,10 +1,13 @@
"""Generates a Dockerfile based on an input matrix for Julia""" """Generates a Dockerfile based on an input matrix for Julia"""
import functools import functools
import os import os
import requests import requests
import semver
import toml import toml
from ..python import PythonBuildPack from ..python import PythonBuildPack
from .semver import find_semver_match, semver from ...semver import find_semver_match
class JuliaProjectTomlBuildPack(PythonBuildPack): class JuliaProjectTomlBuildPack(PythonBuildPack):

Wyświetl plik

@ -1,9 +1,9 @@
"""Generates a Dockerfile based on an input matrix with REQUIRE for legacy Julia""" """Generates a Dockerfile based on an input matrix with REQUIRE for legacy Julia"""
from distutils.version import LooseVersion as V
import os import os
from ..python import PythonBuildPack from ..python import PythonBuildPack
from ...semver import parse_version as V
class JuliaRequireBuildPack(PythonBuildPack): class JuliaRequireBuildPack(PythonBuildPack):

Wyświetl plik

@ -3,8 +3,8 @@ import os
import datetime import datetime
import requests import requests
from distutils.version import LooseVersion as V
from ..semver import parse_version as V
from .python import PythonBuildPack from .python import PythonBuildPack
from ._r_base import rstudio_base_scripts from ._r_base import rstudio_base_scripts

Wyświetl plik

@ -12,11 +12,13 @@ constraints.
import re import re
from functools import lru_cache
import semver import semver
def find_semver_match(constraint, versions_list): def find_semver_match(constraint, versions_list):
"""Find first version in a list of versions that matches a constraint"""
matcher = create_semver_matcher(constraint) matcher = create_semver_matcher(constraint)
for vstr in reversed(versions_list): for vstr in reversed(versions_list):
if matcher.match(str_to_version(vstr)): if matcher.match(str_to_version(vstr)):
@ -25,9 +27,29 @@ def find_semver_match(constraint, versions_list):
def str_to_version(vstr): def str_to_version(vstr):
"""Convert a simple x[.y[.z]] version string to a tuple of ints"""
return tuple([int(n) for n in vstr.split(".")]) return tuple([int(n) for n in vstr.split(".")])
@lru_cache()
def parse_version(vstr):
"""Convert a simple 'x[.y[.z]]' version string to a comparable VersionInfo
Wraps semver.VersionInfo.parse with zero-padding,
so it can accept '1.0', where upstream only accepts exactly 3 version fields.
"""
try:
return semver.VersionInfo.parse(vstr)
except ValueError:
# may fail for e.g. short 1.0 versions
n_fields = vstr.count(".")
if n_fields < 2:
vstr = vstr + (".0" * (2 - n_fields))
return semver.VersionInfo.parse(vstr)
else:
raise
# Helpers # Helpers
def major(v): def major(v):
return v[0] return v[0]
@ -41,6 +63,7 @@ def patch(v):
return v[2] if len(v) >= 3 else 0 return v[2] if len(v) >= 3 else 0
@lru_cache()
def create_semver_matcher(constraint_str): def create_semver_matcher(constraint_str):
"""Create a matcher that can be used to match version tuples """Create a matcher that can be used to match version tuples

Wyświetl plik

@ -1,5 +1,6 @@
import pytest import pytest
from repo2docker.buildpacks.julia import semver from semver import VersionInfo
from repo2docker import semver
@pytest.mark.parametrize("test_input, expected", [("1.5.2", (1, 5, 2)), ("1", (1,))]) @pytest.mark.parametrize("test_input, expected", [("1.5.2", (1, 5, 2)), ("1", (1,))])
@ -145,3 +146,20 @@ def test_largerthan_equal():
semver.create_semver_matcher(">=1.2.3").match(semver.str_to_version("1.2.2")) semver.create_semver_matcher(">=1.2.3").match(semver.str_to_version("1.2.2"))
== False == False
) )
@pytest.mark.parametrize(
"vstr, expected",
[
("1.2.3", "1.2.3"),
("1.2", "1.2.0"),
("1", "1.0.0"),
],
)
def test_parse_version(vstr, expected):
version_info = semver.parse_version(vstr)
assert isinstance(version_info, semver.semver.VersionInfo)
assert str(version_info) == expected
# satisfies itself, since this is how we use it
assert semver.parse_version(expected) <= version_info
assert semver.parse_version(expected) >= version_info