diff --git a/src/ahriman/core/repository/update_handler.py b/src/ahriman/core/repository/update_handler.py index 667185ab..a3246c27 100644 --- a/src/ahriman/core/repository/update_handler.py +++ b/src/ahriman/core/repository/update_handler.py @@ -20,6 +20,7 @@ from collections.abc import Iterable from ahriman.core.build_tools.sources import Sources +from ahriman.core.exceptions import UnknownPackageError from ahriman.core.repository.cleaner import Cleaner from ahriman.models.package import Package from ahriman.models.package_source import PackageSource @@ -53,6 +54,19 @@ class UpdateHandler(Cleaner): Returns: list[Package]: list of packages which are out-of-dated """ + def load_remote(package: Package) -> Package: + source = package.remote.source if package.remote is not None else None + + # try to load package from base and if none found try to load by separated packages + for probe in [package.base] + sorted(package.packages.keys()): + try: + if source == PackageSource.Repository: + return Package.from_official(probe, self.pacman, None) + return Package.from_aur(probe, self.pacman, None) + except UnknownPackageError: + continue + raise UnknownPackageError(package.base) + result: list[Package] = [] for local in self.packages(): @@ -61,13 +75,9 @@ class UpdateHandler(Cleaner): continue if filter_packages and local.base not in filter_packages: continue - source = local.remote.source if local.remote is not None else None try: - if source == PackageSource.Repository: - remote = Package.from_official(local.base, self.pacman, None) - else: - remote = Package.from_aur(local.base, self.pacman, None) + remote = load_remote(local) if local.is_outdated( remote, self.paths, diff --git a/tests/ahriman/core/repository/test_update_handler.py b/tests/ahriman/core/repository/test_update_handler.py index d190242b..506d7a47 100644 --- a/tests/ahriman/core/repository/test_update_handler.py +++ b/tests/ahriman/core/repository/test_update_handler.py @@ -2,7 +2,9 @@ import pytest from pathlib import Path from pytest_mock import MockerFixture +from typing import Any +from ahriman.core.exceptions import UnknownPackageError from ahriman.core.repository.update_handler import UpdateHandler from ahriman.models.package import Package from ahriman.models.package_source import PackageSource @@ -107,6 +109,35 @@ def test_updates_aur_ignore_vcs(update_handler: UpdateHandler, package_ahriman: calculate_version=False) +def test_updates_aur_load_by_package(update_handler: UpdateHandler, package_python_schedule: Package, + mocker: MockerFixture) -> None: + """ + must load package by package name if none found by base + """ + def package_selector(name: str, *_: Any) -> Package: + if name == package_python_schedule.base: + raise UnknownPackageError(name) + return package_python_schedule + + mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.packages", + return_value=[package_python_schedule]) + mocker.patch("ahriman.models.package.Package.from_aur", side_effect=package_selector) + mocker.patch("ahriman.models.package.Package.is_outdated", return_value=True) + assert update_handler.updates_aur([], vcs=True) == [package_python_schedule] + + +def test_updates_load_by_package_aur_failed(update_handler: UpdateHandler, package_ahriman: Package, + mocker: MockerFixture) -> None: + """ + must update status via client for failed load + """ + mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.packages", return_value=[package_ahriman]) + mocker.patch("ahriman.models.package.Package.from_aur", side_effect=UnknownPackageError(package_ahriman.base)) + mocker.patch("ahriman.core.status.client.Client.set_failed") + + update_handler.updates_aur([], vcs=True) + + def test_updates_local(update_handler: UpdateHandler, package_ahriman: Package, mocker: MockerFixture) -> None: """ must check for updates for locally stored packages