From 4c5caba6b77136fa96d1290a37e7f959543dad2b Mon Sep 17 00:00:00 2001 From: Evgenii Alekseev Date: Tue, 8 Jul 2025 16:20:00 +0300 Subject: [PATCH] fix: trim provides/depends versions and lookup provides through pkgname (#150) Current implementation did it in wrong way. First of all, there was a lookup through pkgbase instead of pkgname, which lead to errors, because aur api doesn't allow to search by pkgbase (as well as provides is basically pkgname instead) It also was found that dependencies resolution lookup has been performed by using raw packages array, which can include versions, descriptions etc --- src/ahriman/core/alpm/pacman.py | 3 ++- src/ahriman/core/alpm/remote/aur.py | 2 +- src/ahriman/models/aur_package.py | 13 +++++++++++- src/ahriman/models/package_description.py | 5 +++-- tests/ahriman/core/alpm/test_pacman.py | 1 + tests/ahriman/models/test_aur_package.py | 21 ++++++++++++++++++- .../models/test_package_description.py | 11 +++++++--- 7 files changed, 47 insertions(+), 9 deletions(-) diff --git a/src/ahriman/core/alpm/pacman.py b/src/ahriman/core/alpm/pacman.py index 4865e35a..e7f6cd0a 100644 --- a/src/ahriman/core/alpm/pacman.py +++ b/src/ahriman/core/alpm/pacman.py @@ -267,7 +267,8 @@ class Pacman(LazyLogging): Package: list of packages which were returned by the query """ def is_package_provided(package: Package) -> bool: - return package_name in package.provides + provides = [trim_package(name) for name in package.provides] + return package_name in provides for database in self.handle.get_syncdbs(): yield from filter(is_package_provided, database.search(package_name)) diff --git a/src/ahriman/core/alpm/remote/aur.py b/src/ahriman/core/alpm/remote/aur.py index f6cb0b08..bbe9d8a2 100644 --- a/src/ahriman/core/alpm/remote/aur.py +++ b/src/ahriman/core/alpm/remote/aur.py @@ -146,7 +146,7 @@ class AUR(Remote): # search api provides reduced models for stub in self.package_search(package_name, pacman=pacman, search_by="provides") # verity that found package actually provides it - if package_name in (package := self.package_info(stub.package_base, pacman=pacman)).provides + if package_name in (package := self.package_info(stub.name, pacman=pacman)).provides ] def package_search(self, *keywords: str, pacman: Pacman | None, search_by: str | None) -> list[AURPackage]: diff --git a/src/ahriman/models/aur_package.py b/src/ahriman/models/aur_package.py index bca05ba9..6915fd1d 100644 --- a/src/ahriman/models/aur_package.py +++ b/src/ahriman/models/aur_package.py @@ -25,7 +25,7 @@ from dataclasses import dataclass, field, fields from pyalpm import Package # type: ignore[import-not-found] from typing import Any, Self -from ahriman.core.utils import filter_json, full_version +from ahriman.core.utils import filter_json, full_version, trim_package @dataclass(frozen=True, kw_only=True) @@ -103,6 +103,17 @@ class AURPackage: keywords: list[str] = field(default_factory=list) groups: list[str] = field(default_factory=list) + def __post_init__(self) -> None: + """ + update packages lists accordingly + """ + object.__setattr__(self, "depends", [trim_package(package) for package in self.depends]) + object.__setattr__(self, "make_depends", [trim_package(package) for package in self.make_depends]) + object.__setattr__(self, "opt_depends", [trim_package(package) for package in self.opt_depends]) + object.__setattr__(self, "check_depends", [trim_package(package) for package in self.check_depends]) + object.__setattr__(self, "conflicts", [trim_package(package) for package in self.conflicts]) + object.__setattr__(self, "provides", [trim_package(package) for package in self.provides]) + @classmethod def from_json(cls, dump: dict[str, Any]) -> Self: """ diff --git a/src/ahriman/models/package_description.py b/src/ahriman/models/package_description.py index ef36ef1f..8c4538c8 100644 --- a/src/ahriman/models/package_description.py +++ b/src/ahriman/models/package_description.py @@ -83,12 +83,13 @@ class PackageDescription: def __post_init__(self) -> None: """ - update dependencies list accordingly + update packages lists accordingly """ self.depends = [trim_package(package) for package in self.depends] - self.opt_depends = [trim_package(package) for package in self.opt_depends] self.make_depends = [trim_package(package) for package in self.make_depends] + self.opt_depends = [trim_package(package) for package in self.opt_depends] self.check_depends = [trim_package(package) for package in self.check_depends] + self.provides = [trim_package(package) for package in self.provides] @property def filepath(self) -> Path | None: diff --git a/tests/ahriman/core/alpm/test_pacman.py b/tests/ahriman/core/alpm/test_pacman.py index 2070301e..76c6db49 100644 --- a/tests/ahriman/core/alpm/test_pacman.py +++ b/tests/ahriman/core/alpm/test_pacman.py @@ -289,3 +289,4 @@ def test_package_provided_by(pacman: Pacman) -> None: must search through the provides lists """ assert list(pacman.provided_by("sh")) + assert list(pacman.provided_by("libacl.so")) # case with exact version diff --git a/tests/ahriman/models/test_aur_package.py b/tests/ahriman/models/test_aur_package.py index 8936f219..68844942 100644 --- a/tests/ahriman/models/test_aur_package.py +++ b/tests/ahriman/models/test_aur_package.py @@ -2,7 +2,7 @@ import datetime import json import pyalpm # typing: ignore -from dataclasses import asdict, fields +from dataclasses import asdict, fields, replace from pathlib import Path from pytest_mock import MockerFixture from typing import Any @@ -38,6 +38,25 @@ def _get_official_data(resource_path_root: Path) -> dict[str, Any]: return json.loads(response)["results"][0] +def test_post_init(aur_package_ahriman: AURPackage) -> None: + """ + must trim versions and descriptions from packages list + """ + package = replace( + aur_package_ahriman, + depends=["a=1"], + make_depends=["b>=3"], + opt_depends=["c: a description"], + check_depends=["d=4"], + provides=["e=5"], + ) + assert package.depends == ["a"] + assert package.make_depends == ["b"] + assert package.opt_depends == ["c"] + assert package.check_depends == ["d"] + assert package.provides == ["e"] + + def test_from_json(aur_package_ahriman: AURPackage, resource_path_root: Path) -> None: """ must load package from json diff --git a/tests/ahriman/models/test_package_description.py b/tests/ahriman/models/test_package_description.py index 30c72a69..a89c0222 100644 --- a/tests/ahriman/models/test_package_description.py +++ b/tests/ahriman/models/test_package_description.py @@ -6,10 +6,15 @@ from ahriman.models.package_description import PackageDescription def test_post_init() -> None: """ - must trim versions and descriptions from dependencies list + must trim versions and descriptions from packages list """ - assert PackageDescription(depends=["a=1"], make_depends=["b>=3"], opt_depends=["c: a description"]) == \ - PackageDescription(depends=["a"], make_depends=["b"], opt_depends=["c"]) + assert PackageDescription( + depends=["a=1"], + make_depends=["b>=3"], + opt_depends=["c: a description"], + check_depends=["d=4"], + provides=["e=5"] + ) == PackageDescription(depends=["a"], make_depends=["b"], opt_depends=["c"], check_depends=["d"], provides=["e"]) def test_filepath(package_description_ahriman: PackageDescription) -> None: