From 0bd3ba626ade36bfa4a31bd97f550a9c917daa68 Mon Sep 17 00:00:00 2001 From: Evgeniy Alekseev Date: Sun, 4 Apr 2021 23:53:30 +0300 Subject: [PATCH] implicit type conversion from command line --- src/ahriman/application/ahriman.py | 19 ++++--- src/ahriman/application/handlers/setup.py | 4 +- .../application/handlers/status_update.py | 6 +- .../application/handlers/test_handler.py | 3 +- .../handlers/test_handler_setup.py | 12 ++-- .../handlers/test_handler_status_update.py | 2 +- tests/ahriman/application/test_ahriman.py | 55 +++++++++++++++++++ 7 files changed, 79 insertions(+), 22 deletions(-) diff --git a/src/ahriman/application/ahriman.py b/src/ahriman/application/ahriman.py index e72373e5..4a300b21 100644 --- a/src/ahriman/application/ahriman.py +++ b/src/ahriman/application/ahriman.py @@ -20,16 +20,17 @@ import argparse import sys +from pathlib import Path + import ahriman.application.handlers as handlers import ahriman.version as version from ahriman.models.build_status import BuildStatusEnum +from ahriman.models.sign_settings import SignSettings # pylint thinks it is bad idea, but get the fuck off # pylint: disable=protected-access -from ahriman.models.sign_settings import SignSettings - SubParserAction = argparse._SubParsersAction @@ -42,9 +43,9 @@ def _parser() -> argparse.ArgumentParser: formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument("-a", "--architecture", help="target architectures (can be used multiple times)", action="append", required=True) - parser.add_argument("-c", "--configuration", help="configuration path", default="/etc/ahriman.ini") + parser.add_argument("-c", "--configuration", help="configuration path", type=Path, default=Path("/etc/ahriman.ini")) parser.add_argument("--force", help="force run, remove file lock", action="store_true") - parser.add_argument("--lock", help="lock file", default="/tmp/ahriman.lock") + parser.add_argument("-l", "--lock", help="lock file", type=Path, default=Path("/tmp/ahriman.lock")) parser.add_argument("--no-log", help="redirect all log messages to stderr", action="store_true") parser.add_argument("--no-report", help="force disable reporting to web service", action="store_true") parser.add_argument("--unsafe", help="allow to run ahriman as non-ahriman user", action="store_true") @@ -180,13 +181,13 @@ def _set_setup_parser(root: SubParserAction) -> argparse.ArgumentParser: formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument("--build-command", help="build command prefix", default="ahriman") parser.add_argument("--from-configuration", help="path to default devtools pacman configuration", - default="/usr/share/devtools/pacman-extra.conf") + type=Path, default=Path("/usr/share/devtools/pacman-extra.conf")) parser.add_argument("--no-multilib", help="do not add multilib repository", action="store_true") parser.add_argument("--packager", help="packager name and email", required=True) parser.add_argument("--repository", help="repository name", required=True) parser.add_argument("--sign-key", help="sign key id") - parser.add_argument("--sign-target", help="sign options", - choices=[sign.name.lower() for sign in SignSettings], nargs="*") + parser.add_argument("--sign-target", help="sign options", type=SignSettings.from_option, + choices=SignSettings, nargs="*") parser.add_argument("--web-port", help="port of the web service", type=int) parser.set_defaults(handler=handlers.Setup, lock=None, no_report=True, unsafe=True) return parser @@ -231,8 +232,8 @@ def _set_status_update_parser(root: SubParserAction) -> argparse.ArgumentParser: "package", help="set status for specified packages. If no packages supplied, service status will be updated", nargs="*") - parser.add_argument("--status", help="new status", choices=[value.value for value in BuildStatusEnum], - default="success") + parser.add_argument("--status", help="new status", choices=BuildStatusEnum, + type=BuildStatusEnum, default=BuildStatusEnum.Success) parser.add_argument("--remove", help="remove package status page", action="store_true") parser.set_defaults(handler=handlers.StatusUpdate, lock=None, no_report=True, unsafe=True) return parser diff --git a/src/ahriman/application/handlers/setup.py b/src/ahriman/application/handlers/setup.py index de58858c..c00237b4 100644 --- a/src/ahriman/application/handlers/setup.py +++ b/src/ahriman/application/handlers/setup.py @@ -54,7 +54,7 @@ class Setup(Handler): application = Application(architecture, configuration) Setup.create_makepkg_configuration(args.packager, application.repository.paths) Setup.create_executable(args.build_command, architecture) - Setup.create_devtools_configuration(args.build_command, architecture, Path(args.from_configuration), + Setup.create_devtools_configuration(args.build_command, architecture, args.from_configuration, args.no_multilib, args.repository, application.repository.paths) Setup.create_ahriman_configuration(args, architecture, args.repository, configuration.include) Setup.create_sudo_configuration(args.build_command, architecture) @@ -91,7 +91,7 @@ class Setup(Handler): if args.sign_key is not None: section = Configuration.section_name("sign", architecture) configuration.add_section(section) - configuration.set(section, "target", " ".join(args.sign_target)) + configuration.set(section, "target", " ".join([target.name.lower() for target in args.sign_target])) configuration.set(section, "key", args.sign_key) if args.web_port is not None: diff --git a/src/ahriman/application/handlers/status_update.py b/src/ahriman/application/handlers/status_update.py index 64bcb2cd..39647dc0 100644 --- a/src/ahriman/application/handlers/status_update.py +++ b/src/ahriman/application/handlers/status_update.py @@ -24,7 +24,6 @@ from typing import Callable, Type from ahriman.application.application import Application from ahriman.application.handlers.handler import Handler from ahriman.core.configuration import Configuration -from ahriman.models.build_status import BuildStatusEnum class StatusUpdate(Handler): @@ -41,12 +40,11 @@ class StatusUpdate(Handler): :param configuration: configuration instance """ client = Application(architecture, configuration).repository.reporter - status = BuildStatusEnum(args.status) - callback: Callable[[str], None] = lambda p: client.remove(p) if args.remove else client.update(p, status) + callback: Callable[[str], None] = lambda p: client.remove(p) if args.remove else client.update(p, args.status) if args.package: # update packages statuses for package in args.package: callback(package) else: # update service status - client.update_self(status) + client.update_self(args.status) diff --git a/tests/ahriman/application/handlers/test_handler.py b/tests/ahriman/application/handlers/test_handler.py index 89d71a18..c92a17f2 100644 --- a/tests/ahriman/application/handlers/test_handler.py +++ b/tests/ahriman/application/handlers/test_handler.py @@ -1,6 +1,7 @@ import argparse import pytest +from pathlib import Path from pytest_mock import MockerFixture from ahriman.application.handlers import Handler @@ -11,7 +12,7 @@ def test_call(args: argparse.Namespace, mocker: MockerFixture) -> None: """ must call inside lock """ - args.configuration = "" + args.configuration = Path("") args.no_log = False mocker.patch("ahriman.application.handlers.Handler.run") mocker.patch("ahriman.core.configuration.Configuration.from_path") diff --git a/tests/ahriman/application/handlers/test_handler_setup.py b/tests/ahriman/application/handlers/test_handler_setup.py index 399ca79a..365952a2 100644 --- a/tests/ahriman/application/handlers/test_handler_setup.py +++ b/tests/ahriman/application/handlers/test_handler_setup.py @@ -7,16 +7,17 @@ from unittest import mock from ahriman.application.handlers import Setup from ahriman.core.configuration import Configuration from ahriman.models.repository_paths import RepositoryPaths +from ahriman.models.sign_settings import SignSettings def _default_args(args: argparse.Namespace) -> argparse.Namespace: args.build_command = "ahriman" - args.from_configuration = "/usr/share/devtools/pacman-extra.conf" + args.from_configuration = Path("/usr/share/devtools/pacman-extra.conf") args.no_multilib = False args.packager = "John Doe " args.repository = "aur-clone" args.sign_key = "key" - args.sign_target = ["packages"] + args.sign_target = [SignSettings.Packages] args.web_port = 8080 return args @@ -71,7 +72,8 @@ def test_create_ahriman_configuration(args: argparse.Namespace, configuration: C set_mock.assert_has_calls([ mock.call(Configuration.section_name("build", "x86_64"), "build_command", str(command)), mock.call("repository", "name", args.repository), - mock.call(Configuration.section_name("sign", "x86_64"), "target", " ".join(args.sign_target)), + mock.call(Configuration.section_name("sign", "x86_64"), "target", + " ".join([target.name.lower() for target in args.sign_target])), mock.call(Configuration.section_name("sign", "x86_64"), "key", args.sign_key), mock.call(Configuration.section_name("web", "x86_64"), "port", str(args.web_port)), ]) @@ -89,7 +91,7 @@ def test_create_devtools_configuration(args: argparse.Namespace, repository_path add_section_mock = mocker.patch("configparser.RawConfigParser.add_section") write_mock = mocker.patch("configparser.RawConfigParser.write") - Setup.create_devtools_configuration(args.build_command, "x86_64", Path(args.from_configuration), + Setup.create_devtools_configuration(args.build_command, "x86_64", args.from_configuration, args.no_multilib, args.repository, repository_paths) add_section_mock.assert_has_calls([ mock.call("multilib"), @@ -109,7 +111,7 @@ def test_create_devtools_configuration_no_multilib(args: argparse.Namespace, rep add_section_mock = mocker.patch("configparser.RawConfigParser.add_section") write_mock = mocker.patch("configparser.RawConfigParser.write") - Setup.create_devtools_configuration(args.build_command, "x86_64", Path(args.from_configuration), + Setup.create_devtools_configuration(args.build_command, "x86_64", args.from_configuration, True, args.repository, repository_paths) add_section_mock.assert_called_once() write_mock.assert_called_once() diff --git a/tests/ahriman/application/handlers/test_handler_status_update.py b/tests/ahriman/application/handlers/test_handler_status_update.py index 0e6ebe39..7dce4efd 100644 --- a/tests/ahriman/application/handlers/test_handler_status_update.py +++ b/tests/ahriman/application/handlers/test_handler_status_update.py @@ -9,7 +9,7 @@ from ahriman.models.package import Package def _default_args(args: argparse.Namespace) -> argparse.Namespace: - args.status = BuildStatusEnum.Success.value + args.status = BuildStatusEnum.Success args.package = None args.remove = False return args diff --git a/tests/ahriman/application/test_ahriman.py b/tests/ahriman/application/test_ahriman.py index fb13909a..a530ab7a 100644 --- a/tests/ahriman/application/test_ahriman.py +++ b/tests/ahriman/application/test_ahriman.py @@ -1,8 +1,11 @@ import argparse +from pathlib import Path from pytest_mock import MockerFixture from ahriman.application.handlers import Handler +from ahriman.models.build_status import BuildStatusEnum +from ahriman.models.sign_settings import SignSettings def test_parser(parser: argparse.ArgumentParser) -> None: @@ -12,6 +15,26 @@ def test_parser(parser: argparse.ArgumentParser) -> None: parser.parse_args(["-a", "x86_64", "config"]) +def test_parser_option_configuration(parser: argparse.ArgumentParser) -> None: + """ + must convert configuration option to Path instance + """ + args = parser.parse_args(["-a", "x86_64", "config"]) + assert isinstance(args.configuration, Path) + args = parser.parse_args(["-a", "x86_64", "-c", "ahriman.ini", "config"]) + assert isinstance(args.configuration, Path) + + +def test_parser_option_lock(parser: argparse.ArgumentParser) -> None: + """ + must convert lock option to Path instance + """ + args = parser.parse_args(["-a", "x86_64", "update"]) + assert isinstance(args.lock, Path) + args = parser.parse_args(["-a", "x86_64", "-l", "ahriman.lock", "update"]) + assert isinstance(args.lock, Path) + + def test_multiple_architectures(parser: argparse.ArgumentParser) -> None: """ must accept multiple architectures @@ -59,6 +82,28 @@ def test_subparsers_setup(parser: argparse.ArgumentParser) -> None: assert args.unsafe +def test_subparsers_setup_option_from_configuration(parser: argparse.ArgumentParser) -> None: + """ + setup command must convert from-configuration option to path instance + """ + args = parser.parse_args(["-a", "x86_64", "setup", "--packager", "John Doe ", + "--repository", "aur-clone"]) + assert isinstance(args.from_configuration, Path) + args = parser.parse_args(["-a", "x86_64", "setup", "--packager", "John Doe ", + "--repository", "aur-clone", "--from-configuration", "path"]) + assert isinstance(args.from_configuration, Path) + + +def test_subparsers_setup_option_sign_target(parser: argparse.ArgumentParser) -> None: + """ + setup command must convert sign-target option to signsettings instance + """ + args = parser.parse_args(["-a", "x86_64", "setup", "--packager", "John Doe ", + "--repository", "aur-clone", "--sign-target", "packages"]) + assert args.sign_target + assert all(isinstance(target, SignSettings) for target in args.sign_target) + + def test_subparsers_status(parser: argparse.ArgumentParser) -> None: """ status command must imply lock, no_report and unsafe @@ -79,6 +124,16 @@ def test_subparsers_status_update(parser: argparse.ArgumentParser) -> None: assert args.unsafe +def test_subparsers_status_update_option_status(parser: argparse.ArgumentParser) -> None: + """ + status-update command must convert status option to buildstatusenum instance + """ + args = parser.parse_args(["-a", "x86_64", "status-update"]) + assert isinstance(args.status, BuildStatusEnum) + args = parser.parse_args(["-a", "x86_64", "status-update", "--status", "failed"]) + assert isinstance(args.status, BuildStatusEnum) + + def test_subparsers_web(parser: argparse.ArgumentParser) -> None: """ web command must imply lock and no_report