From d5cc27600075562a689981971937c11a20d3ec4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ila=C3=AF=20Deutel?= Date: Fri, 27 Sep 2024 00:10:21 -0400 Subject: [PATCH 1/2] crates.io: skip pre-releases, list option This adds a `use_pre_release` option and adds support for list option for crates.io, similar to PyPI. --- docs/usage.rst | 5 +++++ nvchecker_source/cratesio.py | 35 ++++++++++++++++++++++++++++++----- tests/test_cratesio.py | 20 ++++++++++++++++++++ 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/docs/usage.rst b/docs/usage.rst index 642c82d5..98b65254 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -661,6 +661,11 @@ Check `crates.io `_ for updates. cratesio The crate name on crates.io, e.g. ``tokio``. +use_pre_release + Whether to accept pre release. Default is false. + +This source supports :ref:`list options`. + Check Local Pacman Database ~~~~~~~~~~~~~~~~~~~~~~~~~~~ :: diff --git a/nvchecker_source/cratesio.py b/nvchecker_source/cratesio.py index 7c1f0d17..6aa0aeb0 100644 --- a/nvchecker_source/cratesio.py +++ b/nvchecker_source/cratesio.py @@ -1,15 +1,40 @@ # MIT licensed # Copyright (c) 2013-2020 lilydjwg , et al. +import re + +import structlog + from nvchecker.api import RichResult +logger = structlog.get_logger(logger_name=__name__) + + API_URL = 'https://crates.io/api/v1/crates/%s' +# https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string +VERSION_PATTERN = r'^(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)(?:-(?P(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$' + async def get_version(name, conf, *, cache, **kwargs): name = conf.get('cratesio') or name + use_pre_release = conf.get('use_pre_release', False) data = await cache.get_json(API_URL % name) - version = [v['num'] for v in data['versions'] if not v['yanked']][0] - return RichResult( - version = version, - url = f'https://crates.io/crates/{name}/{version}', - ) + results = [] + for v in data['versions']: + if v['yanked']: + continue + version = v['num'] + match = re.fullmatch(VERSION_PATTERN, version) + if match is None: + logger.warning('ignoring invalid version', version=version) + continue + if not use_pre_release and match.group('prerelease'): + continue + results.append( + RichResult( + version=version, + url=f'https://crates.io/crates/{name}/{version}', + ) + ) + + return results diff --git a/tests/test_cratesio.py b/tests/test_cratesio.py index bb4bf25f..ee397c5b 100644 --- a/tests/test_cratesio.py +++ b/tests/test_cratesio.py @@ -8,3 +8,23 @@ async def test_cratesio(get_version): assert await get_version("example", { "source": "cratesio", }) == "1.1.0" + +async def test_cratesio_list(get_version): + assert await get_version("example", { + "source": "cratesio", + "include_regex": r"^1\.0.*", + }) == "1.0.2" + +async def test_cratesio_skip_prerelease(get_version): + with pytest.raises(RuntimeError, match='include_regex matched no versions'): + await get_version("cargo-lock", { + "source": "cratesio", + "include_regex": r".*-.*", + }) + +async def test_cratesio_use_prerelease(get_version): + await get_version("cargo-lock", { + "source": "cratesio", + "use_pre_release": "true", + "include_regex": r".*-.*", + }) From 5b561456ae634f07e10f72d43051dff9d93d87a4 Mon Sep 17 00:00:00 2001 From: lilydjwg Date: Fri, 27 Sep 2024 12:36:44 +0800 Subject: [PATCH 2/2] update tests --- tests/test_android_sdk.py | 2 +- tests/test_archpkg.py | 4 ++-- tests/test_launchpad.py | 2 +- tests/test_pypi.py | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/test_android_sdk.py b/tests/test_android_sdk.py index 957a67c8..a9485cbf 100644 --- a/tests/test_android_sdk.py +++ b/tests/test_android_sdk.py @@ -17,7 +17,7 @@ async def test_android_package(get_version): "source": "android_sdk", "android_sdk": "cmake;", "repo": "package", - }) == "3.22.1" + }) == "3.30.3" async def test_android_package_channel(get_version): diff --git a/tests/test_archpkg.py b/tests/test_archpkg.py index 410686c4..3f023289 100644 --- a/tests/test_archpkg.py +++ b/tests/test_archpkg.py @@ -26,9 +26,9 @@ async def test_archpkg_provided(get_version): @pytest.mark.flaky async def test_archpkg_provided_strip(get_version): - assert await get_version("jsoncpp", { + int(await get_version("jsoncpp", { "source": "archpkg", "provided": "libjsoncpp.so", "strip_release": True, - }) == "25" + })) diff --git a/tests/test_launchpad.py b/tests/test_launchpad.py index 3dd0100c..090c1263 100644 --- a/tests/test_launchpad.py +++ b/tests/test_launchpad.py @@ -12,4 +12,4 @@ async def test_launchpad(get_version): } ) - assert version == '3.8.7' + assert version == '3.8.8' diff --git a/tests/test_pypi.py b/tests/test_pypi.py index b5531a72..03fecd27 100644 --- a/tests/test_pypi.py +++ b/tests/test_pypi.py @@ -25,7 +25,7 @@ async def test_pypi_list(get_version): assert await get_version("urllib3", { "source": "pypi", "include_regex": "^1\\..*", - }) == "1.26.19" + }) == "1.26.20" async def test_pypi_invalid_version(get_version): await get_version("sympy", {