Add alpmfiles source

Rewritten from the `archfiles` source in archlinuxcn/lilac
This commit is contained in:
Pekka Ristola 2023-05-31 21:29:17 +03:00
parent af77af34f3
commit 8157e08b59
No known key found for this signature in database
GPG Key ID: 2C20BE716E05213E
3 changed files with 101 additions and 0 deletions

View File

@ -874,6 +874,29 @@ strip_release
provided
Instead of the package version, return the version this package provides. Its value is what the package provides, and ``strip_release`` takes effect too. This is best used with libraries.
Check ALPM files database
~~~~~~~~~~~~~~~~~~~~~~~~~
::
source = "alpmfiles"
Search package files in a local ALPM files database. The package does not need to be installed. This can be useful for checking shared library versions if a package does not list them in its ``provides``.
pkgname
Name of the package.
filename
Regular expression for the file path. If it contains one matching group, that group is returned. Otherwise return the whole file path. Paths do not have an initial slash. For example, ``usr/lib/libuv\\.so\\.([^.]+)`` matches the major shared library version of libuv.
repo
Name of the package repository in which the package resides. If not provided, search all repositories.
strip_dir
Strip directory from the path before matching. Defaults to ``false``.
dbpath
Path to the ALPM database directory. Default: ``/var/lib/pacman``. You need to update the database yourself with ``pacman -Fy``.
Check Open Vsx
~~~~~~~~~~~~~~~
::

View File

@ -0,0 +1,50 @@
# MIT licensed
# Copyright (c) 2023 Pekka Ristola <pekkarr [at] protonmail [dot] com>, et al.
from asyncio import create_subprocess_exec
from asyncio.subprocess import PIPE
import re
from nvchecker.api import GetVersionError
async def get_files(info: tuple) -> list:
dbpath, pkg = info
# there's no pyalpm bindings for the file databases
cmd = ['pacman', '-Flq', '--dbpath', dbpath, pkg]
p = await create_subprocess_exec(*cmd, stdout = PIPE, stderr = PIPE)
stdout, stderr = await p.communicate()
if p.returncode == 0:
return stdout.decode().splitlines()
else:
raise GetVersionError(
'pacman failed to get file list',
pkg = pkg,
cmd = cmd,
stdout = stdout.decode(errors='replace'),
stderr = stderr.decode(errors='replace'),
returncode = p.returncode,
)
async def get_version(name, conf, *, cache, **kwargs):
pkg = conf['pkgname']
repo = conf.get('repo')
if repo is not None:
pkg = f'{repo}/{pkg}'
dbpath = conf.get('dbpath', '/var/lib/pacman')
regex = re.compile(conf['filename'])
if regex.groups > 1:
raise GetVersionError('multi-group regex')
strip_dir = conf.get('strip_dir', False)
files = await cache.get((dbpath, pkg), get_files)
for f in files:
fn = f.rsplit('/', 1)[-1] if strip_dir else f
match = regex.fullmatch(fn)
if match:
groups = match.groups()
return groups[0] if len(groups) > 0 else fn
raise GetVersionError('no file matches specified regex')

28
tests/test_alpmfiles.py Normal file
View File

@ -0,0 +1,28 @@
# MIT licensed
# Copyright (c) 2023 Pekka Ristola <pekkarr [at] protonmail [dot] com>, et al.
import shutil
import pytest
pytestmark = [
pytest.mark.asyncio,
pytest.mark.skipif(shutil.which('pacman') is None, reason='requires pacman command'),
]
async def test_alpmfiles(get_version):
assert await get_version('test', {
'source': 'alpmfiles',
'pkgname': 'libuv',
'filename': 'usr/lib/libuv\\.so\\.([^.]+)',
}) == '1'
async def test_alpmfiles_strip(get_version):
assert await get_version('test', {
'source': 'alpmfiles',
'pkgname': 'glibc',
'repo': 'core',
'filename': 'libc\\.so\\.[^.]+',
'strip_dir': True,
'dbpath': '/var/lib/pacman',
}) == 'libc.so.6'