add ability to run only speicifed triggers from command line

This commit also restores repo-report and repo-sync subcommands
This commit is contained in:
Evgenii Alekseev 2022-05-12 08:00:23 +03:00
parent 04dcaa93ab
commit 375f9fcfb7
6 changed files with 125 additions and 12 deletions

View File

@ -98,10 +98,12 @@ def _parser() -> argparse.ArgumentParser:
_set_repo_config_parser(subparsers) _set_repo_config_parser(subparsers)
_set_repo_rebuild_parser(subparsers) _set_repo_rebuild_parser(subparsers)
_set_repo_remove_unknown_parser(subparsers) _set_repo_remove_unknown_parser(subparsers)
_set_repo_report_parser(subparsers)
_set_repo_restore_parser(subparsers) _set_repo_restore_parser(subparsers)
_set_repo_setup_parser(subparsers) _set_repo_setup_parser(subparsers)
_set_repo_sign_parser(subparsers) _set_repo_sign_parser(subparsers)
_set_repo_status_update_parser(subparsers) _set_repo_status_update_parser(subparsers)
_set_repo_sync_parser(subparsers)
_set_repo_triggers_parser(subparsers) _set_repo_triggers_parser(subparsers)
_set_repo_update_parser(subparsers) _set_repo_update_parser(subparsers)
_set_user_add_parser(subparsers) _set_user_add_parser(subparsers)
@ -495,6 +497,24 @@ def _set_repo_remove_unknown_parser(root: SubParserAction) -> argparse.ArgumentP
return parser return parser
def _set_repo_report_parser(root: SubParserAction) -> argparse.ArgumentParser:
"""
add parser for report subcommand
Args:
root(SubParserAction): subparsers for the commands
Returns:
argparse.ArgumentParser: created argument parser
"""
parser = root.add_parser("repo-report", aliases=["report"], help="generate report",
description="generate repository report according to current settings",
epilog="Create and/or update repository report as configured.",
formatter_class=_formatter)
parser.set_defaults(handler=handlers.Triggers, trigger=["ahriman.core.report.ReportTrigger"])
return parser
def _set_repo_restore_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_repo_restore_parser(root: SubParserAction) -> argparse.ArgumentParser:
""" """
add parser for repository restore subcommand add parser for repository restore subcommand
@ -580,10 +600,28 @@ def _set_repo_status_update_parser(root: SubParserAction) -> argparse.ArgumentPa
return parser return parser
def _set_repo_triggers_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_repo_sync_parser(root: SubParserAction) -> argparse.ArgumentParser:
""" """
add parser for repository sync subcommand add parser for repository sync subcommand
Args:
root(SubParserAction): subparsers for the commands
Returns:
argparse.ArgumentParser: created argument parser
"""
parser = root.add_parser("repo-sync", aliases=["sync"], help="sync repository",
description="sync repository files to remote server according to current settings",
epilog="Synchronize the repository to remote services as configured.",
formatter_class=_formatter)
parser.set_defaults(handler=handlers.Triggers, trigger=["ahriman.core.upload.UploadTrigger"])
return parser
def _set_repo_triggers_parser(root: SubParserAction) -> argparse.ArgumentParser:
"""
add parser for repository triggers subcommand
Args: Args:
root(SubParserAction): subparsers for the commands root(SubParserAction): subparsers for the commands
@ -593,6 +631,8 @@ def _set_repo_triggers_parser(root: SubParserAction) -> argparse.ArgumentParser:
parser = root.add_parser("repo-triggers", help="run triggers", parser = root.add_parser("repo-triggers", help="run triggers",
description="run triggers on empty build result as configured by settings", description="run triggers on empty build result as configured by settings",
formatter_class=_formatter) formatter_class=_formatter)
parser.add_argument("trigger", help="instead of running all triggers as set by configuration, just process "
"specified ones oin order of metion", nargs="*")
parser.set_defaults(handler=handlers.Triggers) parser.set_defaults(handler=handlers.Triggers)
return parser return parser

View File

@ -45,4 +45,8 @@ class Triggers(Handler):
no_report(bool): force disable reporting no_report(bool): force disable reporting
unsafe(bool): if set no user check will be performed before path creation unsafe(bool): if set no user check will be performed before path creation
""" """
Application(architecture, configuration, no_report, unsafe).repository.process_triggers(Result()) application = Application(architecture, configuration, no_report, unsafe)
if args.trigger:
loader = application.repository.triggers
loader.triggers = [loader.load_trigger(trigger) for trigger in args.trigger]
application.repository.process_triggers(Result())

View File

@ -71,7 +71,7 @@ class TriggerLoader:
self.configuration = configuration self.configuration = configuration
self.triggers = [ self.triggers = [
self._load_trigger(trigger) self.load_trigger(trigger)
for trigger in configuration.getlist("build", "triggers") for trigger in configuration.getlist("build", "triggers")
] ]
@ -114,7 +114,7 @@ class TriggerLoader:
except ModuleNotFoundError: except ModuleNotFoundError:
raise InvalidExtension(f"Module {package} not found") raise InvalidExtension(f"Module {package} not found")
def _load_trigger(self, module_path: str) -> Trigger: def load_trigger(self, module_path: str) -> Trigger:
""" """
load trigger by module path load trigger by module path

View File

@ -4,15 +4,48 @@ from pytest_mock import MockerFixture
from ahriman.application.handlers import Triggers from ahriman.application.handlers import Triggers
from ahriman.core.configuration import Configuration from ahriman.core.configuration import Configuration
from ahriman.models.package import Package
from ahriman.models.result import Result from ahriman.models.result import Result
def _default_args(args: argparse.Namespace) -> argparse.Namespace:
"""
default arguments for these test cases
Args:
args(argparse.Namespace): command line arguments fixture
Returns:
argparse.Namespace: generated arguments for these test cases
"""
args.trigger = []
return args
def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None:
""" """
must run command must run command
""" """
args = _default_args(args)
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
application_mock = mocker.patch("ahriman.core.repository.Repository.process_triggers") application_mock = mocker.patch("ahriman.core.repository.Repository.process_triggers")
Triggers.run(args, "x86_64", configuration, True, False) Triggers.run(args, "x86_64", configuration, True, False)
application_mock.assert_called_once_with(Result()) application_mock.assert_called_once_with(Result())
def test_run_trigger(args: argparse.Namespace, configuration: Configuration, package_ahriman: Package,
mocker: MockerFixture) -> None:
"""
must run triggers specified by command line
"""
args = _default_args(args)
args.trigger = ["ahriman.core.report.ReportTrigger"]
mocker.patch("ahriman.core.repository.Repository.packages", return_value=[package_ahriman])
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
report_mock = mocker.patch("ahriman.core.report.ReportTrigger.run")
upload_mock = mocker.patch("ahriman.core.upload.UploadTrigger.run")
Triggers.run(args, "x86_64", configuration, True, False)
report_mock.assert_called_once_with(Result(), [package_ahriman])
upload_mock.assert_not_called()

View File

@ -348,6 +348,24 @@ def test_subparsers_repo_remove_unknown_architecture(parser: argparse.ArgumentPa
assert args.architecture == ["x86_64"] assert args.architecture == ["x86_64"]
def test_subparsers_repo_report(parser: argparse.ArgumentParser) -> None:
"""
repo-report command must imply trigger
"""
args = parser.parse_args(["repo-report"])
assert args.trigger == ["ahriman.core.report.ReportTrigger"]
def test_subparsers_repo_report_architecture(parser: argparse.ArgumentParser) -> None:
"""
repo-report command must correctly parse architecture list
"""
args = parser.parse_args(["repo-report"])
assert args.architecture is None
args = parser.parse_args(["-a", "x86_64", "repo-report"])
assert args.architecture == ["x86_64"]
def test_subparsers_repo_restore(parser: argparse.ArgumentParser) -> None: def test_subparsers_repo_restore(parser: argparse.ArgumentParser) -> None:
""" """
repo-restore command must imply architecture list, lock, no-report and unsafe repo-restore command must imply architecture list, lock, no-report and unsafe
@ -436,6 +454,24 @@ def test_subparsers_repo_status_update_option_status(parser: argparse.ArgumentPa
assert isinstance(args.status, BuildStatusEnum) assert isinstance(args.status, BuildStatusEnum)
def test_subparsers_repo_sync(parser: argparse.ArgumentParser) -> None:
"""
repo-sync command must imply trigger
"""
args = parser.parse_args(["repo-sync"])
assert args.trigger == ["ahriman.core.upload.UploadTrigger"]
def test_subparsers_repo_sync_architecture(parser: argparse.ArgumentParser) -> None:
"""
repo-sync command must correctly parse architecture list
"""
args = parser.parse_args(["repo-report"])
assert args.architecture is None
args = parser.parse_args(["-a", "x86_64", "repo-report"])
assert args.architecture == ["x86_64"]
def test_subparsers_repo_triggers_architecture(parser: argparse.ArgumentParser) -> None: def test_subparsers_repo_triggers_architecture(parser: argparse.ArgumentParser) -> None:
""" """
repo-triggers command must correctly parse architecture list repo-triggers command must correctly parse architecture list

View File

@ -13,7 +13,7 @@ def test_load_trigger_package(trigger_loader: TriggerLoader) -> None:
""" """
must load trigger from package must load trigger from package
""" """
assert trigger_loader._load_trigger("ahriman.core.report.ReportTrigger") assert trigger_loader.load_trigger("ahriman.core.report.ReportTrigger")
def test_load_trigger_package_invalid_import(trigger_loader: TriggerLoader, mocker: MockerFixture) -> None: def test_load_trigger_package_invalid_import(trigger_loader: TriggerLoader, mocker: MockerFixture) -> None:
@ -22,7 +22,7 @@ def test_load_trigger_package_invalid_import(trigger_loader: TriggerLoader, mock
""" """
mocker.patch("ahriman.core.triggers.trigger_loader.importlib.import_module", side_effect=ModuleNotFoundError()) mocker.patch("ahriman.core.triggers.trigger_loader.importlib.import_module", side_effect=ModuleNotFoundError())
with pytest.raises(InvalidExtension): with pytest.raises(InvalidExtension):
trigger_loader._load_trigger("random.module") trigger_loader.load_trigger("random.module")
def test_load_trigger_package_not_trigger(trigger_loader: TriggerLoader) -> None: def test_load_trigger_package_not_trigger(trigger_loader: TriggerLoader) -> None:
@ -30,7 +30,7 @@ def test_load_trigger_package_not_trigger(trigger_loader: TriggerLoader) -> None
must raise InvalidExtension if imported module is not a type must raise InvalidExtension if imported module is not a type
""" """
with pytest.raises(InvalidExtension): with pytest.raises(InvalidExtension):
trigger_loader._load_trigger("ahriman.core.util.check_output") trigger_loader.load_trigger("ahriman.core.util.check_output")
def test_load_trigger_package_error_on_creation(trigger_loader: TriggerLoader, mocker: MockerFixture) -> None: def test_load_trigger_package_error_on_creation(trigger_loader: TriggerLoader, mocker: MockerFixture) -> None:
@ -39,7 +39,7 @@ def test_load_trigger_package_error_on_creation(trigger_loader: TriggerLoader, m
""" """
mocker.patch("ahriman.core.triggers.trigger.Trigger.__init__", side_effect=Exception()) mocker.patch("ahriman.core.triggers.trigger.Trigger.__init__", side_effect=Exception())
with pytest.raises(InvalidExtension): with pytest.raises(InvalidExtension):
trigger_loader._load_trigger("ahriman.core.report.ReportTrigger") trigger_loader.load_trigger("ahriman.core.report.ReportTrigger")
def test_load_trigger_package_is_not_trigger(trigger_loader: TriggerLoader) -> None: def test_load_trigger_package_is_not_trigger(trigger_loader: TriggerLoader) -> None:
@ -47,7 +47,7 @@ def test_load_trigger_package_is_not_trigger(trigger_loader: TriggerLoader) -> N
must raise InvalidExtension if loaded class is not a trigger must raise InvalidExtension if loaded class is not a trigger
""" """
with pytest.raises(InvalidExtension): with pytest.raises(InvalidExtension):
trigger_loader._load_trigger("ahriman.core.sign.gpg.GPG") trigger_loader.load_trigger("ahriman.core.sign.gpg.GPG")
def test_load_trigger_path(trigger_loader: TriggerLoader, resource_path_root: Path) -> None: def test_load_trigger_path(trigger_loader: TriggerLoader, resource_path_root: Path) -> None:
@ -55,7 +55,7 @@ def test_load_trigger_path(trigger_loader: TriggerLoader, resource_path_root: Pa
must load trigger from path must load trigger from path
""" """
path = resource_path_root.parent.parent / "src" / "ahriman" / "core" / "report" / "report_trigger.py" path = resource_path_root.parent.parent / "src" / "ahriman" / "core" / "report" / "report_trigger.py"
assert trigger_loader._load_trigger(f"{path}.ReportTrigger") assert trigger_loader.load_trigger(f"{path}.ReportTrigger")
def test_load_trigger_path_directory(trigger_loader: TriggerLoader, resource_path_root: Path) -> None: def test_load_trigger_path_directory(trigger_loader: TriggerLoader, resource_path_root: Path) -> None:
@ -64,7 +64,7 @@ def test_load_trigger_path_directory(trigger_loader: TriggerLoader, resource_pat
""" """
path = resource_path_root.parent.parent / "src" / "ahriman" / "core" / "report" path = resource_path_root.parent.parent / "src" / "ahriman" / "core" / "report"
with pytest.raises(InvalidExtension): with pytest.raises(InvalidExtension):
trigger_loader._load_trigger(f"{path}.ReportTrigger") trigger_loader.load_trigger(f"{path}.ReportTrigger")
def test_load_trigger_path_not_found(trigger_loader: TriggerLoader) -> None: def test_load_trigger_path_not_found(trigger_loader: TriggerLoader) -> None:
@ -72,7 +72,7 @@ def test_load_trigger_path_not_found(trigger_loader: TriggerLoader) -> None:
must raise InvalidExtension if file cannot be found must raise InvalidExtension if file cannot be found
""" """
with pytest.raises(InvalidExtension): with pytest.raises(InvalidExtension):
trigger_loader._load_trigger("/some/random/path.py.SomeRandomModule") trigger_loader.load_trigger("/some/random/path.py.SomeRandomModule")
def test_process(trigger_loader: TriggerLoader, package_ahriman: Package, mocker: MockerFixture) -> None: def test_process(trigger_loader: TriggerLoader, package_ahriman: Package, mocker: MockerFixture) -> None: