From fb6b22cdd77fdaf7b11490c9cdad79abca117a1c Mon Sep 17 00:00:00 2001 From: Evgeniy Alekseev Date: Wed, 2 Nov 2022 04:09:42 +0200 Subject: [PATCH] change gitremote api to be same as report and upload These changes are keeping fallback to old settings, but will allow to run multiple git targets with different settings --- docs/ahriman.core.gitremote.rst | 16 +++ docs/faq.rst | 7 ++ src/ahriman/core/exceptions.py | 12 ++ src/ahriman/core/gitremote/remote_pull.py | 90 ++++++++++++++ .../core/gitremote/remote_pull_trigger.py | 51 +------- src/ahriman/core/gitremote/remote_push.py | 113 ++++++++++++++++++ .../core/gitremote/remote_push_trigger.py | 67 +---------- .../core/gitremote/test_remote_pull.py | 70 +++++++++++ .../gitremote/test_remote_pull_trigger.py | 47 +------- .../core/gitremote/test_remote_push.py | 67 +++++++++++ .../gitremote/test_remote_push_trigger.py | 42 +------ tests/ahriman/core/report/test_report.py | 2 +- tests/testresources/core/ahriman.ini | 8 +- 13 files changed, 399 insertions(+), 193 deletions(-) create mode 100644 src/ahriman/core/gitremote/remote_pull.py create mode 100644 src/ahriman/core/gitremote/remote_push.py create mode 100644 tests/ahriman/core/gitremote/test_remote_pull.py create mode 100644 tests/ahriman/core/gitremote/test_remote_push.py diff --git a/docs/ahriman.core.gitremote.rst b/docs/ahriman.core.gitremote.rst index b2322c6f..ebcef486 100644 --- a/docs/ahriman.core.gitremote.rst +++ b/docs/ahriman.core.gitremote.rst @@ -4,6 +4,14 @@ ahriman.core.gitremote package Submodules ---------- +ahriman.core.gitremote.remote\_pull module +------------------------------------------ + +.. automodule:: ahriman.core.gitremote.remote_pull + :members: + :no-undoc-members: + :show-inheritance: + ahriman.core.gitremote.remote\_pull\_trigger module --------------------------------------------------- @@ -12,6 +20,14 @@ ahriman.core.gitremote.remote\_pull\_trigger module :no-undoc-members: :show-inheritance: +ahriman.core.gitremote.remote\_push module +------------------------------------------ + +.. automodule:: ahriman.core.gitremote.remote_push + :members: + :no-undoc-members: + :show-inheritance: + ahriman.core.gitremote.remote\_push\_trigger module --------------------------------------------------- diff --git a/docs/faq.rst b/docs/faq.rst index 99af90d8..9c1c0e7b 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -1,3 +1,4 @@ + FAQ === @@ -131,6 +132,9 @@ For that purpose you could use ``RemotePullTrigger`` trigger. To do so you will .. code-block:: ini + [remote-pull] + target = gitremote + [gitremote] pull_url = https://github.com/username/repository @@ -154,6 +158,9 @@ For that purpose you'd need to use another trigger called ``RemotePushTrigger``. .. code-block:: ini + [remote-push] + target = gitremote + [gitremote] push_url = https://github.com/username/repository diff --git a/src/ahriman/core/exceptions.py b/src/ahriman/core/exceptions.py index 1ea3c0e8..6345739c 100644 --- a/src/ahriman/core/exceptions.py +++ b/src/ahriman/core/exceptions.py @@ -55,6 +55,18 @@ class ExitCode(RuntimeError): """ +class GitRemoteFailed(RuntimeError): + """ + git remote exception + """ + + def __init__(self) -> None: + """ + default constructor + """ + RuntimeError.__init__(self, "Git remote failed") + + class InitializeException(RuntimeError): """ base service initialization exception diff --git a/src/ahriman/core/gitremote/remote_pull.py b/src/ahriman/core/gitremote/remote_pull.py new file mode 100644 index 00000000..249d86d3 --- /dev/null +++ b/src/ahriman/core/gitremote/remote_pull.py @@ -0,0 +1,90 @@ +# +# copyright (c) 2021-2022 ahriman team. +# +# this file is part of ahriman +# (see https://github.com/arcan1s/ahriman). +# +# this program is free software: you can redistribute it and/or modify +# it under the terms of the gnu general public license as published by +# the free software foundation, either version 3 of the license, or +# (at your option) any later version. +# +# this program is distributed in the hope that it will be useful, +# but without any warranty; without even the implied warranty of +# merchantability or fitness for a particular purpose. see the +# gnu general public license for more details. +# +# you should have received a copy of the gnu general public license +# along with this program. if not, see . +# +import shutil + +from pathlib import Path +from tempfile import TemporaryDirectory + +from ahriman.core.build_tools.sources import Sources +from ahriman.core.configuration import Configuration +from ahriman.core.exceptions import GitRemoteFailed +from ahriman.core.lazy_logging import LazyLogging +from ahriman.core.util import walk +from ahriman.models.package_source import PackageSource +from ahriman.models.remote_source import RemoteSource + + +class RemotePull(LazyLogging): + """ + fetch PKGBUILDs from remote repository and use them for following actions + + Attributes: + remote_source(RemoteSource): repository remote source (remote pull url and branch) + repository_paths(RepositoryPaths): repository paths instance + """ + + def __init__(self, configuration: Configuration, section: str) -> None: + """ + default constructor + + Args: + configuration(Configuration): configuration instance + section(str): settings section name + """ + self.remote_source = RemoteSource( + git_url=configuration.get(section, "pull_url"), + web_url="", + path=".", + branch=configuration.get(section, "pull_branch", fallback="master"), + source=PackageSource.Local, + ) + self.repository_paths = configuration.repository_paths + + def repo_clone(self) -> None: + """ + clone repository from remote source + """ + with TemporaryDirectory(ignore_cleanup_errors=True) as dir_name, (clone_dir := Path(dir_name)): + Sources.fetch(clone_dir, self.remote_source) + self.repo_copy(clone_dir) + + def repo_copy(self, clone_dir: Path) -> None: + """ + copy directories from cloned remote source to local cache + + Args: + clone_dir(Path): path to temporary cloned directory + """ + for pkgbuild_path in filter(lambda path: path.name == "PKGBUILD", walk(clone_dir)): + cloned_pkgbuild_dir = pkgbuild_path.parent + package_base = cloned_pkgbuild_dir.name + local_pkgbuild_dir = self.repository_paths.cache_for(package_base) + shutil.copytree(cloned_pkgbuild_dir, local_pkgbuild_dir, dirs_exist_ok=True) + Sources.init(local_pkgbuild_dir) # initialized git repository is required for local sources + + def run(self) -> None: + """ + run git pull action + """ + try: + self.repo_clone() + except Exception: + self.logger.exception("git pull failed") + raise GitRemoteFailed() diff --git a/src/ahriman/core/gitremote/remote_pull_trigger.py b/src/ahriman/core/gitremote/remote_pull_trigger.py index 853840cb..4c105a94 100644 --- a/src/ahriman/core/gitremote/remote_pull_trigger.py +++ b/src/ahriman/core/gitremote/remote_pull_trigger.py @@ -17,26 +17,14 @@ # you should have received a copy of the gnu general public license # along with this program. if not, see . # -import shutil - -from pathlib import Path -from tempfile import TemporaryDirectory - -from ahriman.core.build_tools.sources import Sources from ahriman.core.configuration import Configuration +from ahriman.core.gitremote.remote_pull import RemotePull from ahriman.core.triggers import Trigger -from ahriman.core.util import walk -from ahriman.models.package_source import PackageSource -from ahriman.models.remote_source import RemoteSource class RemotePullTrigger(Trigger): """ - trigger for fetching PKGBUILDs from remote repository - - Attributes: - remote_source(RemoteSource): repository remote source (remote pull url and branch) - repository_paths(RepositoryPaths): repository paths instance + trigger based on pulling PKGBUILDs before the actions """ def __init__(self, architecture: str, configuration: Configuration) -> None: @@ -48,39 +36,12 @@ class RemotePullTrigger(Trigger): configuration(Configuration): configuration instance """ Trigger.__init__(self, architecture, configuration) - self.remote_source = RemoteSource( - git_url=configuration.get("gitremote", "pull_url"), - web_url="", - path=".", - branch=configuration.get("gitremote", "pull_branch", fallback="master"), - source=PackageSource.Local, - ) - self.repository_paths = configuration.repository_paths + self.targets = configuration.getlist("remote-pull", "target", fallback=["gitremote"]) def on_start(self) -> None: """ trigger action which will be called at the start of the application """ - self.repo_clone() - - def repo_clone(self) -> None: - """ - clone repository from remote source - """ - with TemporaryDirectory(ignore_cleanup_errors=True) as dir_name, (clone_dir := Path(dir_name)): - Sources.fetch(clone_dir, self.remote_source) - self.repo_copy(clone_dir) - - def repo_copy(self, clone_dir: Path) -> None: - """ - copy directories from cloned remote source to local cache - - Args: - clone_dir(Path): path to temporary cloned directory - """ - for pkgbuild_path in filter(lambda path: path.name == "PKGBUILD", walk(clone_dir)): - cloned_pkgbuild_dir = pkgbuild_path.parent - package_base = cloned_pkgbuild_dir.name - local_pkgbuild_dir = self.repository_paths.cache_for(package_base) - shutil.copytree(cloned_pkgbuild_dir, local_pkgbuild_dir, dirs_exist_ok=True) - Sources.init(local_pkgbuild_dir) # initialized git repository is required for local sources + for target in self.targets: + runner = RemotePull(self.configuration, target) + runner.run() diff --git a/src/ahriman/core/gitremote/remote_push.py b/src/ahriman/core/gitremote/remote_push.py new file mode 100644 index 00000000..73736172 --- /dev/null +++ b/src/ahriman/core/gitremote/remote_push.py @@ -0,0 +1,113 @@ +# +# copyright (c) 2021-2022 ahriman team. +# +# this file is part of ahriman +# (see https://github.com/arcan1s/ahriman). +# +# this program is free software: you can redistribute it and/or modify +# it under the terms of the gnu general public license as published by +# the free software foundation, either version 3 of the license, or +# (at your option) any later version. +# +# this program is distributed in the hope that it will be useful, +# but without any warranty; without even the implied warranty of +# merchantability or fitness for a particular purpose. see the +# gnu general public license for more details. +# +# you should have received a copy of the gnu general public license +# along with this program. if not, see . +# +import shutil + +from pathlib import Path +from tempfile import TemporaryDirectory +from typing import Generator + +from ahriman.core.build_tools.sources import Sources +from ahriman.core.configuration import Configuration +from ahriman.core.exceptions import GitRemoteFailed +from ahriman.core.lazy_logging import LazyLogging +from ahriman.models.package import Package +from ahriman.models.package_source import PackageSource +from ahriman.models.remote_source import RemoteSource +from ahriman.models.result import Result + + +class RemotePush(LazyLogging): + """ + sync PKGBUILDs to remote repository after actions + + Attributes: + remote_source(RemoteSource): repository remote source (remote pull url and branch) + """ + + def __init__(self, configuration: Configuration, section: str) -> None: + """ + default constructor + + Args: + configuration(Configuration): configuration instance + remote_push_trigger.py + """ + self.remote_source = RemoteSource( + git_url=configuration.get(section, "push_url"), + web_url="", + path=".", + branch=configuration.get(section, "push_branch", fallback="master"), + source=PackageSource.Local, + ) + + @staticmethod + def package_update(package: Package, target_dir: Path) -> str: + """ + clone specified package and update its content in cloned PKGBUILD repository + + Args: + package(Package): built package to update pkgbuild repository + target_dir(Path): path to the cloned PKGBUILD repository + + Returns: + str: relative path to be added as new file + """ + # instead of iterating by directory we can simplify the process + # firstly, we need to remove old data to make sure that removed files are not tracked anymore... + package_target_dir = target_dir / package.base + shutil.rmtree(package_target_dir, ignore_errors=True) + # ...secondly, we copy whole tree... + with TemporaryDirectory(ignore_cleanup_errors=True) as dir_name, (clone_dir := Path(dir_name)): + Sources.fetch(clone_dir, package.remote) + shutil.copytree(clone_dir, package_target_dir) + # ...and last, but not least, we remove the dot-git directory... + shutil.rmtree(package_target_dir / ".git", ignore_errors=True) + # ...and finally return path to the copied directory + return package.base + + @staticmethod + def packages_update(result: Result, target_dir: Path) -> Generator[str, None, None]: + """ + update all packages from the build result + + Args: + result(Result): build result + target_dir(Path): path to the cloned PKGBUILD repository + + Yields: + str: path to updated files + """ + for package in result.success: + yield RemotePush.package_update(package, target_dir) + + def run(self, result: Result) -> None: + """ + run git pull action + + Args: + result(Result): build result + """ + try: + with TemporaryDirectory(ignore_cleanup_errors=True) as dir_name, (clone_dir := Path(dir_name)): + Sources.fetch(clone_dir, self.remote_source) + Sources.push(clone_dir, self.remote_source, *RemotePush.packages_update(result, clone_dir)) + except Exception: + self.logger.exception("git push failed") + raise GitRemoteFailed() diff --git a/src/ahriman/core/gitremote/remote_push_trigger.py b/src/ahriman/core/gitremote/remote_push_trigger.py index a1bf3ec2..17105309 100644 --- a/src/ahriman/core/gitremote/remote_push_trigger.py +++ b/src/ahriman/core/gitremote/remote_push_trigger.py @@ -17,27 +17,18 @@ # you should have received a copy of the gnu general public license # along with this program. if not, see . # -import shutil +from typing import Iterable -from pathlib import Path -from tempfile import TemporaryDirectory -from typing import Generator, Iterable - -from ahriman.core.build_tools.sources import Sources from ahriman.core.configuration import Configuration +from ahriman.core.gitremote.remote_push import RemotePush from ahriman.core.triggers import Trigger from ahriman.models.package import Package -from ahriman.models.package_source import PackageSource -from ahriman.models.remote_source import RemoteSource from ahriman.models.result import Result class RemotePushTrigger(Trigger): """ trigger for syncing PKGBUILDs to remote repository - - Attributes: - remote_source(RemoteSource): repository remote source (remote pull url and branch) """ def __init__(self, architecture: str, configuration: Configuration) -> None: @@ -49,53 +40,7 @@ class RemotePushTrigger(Trigger): configuration(Configuration): configuration instance """ Trigger.__init__(self, architecture, configuration) - self.remote_source = RemoteSource( - git_url=configuration.get("gitremote", "push_url"), - web_url="", - path=".", - branch=configuration.get("gitremote", "push_branch", fallback="master"), - source=PackageSource.Local, - ) - - @staticmethod - def package_update(package: Package, target_dir: Path) -> str: - """ - clone specified package and update its content in cloned PKGBUILD repository - - Args: - package(Package): built package to update pkgbuild repository - target_dir(Path): path to the cloned PKGBUILD repository - - Returns: - str: relative path to be added as new file - """ - # instead of iterating by directory we can simplify the process - # firstly, we need to remove old data to make sure that removed files are not tracked anymore... - package_target_dir = target_dir / package.base - shutil.rmtree(package_target_dir, ignore_errors=True) - # ...secondly, we copy whole tree... - with TemporaryDirectory(ignore_cleanup_errors=True) as dir_name, (clone_dir := Path(dir_name)): - Sources.fetch(clone_dir, package.remote) - shutil.copytree(clone_dir, package_target_dir) - # ...and last, but not least, we remove the dot-git directory... - shutil.rmtree(package_target_dir / ".git", ignore_errors=True) - # ...and finally return path to the copied directory - return package.base - - @staticmethod - def packages_update(result: Result, target_dir: Path) -> Generator[str, None, None]: - """ - update all packages from the build result - - Args: - result(Result): build result - target_dir(Path): path to the cloned PKGBUILD repository - - Yields: - str: path to updated files - """ - for package in result.success: - yield RemotePushTrigger.package_update(package, target_dir) + self.targets = configuration.getlist("remote-push", "target", fallback=["gitremote"]) def on_result(self, result: Result, packages: Iterable[Package]) -> None: """ @@ -105,6 +50,6 @@ class RemotePushTrigger(Trigger): result(Result): build result packages(Iterable[Package]): list of all available packages """ - with TemporaryDirectory(ignore_cleanup_errors=True) as dir_name, (clone_dir := Path(dir_name)): - Sources.fetch(clone_dir, self.remote_source) - Sources.push(clone_dir, self.remote_source, *RemotePushTrigger.packages_update(result, clone_dir)) + for target in self.targets: + runner = RemotePush(self.configuration, target) + runner.run(result) diff --git a/tests/ahriman/core/gitremote/test_remote_pull.py b/tests/ahriman/core/gitremote/test_remote_pull.py new file mode 100644 index 00000000..f5ebba7a --- /dev/null +++ b/tests/ahriman/core/gitremote/test_remote_pull.py @@ -0,0 +1,70 @@ +import pytest + +from pathlib import Path +from pytest_mock import MockerFixture +from unittest import mock + +from ahriman.core.configuration import Configuration +from ahriman.core.exceptions import GitRemoteFailed +from ahriman.core.gitremote.remote_pull import RemotePull + + +def test_repo_clone(configuration: Configuration, mocker: MockerFixture) -> None: + """ + must clone repository locally and copy its content + """ + fetch_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.fetch") + copy_mock = mocker.patch("ahriman.core.gitremote.remote_pull.RemotePull.repo_copy") + runner = RemotePull(configuration, "gitremote") + + runner.repo_clone() + fetch_mock.assert_called_once_with(pytest.helpers.anyvar(int), runner.remote_source) + copy_mock.assert_called_once_with(pytest.helpers.anyvar(int)) + + +def test_repo_copy(configuration: Configuration, mocker: MockerFixture) -> None: + """ + must copy repository tree from temporary directory to the local cache + """ + mocker.patch("ahriman.core.gitremote.remote_pull.walk", return_value=[ + Path("local") / "package1" / "PKGBUILD", + Path("local") / "package1" / ".SRCINFO", + Path("local") / "package2" / ".SRCINFO", + Path("local") / "package3" / "PKGBUILD", + Path("local") / "package3" / ".SRCINFO", + ]) + copytree_mock = mocker.patch("shutil.copytree") + init_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.init") + runner = RemotePull(configuration, "gitremote") + + runner.repo_copy(Path("local")) + copytree_mock.assert_has_calls([ + mock.call(Path("local") / "package1", configuration.repository_paths.cache_for("package1"), dirs_exist_ok=True), + mock.call(Path("local") / "package3", configuration.repository_paths.cache_for("package3"), dirs_exist_ok=True), + ]) + init_mock.assert_has_calls([ + mock.call(configuration.repository_paths.cache_for("package1")), + mock.call(configuration.repository_paths.cache_for("package3")), + ]) + + +def test_run(configuration: Configuration, mocker: MockerFixture) -> None: + """ + must clone repo on run + """ + clone_mock = mocker.patch("ahriman.core.gitremote.remote_pull.RemotePull.repo_clone") + runner = RemotePull(configuration, "gitremote") + + runner.run() + clone_mock.assert_called_once_with() + + +def test_run_failed(configuration: Configuration, mocker: MockerFixture) -> None: + """ + must reraise exception on error occurred + """ + mocker.patch("ahriman.core.gitremote.remote_pull.RemotePull.repo_clone", side_effect=Exception()) + runner = RemotePull(configuration, "gitremote") + + with pytest.raises(GitRemoteFailed): + runner.run() diff --git a/tests/ahriman/core/gitremote/test_remote_pull_trigger.py b/tests/ahriman/core/gitremote/test_remote_pull_trigger.py index 1120853e..9b22eee0 100644 --- a/tests/ahriman/core/gitremote/test_remote_pull_trigger.py +++ b/tests/ahriman/core/gitremote/test_remote_pull_trigger.py @@ -1,8 +1,4 @@ -import pytest - -from pathlib import Path from pytest_mock import MockerFixture -from unittest import mock from ahriman.core.configuration import Configuration from ahriman.core.gitremote import RemotePullTrigger @@ -12,47 +8,8 @@ def test_on_start(configuration: Configuration, mocker: MockerFixture) -> None: """ must clone repo on start """ - clone_mock = mocker.patch("ahriman.core.gitremote.RemotePullTrigger.repo_clone") + run_mock = mocker.patch("ahriman.core.gitremote.remote_pull.RemotePull.run") trigger = RemotePullTrigger("x86_64", configuration) trigger.on_start() - clone_mock.assert_called_once_with() - - -def test_repo_clone(configuration: Configuration, mocker: MockerFixture) -> None: - """ - must clone repository locally and copy its content - """ - fetch_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.fetch") - copy_mock = mocker.patch("ahriman.core.gitremote.RemotePullTrigger.repo_copy") - trigger = RemotePullTrigger("x86_64", configuration) - - trigger.repo_clone() - fetch_mock.assert_called_once_with(pytest.helpers.anyvar(int), trigger.remote_source) - copy_mock.assert_called_once_with(pytest.helpers.anyvar(int)) - - -def test_repo_copy(configuration: Configuration, mocker: MockerFixture) -> None: - """ - must copy repository tree from temporary directory to the local cache - """ - mocker.patch("ahriman.core.gitremote.remote_pull_trigger.walk", return_value=[ - Path("local") / "package1" / "PKGBUILD", - Path("local") / "package1" / ".SRCINFO", - Path("local") / "package2" / ".SRCINFO", - Path("local") / "package3" / "PKGBUILD", - Path("local") / "package3" / ".SRCINFO", - ]) - copytree_mock = mocker.patch("shutil.copytree") - init_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.init") - trigger = RemotePullTrigger("x86_64", configuration) - - trigger.repo_copy(Path("local")) - copytree_mock.assert_has_calls([ - mock.call(Path("local") / "package1", configuration.repository_paths.cache_for("package1"), dirs_exist_ok=True), - mock.call(Path("local") / "package3", configuration.repository_paths.cache_for("package3"), dirs_exist_ok=True), - ]) - init_mock.assert_has_calls([ - mock.call(configuration.repository_paths.cache_for("package1")), - mock.call(configuration.repository_paths.cache_for("package3")), - ]) + run_mock.assert_called_once_with() diff --git a/tests/ahriman/core/gitremote/test_remote_push.py b/tests/ahriman/core/gitremote/test_remote_push.py new file mode 100644 index 00000000..3670202d --- /dev/null +++ b/tests/ahriman/core/gitremote/test_remote_push.py @@ -0,0 +1,67 @@ +import pytest + +from pathlib import Path +from pytest_mock import MockerFixture +from unittest import mock + +from ahriman.core.configuration import Configuration +from ahriman.core.exceptions import GitRemoteFailed +from ahriman.core.gitremote.remote_push import RemotePush +from ahriman.models.package import Package +from ahriman.models.result import Result + + +def test_package_update(package_ahriman: Package, mocker: MockerFixture) -> None: + """ + must update single package + """ + rmtree_mock = mocker.patch("shutil.rmtree") + fetch_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.fetch") + copytree_mock = mocker.patch("shutil.copytree") + + local = Path("local") + RemotePush.package_update(package_ahriman, local) + rmtree_mock.assert_has_calls([ + mock.call(local / package_ahriman.base, ignore_errors=True), + mock.call(pytest.helpers.anyvar(int), onerror=pytest.helpers.anyvar(int)), # removal of the TemporaryDirectory + mock.call(local / package_ahriman.base / ".git", ignore_errors=True), + ]) + fetch_mock.assert_called_once_with(pytest.helpers.anyvar(int), package_ahriman.remote) + copytree_mock.assert_called_once_with(pytest.helpers.anyvar(int), local / package_ahriman.base) + + +def test_packages_update(result: Result, package_ahriman: Package, mocker: MockerFixture) -> None: + """ + must generate packages update + """ + update_mock = mocker.patch("ahriman.core.gitremote.remote_push.RemotePush.package_update", + return_value=[package_ahriman.base]) + + local = Path("local") + assert list(RemotePush.packages_update(result, local)) + update_mock.assert_called_once_with(package_ahriman, local) + + +def test_run(configuration: Configuration, result: Result, package_ahriman: Package, mocker: MockerFixture) -> None: + """ + must push changes on result + """ + mocker.patch("ahriman.core.gitremote.remote_push.RemotePush.packages_update", return_value=[package_ahriman.base]) + fetch_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.fetch") + push_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.push") + runner = RemotePush(configuration, "gitremote") + + runner.run(result) + fetch_mock.assert_called_once_with(pytest.helpers.anyvar(int), runner.remote_source) + push_mock.assert_called_once_with(pytest.helpers.anyvar(int), runner.remote_source, package_ahriman.base) + + +def test_run_failed(configuration: Configuration, result: Result, mocker: MockerFixture) -> None: + """ + must reraise exception on error occurred + """ + mocker.patch("ahriman.core.build_tools.sources.Sources.fetch", side_effect=Exception()) + runner = RemotePush(configuration, "gitremote") + + with pytest.raises(GitRemoteFailed): + runner.run(result) diff --git a/tests/ahriman/core/gitremote/test_remote_push_trigger.py b/tests/ahriman/core/gitremote/test_remote_push_trigger.py index 056547ca..b9a0fd10 100644 --- a/tests/ahriman/core/gitremote/test_remote_push_trigger.py +++ b/tests/ahriman/core/gitremote/test_remote_push_trigger.py @@ -1,8 +1,4 @@ -import pytest - -from pathlib import Path from pytest_mock import MockerFixture -from unittest import mock from ahriman.core.configuration import Configuration from ahriman.core.gitremote import RemotePushTrigger @@ -10,47 +6,13 @@ from ahriman.models.package import Package from ahriman.models.result import Result -def test_package_update(package_ahriman: Package, mocker: MockerFixture) -> None: - """ - must update single package - """ - rmtree_mock = mocker.patch("shutil.rmtree") - fetch_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.fetch") - copytree_mock = mocker.patch("shutil.copytree") - - local = Path("local") - RemotePushTrigger.package_update(package_ahriman, local) - rmtree_mock.assert_has_calls([ - mock.call(local / package_ahriman.base, ignore_errors=True), - mock.call(pytest.helpers.anyvar(int), onerror=pytest.helpers.anyvar(int)), # removal of the TemporaryDirectory - mock.call(local / package_ahriman.base / ".git", ignore_errors=True), - ]) - fetch_mock.assert_called_once_with(pytest.helpers.anyvar(int), package_ahriman.remote) - copytree_mock.assert_called_once_with(pytest.helpers.anyvar(int), local / package_ahriman.base) - - -def test_packages_update(result: Result, package_ahriman: Package, mocker: MockerFixture) -> None: - """ - must generate packages update - """ - update_mock = mocker.patch("ahriman.core.gitremote.RemotePushTrigger.package_update", - return_value=[package_ahriman.base]) - - local = Path("local") - assert list(RemotePushTrigger.packages_update(result, local)) - update_mock.assert_called_once_with(package_ahriman, local) - - def test_on_result(configuration: Configuration, result: Result, package_ahriman: Package, mocker: MockerFixture) -> None: """ must push changes on result """ - mocker.patch("ahriman.core.gitremote.RemotePushTrigger.packages_update", return_value=[package_ahriman.base]) - fetch_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.fetch") - push_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.push") + run_mock = mocker.patch("ahriman.core.gitremote.remote_push.RemotePush.run") trigger = RemotePushTrigger("x86_64", configuration) trigger.on_result(result, [package_ahriman]) - fetch_mock.assert_called_once_with(pytest.helpers.anyvar(int), trigger.remote_source) - push_mock.assert_called_once_with(pytest.helpers.anyvar(int), trigger.remote_source, package_ahriman.base) + run_mock.assert_called_once_with(result) diff --git a/tests/ahriman/core/report/test_report.py b/tests/ahriman/core/report/test_report.py index 7e744032..c8db9987 100644 --- a/tests/ahriman/core/report/test_report.py +++ b/tests/ahriman/core/report/test_report.py @@ -15,7 +15,7 @@ def test_report_failure(configuration: Configuration, mocker: MockerFixture) -> """ mocker.patch("ahriman.core.report.html.HTML.generate", side_effect=Exception()) with pytest.raises(ReportFailed): - Report.load("x86_64", configuration, "html").run([], Result()) + Report.load("x86_64", configuration, "html").run(Result(), []) def test_report_dummy(configuration: Configuration, result: Result, mocker: MockerFixture) -> None: diff --git a/tests/testresources/core/ahriman.ini b/tests/testresources/core/ahriman.ini index 26ebbc58..de865840 100644 --- a/tests/testresources/core/ahriman.ini +++ b/tests/testresources/core/ahriman.ini @@ -31,9 +31,15 @@ root = ../../../ [sign] target = +[remote-push] +target = gitremote + +[remote-pull] +target = gitremote + [gitremote] -pull_url = https://github.com/arcan1s/repository.git push_url = https://github.com/arcan1s/repository.git +pull_url = https://github.com/arcan1s/repository.git [report] target =