diff --git a/src/ahriman/application/ahriman.py b/src/ahriman/application/ahriman.py index 5516584f..2afb3981 100644 --- a/src/ahriman/application/ahriman.py +++ b/src/ahriman/application/ahriman.py @@ -245,6 +245,8 @@ def _set_package_add_parser(root: SubParserAction) -> argparse.ArgumentParser: "5) and finally you can add package from AUR.", formatter_class=_formatter) parser.add_argument("package", help="package source (base name, path to local files, remote URL)", nargs="+") + parser.add_argument("--dependencies", help="process missing package dependencies", + action=argparse.BooleanOptionalAction, default=True) parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty", action="store_true") parser.add_argument("-n", "--now", help="run update function after", action="store_true") parser.add_argument("-y", "--refresh", help="download fresh package databases from the mirror before actions, " @@ -252,7 +254,6 @@ def _set_package_add_parser(root: SubParserAction) -> argparse.ArgumentParser: action="count", default=False) parser.add_argument("-s", "--source", help="explicitly specify the package source for this command", type=PackageSource, choices=enum_values(PackageSource), default=PackageSource.Auto) - parser.add_argument("--without-dependencies", help="do not add dependencies", action="store_true") parser.set_defaults(handler=handlers.Add) return parser @@ -472,7 +473,7 @@ def _set_repo_check_parser(root: SubParserAction) -> argparse.ArgumentParser: parser.add_argument("-y", "--refresh", help="download fresh package databases from the mirror before actions, " "-yy to force refresh even if up to date", action="count", default=False) - parser.set_defaults(handler=handlers.Update, dry_run=True, aur=True, local=True, manual=False) + parser.set_defaults(handler=handlers.Update, dependencies=False, dry_run=True, aur=True, local=True, manual=False) return parser @@ -492,6 +493,8 @@ def _set_repo_daemon_parser(root: SubParserAction) -> argparse.ArgumentParser: parser.add_argument("-i", "--interval", help="interval between runs in seconds", type=int, default=60 * 60 * 12) parser.add_argument("--aur", help="enable or disable checking for AUR updates", action=argparse.BooleanOptionalAction, default=True) + parser.add_argument("--dependencies", help="process missing package dependencies", + action=argparse.BooleanOptionalAction, default=True) parser.add_argument("--local", help="enable or disable checking of local packages for updates", action=argparse.BooleanOptionalAction, default=True) parser.add_argument("--manual", help="include or exclude manual updates", @@ -691,10 +694,12 @@ def _set_repo_update_parser(root: SubParserAction) -> argparse.ArgumentParser: description="check for packages updates and run build process if requested", formatter_class=_formatter) parser.add_argument("package", help="filter check by package base", nargs="*") - parser.add_argument("--dry-run", help="just perform check for updates, same as check command", action="store_true") - parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty", action="store_true") parser.add_argument("--aur", help="enable or disable checking for AUR updates", action=argparse.BooleanOptionalAction, default=True) + parser.add_argument("--dependencies", help="process missing package dependencies", + action=argparse.BooleanOptionalAction, default=True) + parser.add_argument("--dry-run", help="just perform check for updates, same as check command", action="store_true") + parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty", action="store_true") parser.add_argument("--local", help="enable or disable checking of local packages for updates", action=argparse.BooleanOptionalAction, default=True) parser.add_argument("--manual", help="include or exclude manual updates", diff --git a/src/ahriman/application/application/application.py b/src/ahriman/application/application/application.py index c8de0a80..1e17a14c 100644 --- a/src/ahriman/application/application/application.py +++ b/src/ahriman/application/application/application.py @@ -17,10 +17,11 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # -from typing import Set +from typing import Iterable, List, Set from ahriman.application.application.application_packages import ApplicationPackages from ahriman.application.application.application_repository import ApplicationRepository +from ahriman.models.package import Package from ahriman.models.result import Result @@ -87,3 +88,39 @@ class Application(ApplicationPackages, ApplicationRepository): directly as it will be called after on_start action """ self.repository.triggers.on_stop() + + def with_dependencies(self, packages: List[Package], *, process_dependencies: bool) -> List[Package]: + """ + add missing dependencies to list of packages + + Args: + packages(List[Package]): list of source packages of which dependencies have to be processed + process_dependencies(bool): if no set, dependencies will not be processed + """ + def missing_dependencies(source: Iterable[Package]) -> Set[str]: + # build initial list of dependencies + result = set() + for package in source: + result.update(package.depends_build) + + # remove ones which are already well-known + result = result.difference(known_packages) + + # remove ones which are in this list already + for package in source: + result = result.difference(package.packages_full) + + return result + + if not process_dependencies or not packages: + return packages + + known_packages = self._known_packages() + with_dependencies = {package.base: package for package in packages} + + while missing := missing_dependencies(with_dependencies.values()): + for package_name in missing: + package = Package.from_aur(package_name, self.repository.pacman) + with_dependencies[package.base] = package + + return list(with_dependencies.values()) diff --git a/src/ahriman/application/application/application_packages.py b/src/ahriman/application/application/application_packages.py index 9dba0605..83fc26f3 100644 --- a/src/ahriman/application/application/application_packages.py +++ b/src/ahriman/application/application/application_packages.py @@ -21,7 +21,7 @@ import requests import shutil from pathlib import Path -from typing import Any, Iterable, Set +from typing import Any, Iterable from ahriman.application.application.application_properties import ApplicationProperties from ahriman.core.build_tools.sources import Sources @@ -47,22 +47,18 @@ class ApplicationPackages(ApplicationProperties): dst = self.repository.paths.packages / local_path.name shutil.copy(local_path, dst) - def _add_aur(self, source: str, known_packages: Set[str], without_dependencies: bool) -> None: + def _add_aur(self, source: str) -> None: """ add package from AUR Args: source(str): package base name - known_packages(Set[str]): list of packages which are known by the service - without_dependencies(bool): if set, dependency check will be disabled """ package = Package.from_aur(source, self.repository.pacman) self.database.build_queue_insert(package) self.database.remote_update(package) - self._process_dependencies(package, known_packages, without_dependencies) - def _add_directory(self, source: str, *_: Any) -> None: """ add packages from directory @@ -74,14 +70,12 @@ class ApplicationPackages(ApplicationProperties): for full_path in filter(package_like, local_dir.iterdir()): self._add_archive(str(full_path)) - def _add_local(self, source: str, known_packages: Set[str], without_dependencies: bool) -> None: + def _add_local(self, source: str) -> None: """ add package from local PKGBUILDs Args: source(str): path to directory with local source files - known_packages(Set[str]): list of packages which are known by the service - without_dependencies(bool): if set, dependency check will be disabled """ source_dir = Path(source) package = Package.from_build(source_dir, self.architecture) @@ -91,8 +85,6 @@ class ApplicationPackages(ApplicationProperties): self.database.build_queue_insert(package) - self._process_dependencies(package, known_packages, without_dependencies) - def _add_remote(self, source: str, *_: Any) -> None: """ add package from remote sources (e.g. HTTP) @@ -118,50 +110,19 @@ class ApplicationPackages(ApplicationProperties): package = Package.from_official(source, self.repository.pacman) self.database.build_queue_insert(package) self.database.remote_update(package) - # repository packages must not depend on unknown packages, thus we are not going to process dependencies - def _known_packages(self) -> Set[str]: - """ - load packages from repository and pacman repositories - - Returns: - Set[str]: list of known packages - - Raises: - NotImplementedError: not implemented method - """ - raise NotImplementedError - - def _process_dependencies(self, package: Package, known_packages: Set[str], without_dependencies: bool) -> None: - """ - process package dependencies - - Args: - package(Package): source package of which dependencies have to be processed - known_packages(Set[str]): list of packages which are known by the service - without_dependencies(bool): if set, dependency check will be disabled - """ - if without_dependencies: - return - - dependencies = package.depends_build - self.add(dependencies.difference(known_packages), PackageSource.AUR, without_dependencies) - - def add(self, names: Iterable[str], source: PackageSource, without_dependencies: bool) -> None: + def add(self, names: Iterable[str], source: PackageSource) -> None: """ add packages for the next build Args: names(Iterable[str]): list of package bases to add source(PackageSource): package source to add - without_dependencies(bool): if set, dependency check will be disabled """ - known_packages = self._known_packages() # speedup dependencies processing - for name in names: resolved_source = source.resolve(name) fn = getattr(self, f"_add_{resolved_source.value}") - fn(name, known_packages, without_dependencies) + fn(name) def on_result(self, result: Result) -> None: """ diff --git a/src/ahriman/application/handlers/add.py b/src/ahriman/application/handlers/add.py index 64f8c9b9..a129bc05 100644 --- a/src/ahriman/application/handlers/add.py +++ b/src/ahriman/application/handlers/add.py @@ -47,11 +47,12 @@ class Add(Handler): application = Application(architecture, configuration, report=report, unsafe=unsafe, refresh_pacman_database=args.refresh) application.on_start() - application.add(args.package, args.source, args.without_dependencies) + application.add(args.package, args.source) if not args.now: return packages = application.updates(args.package, aur=False, local=False, manual=True, vcs=False, log_fn=application.logger.info) + packages = application.with_dependencies(packages, process_dependencies=args.dependencies) result = application.update(packages) Add.check_if_empty(args.exit_code, result.is_empty) diff --git a/src/ahriman/application/handlers/update.py b/src/ahriman/application/handlers/update.py index dea34bed..7749081b 100644 --- a/src/ahriman/application/handlers/update.py +++ b/src/ahriman/application/handlers/update.py @@ -53,6 +53,7 @@ class Update(Handler): if args.dry_run: return + packages = application.with_dependencies(packages, process_dependencies=args.dependencies) result = application.update(packages) Update.check_if_empty(args.exit_code, result.is_empty) diff --git a/src/ahriman/models/package.py b/src/ahriman/models/package.py index 9aa2e042..3f909163 100644 --- a/src/ahriman/models/package.py +++ b/src/ahriman/models/package.py @@ -17,7 +17,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # -# pylint: disable=too-many-lines +# pylint: disable=too-many-lines,too-many-public-methods from __future__ import annotations import copy @@ -96,7 +96,7 @@ class Package(LazyLogging): Returns: Set[str]: full dependencies list used by devtools """ - return (set(self.depends) | set(self.depends_make)) - self.packages.keys() + return (set(self.depends) | set(self.depends_make)).difference(self.packages_full) @property def depends_make(self) -> List[str]: @@ -163,6 +163,20 @@ class Package(LazyLogging): """ return sorted(set(sum((package.licenses for package in self.packages.values()), start=[]))) + @property + def packages_full(self) -> List[str]: + """ + get full packages list including provides + + Returns: + List[str]: full list of packages which this base contains + """ + packages = set() + for package, properties in self.packages.items(): + packages.add(package) + packages.update(properties.provides) + return sorted(packages) + @classmethod def from_archive(cls: Type[Package], path: Path, pacman: Pacman, remote: Optional[RemoteSource]) -> Package: """ diff --git a/tests/ahriman/application/application/test_application.py b/tests/ahriman/application/application/test_application.py index 847efaba..2a61eafc 100644 --- a/tests/ahriman/application/application/test_application.py +++ b/tests/ahriman/application/application/test_application.py @@ -1,4 +1,5 @@ from pytest_mock import MockerFixture +from unittest.mock import MagicMock, call as MockCall from ahriman.application.application import Application from ahriman.models.package import Package @@ -44,3 +45,55 @@ def test_on_stop(application: Application, mocker: MockerFixture) -> None: application.on_stop() triggers_mock.assert_called_once_with() + + +def test_with_dependencies(application: Application, package_ahriman: Package, package_python_schedule: Package, + mocker: MockerFixture) -> None: + """ + must append list of missing dependencies + """ + def create_package_mock(package_base) -> MagicMock: + mock = MagicMock() + mock.base = package_base + mock.depends_build = [] + mock.packages_full = [package_base] + return mock + + package_python_schedule.packages = { + package_python_schedule.base: package_python_schedule.packages[package_python_schedule.base] + } + package_ahriman.packages[package_ahriman.base].depends = ["devtools", "python", package_python_schedule.base] + package_ahriman.packages[package_ahriman.base].make_depends = ["python-build", "python-installer"] + + packages = { + package_ahriman.base: package_ahriman, + package_python_schedule.base: package_python_schedule, + "python": create_package_mock("python"), + "python-installer": create_package_mock("python-installer"), + } + + package_mock = mocker.patch("ahriman.models.package.Package.from_aur", side_effect=lambda p, _: packages[p]) + packages_mock = mocker.patch("ahriman.application.application.Application._known_packages", + return_value=["devtools", "python-build"]) + + result = application.with_dependencies([package_ahriman], process_dependencies=True) + assert {package.base: package for package in result} == packages + package_mock.assert_has_calls([ + MockCall(package_python_schedule.base, application.repository.pacman), + MockCall("python", application.repository.pacman), + MockCall("python-installer", application.repository.pacman), + ], any_order=True) + packages_mock.assert_called_once_with() + + +def test_with_dependencies_skip(application: Application, package_ahriman: Package, mocker: MockerFixture) -> None: + """ + must skip processing of dependencies + """ + packages_mock = mocker.patch("ahriman.application.application.Application._known_packages") + + assert application.with_dependencies([package_ahriman], process_dependencies=False) == [package_ahriman] + packages_mock.assert_not_called() + + assert application.with_dependencies([], process_dependencies=True) == [] + packages_mock.assert_not_called() diff --git a/tests/ahriman/application/application/test_application_packages.py b/tests/ahriman/application/application/test_application_packages.py index 1f45031a..82ef9022 100644 --- a/tests/ahriman/application/application/test_application_packages.py +++ b/tests/ahriman/application/application/test_application_packages.py @@ -29,13 +29,10 @@ def test_add_aur(application_packages: ApplicationPackages, package_ahriman: Pac must add package from AUR """ mocker.patch("ahriman.models.package.Package.from_aur", return_value=package_ahriman) - dependencies_mock = mocker.patch( - "ahriman.application.application.application_packages.ApplicationPackages._process_dependencies") build_queue_mock = mocker.patch("ahriman.core.database.SQLite.build_queue_insert") update_remote_mock = mocker.patch("ahriman.core.database.SQLite.remote_update") - application_packages._add_aur(package_ahriman.base, set(), False) - dependencies_mock.assert_called_once_with(pytest.helpers.anyvar(int), set(), False) + application_packages._add_aur(package_ahriman.base) build_queue_mock.assert_called_once_with(package_ahriman) update_remote_mock.assert_called_once_with(package_ahriman) @@ -64,15 +61,12 @@ def test_add_local(application_packages: ApplicationPackages, package_ahriman: P mocker.patch("ahriman.models.package.Package.from_build", return_value=package_ahriman) init_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.init") copytree_mock = mocker.patch("shutil.copytree") - dependencies_mock = mocker.patch( - "ahriman.application.application.application_packages.ApplicationPackages._process_dependencies") build_queue_mock = mocker.patch("ahriman.core.database.SQLite.build_queue_insert") - application_packages._add_local(package_ahriman.base, set(), False) + application_packages._add_local(package_ahriman.base) copytree_mock.assert_called_once_with( Path(package_ahriman.base), application_packages.repository.paths.cache_for(package_ahriman.base)) init_mock.assert_called_once_with(application_packages.repository.paths.cache_for(package_ahriman.base)) - dependencies_mock.assert_called_once_with(pytest.helpers.anyvar(int), set(), False) build_queue_mock.assert_called_once_with(package_ahriman) @@ -107,59 +101,15 @@ def test_add_repository(application_packages: ApplicationPackages, package_ahrim update_remote_mock.assert_called_once_with(package_ahriman) -def test_known_packages(application_packages: ApplicationPackages) -> None: - """ - must raise NotImplemented for missing known_packages method - """ - with pytest.raises(NotImplementedError): - application_packages._known_packages() - - -def test_process_dependencies(application_packages: ApplicationPackages, package_ahriman: Package, - mocker: MockerFixture) -> None: - """ - must process dependencies addition - """ - add_mock = mocker.patch("ahriman.application.application.application_packages.ApplicationPackages.add") - - application_packages._process_dependencies(package_ahriman, set(), False) - add_mock.assert_called_once_with(package_ahriman.depends_build, PackageSource.AUR, False) - - -def test_process_dependencies_missing(application_packages: ApplicationPackages, package_ahriman: Package, - mocker: MockerFixture) -> None: - """ - must process dependencies addition only for missing packages - """ - missing = {"devtools"} - add_mock = mocker.patch("ahriman.application.application.application_packages.ApplicationPackages.add") - - application_packages._process_dependencies( - package_ahriman, package_ahriman.depends_build.difference(missing), False) - add_mock.assert_called_once_with(missing, PackageSource.AUR, False) - - -def test_process_dependencies_skip(application_packages: ApplicationPackages, package_ahriman: Package, - mocker: MockerFixture) -> None: - """ - must skip dependencies processing - """ - add_mock = mocker.patch("ahriman.application.application.application_packages.ApplicationPackages.add") - application_packages._process_dependencies(package_ahriman, set(), True) - add_mock.assert_not_called() - - def test_add_add_archive(application_packages: ApplicationPackages, package_ahriman: Package, mocker: MockerFixture) -> None: """ must add package from archive via add function """ - mocker.patch("ahriman.application.application.application_packages.ApplicationPackages._known_packages", - return_value=set()) add_mock = mocker.patch("ahriman.application.application.application_packages.ApplicationPackages._add_archive") - application_packages.add([package_ahriman.base], PackageSource.Archive, False) - add_mock.assert_called_once_with(package_ahriman.base, set(), False) + application_packages.add([package_ahriman.base], PackageSource.Archive) + add_mock.assert_called_once_with(package_ahriman.base) def test_add_add_aur( @@ -169,12 +119,10 @@ def test_add_add_aur( """ must add package from AUR via add function """ - mocker.patch("ahriman.application.application.application_packages.ApplicationPackages._known_packages", - return_value=set()) add_mock = mocker.patch("ahriman.application.application.application_packages.ApplicationPackages._add_aur") - application_packages.add([package_ahriman.base], PackageSource.AUR, True) - add_mock.assert_called_once_with(package_ahriman.base, set(), True) + application_packages.add([package_ahriman.base], PackageSource.AUR) + add_mock.assert_called_once_with(package_ahriman.base) def test_add_add_directory(application_packages: ApplicationPackages, package_ahriman: Package, @@ -182,12 +130,10 @@ def test_add_add_directory(application_packages: ApplicationPackages, package_ah """ must add packages from directory via add function """ - mocker.patch("ahriman.application.application.application_packages.ApplicationPackages._known_packages", - return_value=set()) add_mock = mocker.patch("ahriman.application.application.application_packages.ApplicationPackages._add_directory") - application_packages.add([package_ahriman.base], PackageSource.Directory, False) - add_mock.assert_called_once_with(package_ahriman.base, set(), False) + application_packages.add([package_ahriman.base], PackageSource.Directory) + add_mock.assert_called_once_with(package_ahriman.base) def test_add_add_local(application_packages: ApplicationPackages, package_ahriman: Package, @@ -195,12 +141,10 @@ def test_add_add_local(application_packages: ApplicationPackages, package_ahrima """ must add package from local sources via add function """ - mocker.patch("ahriman.application.application.application_packages.ApplicationPackages._known_packages", - return_value=set()) add_mock = mocker.patch("ahriman.application.application.application_packages.ApplicationPackages._add_local") - application_packages.add([package_ahriman.base], PackageSource.Local, False) - add_mock.assert_called_once_with(package_ahriman.base, set(), False) + application_packages.add([package_ahriman.base], PackageSource.Local) + add_mock.assert_called_once_with(package_ahriman.base) def test_add_add_remote(application_packages: ApplicationPackages, package_description_ahriman: PackageDescription, @@ -208,13 +152,11 @@ def test_add_add_remote(application_packages: ApplicationPackages, package_descr """ must add package from remote source via add function """ - mocker.patch("ahriman.application.application.application_packages.ApplicationPackages._known_packages", - return_value=set()) add_mock = mocker.patch("ahriman.application.application.application_packages.ApplicationPackages._add_remote") url = f"https://host/{package_description_ahriman.filename}" - application_packages.add([url], PackageSource.Remote, False) - add_mock.assert_called_once_with(url, set(), False) + application_packages.add([url], PackageSource.Remote) + add_mock.assert_called_once_with(url) def test_on_result(application_packages: ApplicationPackages) -> None: diff --git a/tests/ahriman/application/handlers/test_handler_add.py b/tests/ahriman/application/handlers/test_handler_add.py index cf1234ce..a8ed05a1 100644 --- a/tests/ahriman/application/handlers/test_handler_add.py +++ b/tests/ahriman/application/handlers/test_handler_add.py @@ -26,7 +26,7 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace: args.now = False args.refresh = 0 args.source = PackageSource.Auto - args.without_dependencies = False + args.dependencies = True return args @@ -38,10 +38,12 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository: args = _default_args(args) mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) application_mock = mocker.patch("ahriman.application.application.Application.add") + dependencies_mock = mocker.patch("ahriman.application.application.Application.with_dependencies") on_start_mock = mocker.patch("ahriman.application.application.Application.on_start") Add.run(args, "x86_64", configuration, report=False, unsafe=False) - application_mock.assert_called_once_with(args.package, args.source, args.without_dependencies) + application_mock.assert_called_once_with(args.package, args.source) + dependencies_mock.assert_not_called() on_start_mock.assert_called_once_with() @@ -59,11 +61,14 @@ def test_run_with_updates(args: argparse.Namespace, configuration: Configuration application_mock = mocker.patch("ahriman.application.application.Application.update", return_value=result) check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty") updates_mock = mocker.patch("ahriman.application.application.Application.updates", return_value=[package_ahriman]) + dependencies_mock = mocker.patch("ahriman.application.application.Application.with_dependencies", + return_value=[package_ahriman]) Add.run(args, "x86_64", configuration, report=False, unsafe=False) updates_mock.assert_called_once_with(args.package, aur=False, local=False, manual=True, vcs=False, log_fn=pytest.helpers.anyvar(int)) application_mock.assert_called_once_with([package_ahriman]) + dependencies_mock.assert_called_once_with([package_ahriman], process_dependencies=args.dependencies) check_mock.assert_called_once_with(False, False) @@ -78,6 +83,7 @@ def test_run_empty_exception(args: argparse.Namespace, configuration: Configurat mocker.patch("ahriman.application.application.Application.add") mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch("ahriman.application.application.Application.update", return_value=Result()) + mocker.patch("ahriman.application.application.Application.with_dependencies") mocker.patch("ahriman.application.application.Application.updates") check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty") diff --git a/tests/ahriman/application/handlers/test_handler_update.py b/tests/ahriman/application/handlers/test_handler_update.py index 6cca8f47..c83462f7 100644 --- a/tests/ahriman/application/handlers/test_handler_update.py +++ b/tests/ahriman/application/handlers/test_handler_update.py @@ -23,6 +23,7 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace: argparse.Namespace: generated arguments for these test cases """ args.package = [] + args.dependencies = True args.dry_run = False args.exit_code = False args.aur = True @@ -44,6 +45,8 @@ def test_run(args: argparse.Namespace, package_ahriman: Package, configuration: mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) application_mock = mocker.patch("ahriman.application.application.Application.update", return_value=result) check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty") + dependencies_mock = mocker.patch("ahriman.application.application.Application.with_dependencies", + return_value=[package_ahriman]) updates_mock = mocker.patch("ahriman.application.application.Application.updates", return_value=[package_ahriman]) on_start_mock = mocker.patch("ahriman.application.application.Application.on_start") @@ -51,6 +54,7 @@ def test_run(args: argparse.Namespace, package_ahriman: Package, configuration: application_mock.assert_called_once_with([package_ahriman]) updates_mock.assert_called_once_with(args.package, aur=args.aur, local=args.local, manual=args.manual, vcs=args.vcs, log_fn=pytest.helpers.anyvar(int)) + dependencies_mock.assert_called_once_with([package_ahriman], process_dependencies=args.dependencies) check_mock.assert_has_calls([MockCall(False, False), MockCall(False, False)]) on_start_mock.assert_called_once_with() @@ -81,6 +85,7 @@ def test_run_update_empty_exception(args: argparse.Namespace, package_ahriman: P mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch("ahriman.application.application.Application.update", return_value=Result()) mocker.patch("ahriman.application.application.Application.updates", return_value=[package_ahriman]) + mocker.patch("ahriman.application.application.Application.with_dependencies", return_value=[package_ahriman]) check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty") Update.run(args, "x86_64", configuration, report=False, unsafe=False) diff --git a/tests/ahriman/application/test_ahriman.py b/tests/ahriman/application/test_ahriman.py index 546949ec..1fe5f9a3 100644 --- a/tests/ahriman/application/test_ahriman.py +++ b/tests/ahriman/application/test_ahriman.py @@ -342,9 +342,10 @@ def test_subparsers_repo_backup_architecture(parser: argparse.ArgumentParser) -> def test_subparsers_repo_check(parser: argparse.ArgumentParser) -> None: """ - repo-check command must imply dry-run, aur and manual + repo-check command must imply dependencies, dry-run, aur and manual """ args = parser.parse_args(["repo-check"]) + assert not args.dependencies assert args.dry_run assert args.aur assert not args.manual diff --git a/tests/ahriman/models/test_package.py b/tests/ahriman/models/test_package.py index edaf9634..123e061d 100644 --- a/tests/ahriman/models/test_package.py +++ b/tests/ahriman/models/test_package.py @@ -125,6 +125,14 @@ def test_licenses(package_ahriman: Package) -> None: assert sorted(package_ahriman.licenses) == package_ahriman.licenses +def test_packages_full(package_ahriman: Package) -> None: + """ + must return full list of packages including provides + """ + package_ahriman.packages[package_ahriman.base].provides = [f"{package_ahriman.base}-git"] + assert package_ahriman.packages_full == [package_ahriman.base, f"{package_ahriman.base}-git"] + + def test_from_archive(package_ahriman: Package, pyalpm_handle: MagicMock, mocker: MockerFixture) -> None: """ must construct package from alpm library