diff --git a/nvchecker/get_version.py b/nvchecker/get_version.py index 70165bb..68ef721 100644 --- a/nvchecker/get_version.py +++ b/nvchecker/get_version.py @@ -15,7 +15,7 @@ handler_precedence = ( 'gems', 'pacman', 'cmd', 'bitbucket', 'regex', 'manual', 'vcs', 'cratesio', 'npm', 'hackage', 'cpan', 'gitlab', 'packagist', - 'anitya', 'android_sdk', + 'repology', 'anitya', 'android_sdk', ) def substitute_version(version, name, conf): diff --git a/nvchecker/source/repology.py b/nvchecker/source/repology.py new file mode 100644 index 0000000..c602f55 --- /dev/null +++ b/nvchecker/source/repology.py @@ -0,0 +1,33 @@ +# MIT licensed +# Copyright (c) 2019 lilydjwg , et al. + +import structlog +import functools + +from . import session + +logger = structlog.get_logger(logger_name=__name__) + +API_URL = 'https://repology.org/api/v1/project/{}' + +async def get_version(name, conf, **kwargs): + project = conf.get('repology') or name + repo = conf.get('repo') + if not repo: + logger.error('repo field is required for repology source', name = name) + + + url = API_URL.format(project) + data = await _request(url) + + versions = [pkg['version'] for pkg in data if pkg['repo'] == repo] + if not versions: + logger.error('package is not found', name=name, repo=repo) + return + + return versions[0] + +@functools.lru_cache() +async def _request(url): + async with session.get(url) as res: + return await res.json() diff --git a/tests/test_repology.py b/tests/test_repology.py new file mode 100644 index 0000000..4da0b63 --- /dev/null +++ b/tests/test_repology.py @@ -0,0 +1,15 @@ +# MIT licensed +# Copyright (c) 2019 lilydjwg , et al. + +import pytest +pytestmark = [pytest.mark.asyncio, + pytest.mark.needs_net] + +async def test_repology(get_version): + assert await get_version("ssed", {"repology": None, "repo": "aur"}) == "3.62" + +async def test_repology_no_repo(get_version): + try: + assert await get_version("ssed", {"repology": None}) is None + except RuntimeError as e: + assert "repo field is required" in str(e)