mirror of
				https://github.com/arcan1s/ahriman.git
				synced 2025-10-30 21:33:43 +00:00 
			
		
		
		
	Setup command (#9)
* block issues without templates * add setup subcommand * handle devtools config correctly
This commit is contained in:
		
							
								
								
									
										1
									
								
								.github/ISSUE_TEMPLATE/config.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.github/ISSUE_TEMPLATE/config.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| blank_issues_enabled: false | ||||
| @ -19,14 +19,14 @@ Wrapper for managing custom repository inspired by [repo-scripts](https://github | ||||
| * Create `/var/lib/ahriman/.makepkg.conf` with `makepkg.conf` overrides if required (at least you might want to set `PACKAGER`): | ||||
|  | ||||
|     ```shell | ||||
|     echo 'PACKAGES="John Doe <john@doe.com>"' | sudo -u ahriman tee -a /var/lib/ahriman/.makepkg.conf | ||||
|     echo 'PACKAGER="John Doe <john@doe.com>"' | sudo -u ahriman tee -a /var/lib/ahriman/.makepkg.conf | ||||
|     ``` | ||||
|  | ||||
| * Configure build tools (it is required for correct dependency management system): | ||||
|  | ||||
|     * create build command, e.g. `ln -s /usr/bin/archbuild /usr/local/bin/ahriman-x86_64-build` (you can choose any name for command, basically it should be `{name}-{arch}-build`); | ||||
|     * create configuration file, e.g. `cp /usr/share/devtools/pacman-{extra,ahriman}.conf` (same as previous `pacman-{name}.conf`); | ||||
|     * change configuration file, add your own repository, add multilib repository etc. Hint: you can use `Include` option as well; | ||||
|     * change configuration file, add your own repository, add multilib repository etc; | ||||
|     * set `build_command` option to point to your command; | ||||
|     * configure `/etc/sudoers.d/ahriman` to allow running command without a password. | ||||
|  | ||||
| @ -66,3 +66,5 @@ Wrapper for managing custom repository inspired by [repo-scripts](https://github | ||||
|     ```shell | ||||
|     sudo -u ahriman ahriman -a x86_64 add yay | ||||
|     ``` | ||||
|  | ||||
| Note that initial service configuration can be done by running `ahriman setup` with specific arguments. | ||||
|  | ||||
| @ -31,12 +31,8 @@ def _parser() -> argparse.ArgumentParser: | ||||
|     :return: command line parser for the application | ||||
|     """ | ||||
|     parser = argparse.ArgumentParser(prog="ahriman", description="ArcHlinux ReposItory MANager") | ||||
|     parser.add_argument( | ||||
|         "-a", | ||||
|         "--architecture", | ||||
|         help="target architectures (can be used multiple times)", | ||||
|         action="append", | ||||
|         required=True) | ||||
|     parser.add_argument("-a", "--architecture", help="target architectures (can be used multiple times)", | ||||
|                         action="append", required=True) | ||||
|     parser.add_argument("-c", "--config", help="configuration path", default="/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") | ||||
| @ -44,6 +40,7 @@ def _parser() -> argparse.ArgumentParser: | ||||
|     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") | ||||
|     parser.add_argument("-v", "--version", action="version", version=version.__version__) | ||||
|  | ||||
|     subparsers = parser.add_subparsers(title="command", help="command to run", dest="command", required=True) | ||||
|  | ||||
|     add_parser = subparsers.add_parser("add", description="add package") | ||||
| @ -60,12 +57,10 @@ def _parser() -> argparse.ArgumentParser: | ||||
|     clean_parser.add_argument("--no-build", help="do not clear directory with package sources", action="store_true") | ||||
|     clean_parser.add_argument("--no-cache", help="do not clear directory with package caches", action="store_true") | ||||
|     clean_parser.add_argument("--no-chroot", help="do not clear build chroot", action="store_true") | ||||
|     clean_parser.add_argument( | ||||
|         "--no-manual", | ||||
|         help="do not clear directory with manually added packages", | ||||
|         action="store_true") | ||||
|     clean_parser.add_argument("--no-manual", help="do not clear directory with manually added packages", | ||||
|                               action="store_true") | ||||
|     clean_parser.add_argument("--no-packages", help="do not clear directory with built packages", action="store_true") | ||||
|     clean_parser.set_defaults(handler=handlers.Clean) | ||||
|     clean_parser.set_defaults(handler=handlers.Clean, unsafe=True) | ||||
|  | ||||
|     config_parser = subparsers.add_parser("config", description="dump configuration for specified architecture") | ||||
|     config_parser.set_defaults(handler=handlers.Dump, lock=None, no_report=True, unsafe=True) | ||||
| @ -81,6 +76,15 @@ def _parser() -> argparse.ArgumentParser: | ||||
|     report_parser.add_argument("target", help="target to generate report", nargs="*") | ||||
|     report_parser.set_defaults(handler=handlers.Report) | ||||
|  | ||||
|     setup_parser = subparsers.add_parser("setup", description="create initial service configuration, requires root") | ||||
|     setup_parser.add_argument("--build-command", help="build command prefix", default="ahriman") | ||||
|     setup_parser.add_argument("--from-config", help="path to default devtools pacman configuration", | ||||
|                               default="/usr/share/devtools/pacman-extra.conf") | ||||
|     setup_parser.add_argument("--no-multilib", help="do not add multilib repository", action="store_true") | ||||
|     setup_parser.add_argument("--packager", help="packager name and email", required=True) | ||||
|     setup_parser.add_argument("--repository", help="repository name", default="aur-clone") | ||||
|     setup_parser.set_defaults(handler=handlers.Setup, lock=None, no_report=True, unsafe=True) | ||||
|  | ||||
|     sign_parser = subparsers.add_parser("sign", description="(re-)sign packages and repository database") | ||||
|     sign_parser.add_argument("package", help="sign only specified packages", nargs="*") | ||||
|     sign_parser.set_defaults(handler=handlers.Sign) | ||||
| @ -96,8 +100,8 @@ def _parser() -> argparse.ArgumentParser: | ||||
|  | ||||
|     update_parser = subparsers.add_parser("update", description="run updates") | ||||
|     update_parser.add_argument("package", help="filter check by package base", nargs="*") | ||||
|     update_parser.add_argument( | ||||
|         "--dry-run", help="just perform check for updates, same as check command", action="store_true") | ||||
|     update_parser.add_argument("--dry-run", help="just perform check for updates, same as check command", | ||||
|                                action="store_true") | ||||
|     update_parser.add_argument("--no-aur", help="do not check for AUR updates. Implies --no-vcs", action="store_true") | ||||
|     update_parser.add_argument("--no-manual", help="do not include manual updates", action="store_true") | ||||
|     update_parser.add_argument("--no-vcs", help="do not check VCS packages", action="store_true") | ||||
| @ -110,8 +114,8 @@ def _parser() -> argparse.ArgumentParser: | ||||
|  | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     arg_parser = _parser() | ||||
|     args = arg_parser.parse_args() | ||||
|     args_parser = _parser() | ||||
|     args = args_parser.parse_args() | ||||
|  | ||||
|     handler: handlers.Handler = args.handler | ||||
|     status = handler.execute(args) | ||||
|  | ||||
| @ -25,6 +25,7 @@ from ahriman.application.handlers.dump import Dump | ||||
| from ahriman.application.handlers.rebuild import Rebuild | ||||
| from ahriman.application.handlers.remove import Remove | ||||
| from ahriman.application.handlers.report import Report | ||||
| from ahriman.application.handlers.setup import Setup | ||||
| from ahriman.application.handlers.sign import Sign | ||||
| from ahriman.application.handlers.status import Status | ||||
| from ahriman.application.handlers.sync import Sync | ||||
|  | ||||
							
								
								
									
										160
									
								
								src/ahriman/application/handlers/setup.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								src/ahriman/application/handlers/setup.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,160 @@ | ||||
| # | ||||
| # Copyright (c) 2021 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 <http://www.gnu.org/licenses/>. | ||||
| # | ||||
| import argparse | ||||
| import configparser | ||||
|  | ||||
| from pathlib import Path | ||||
| from typing import Type | ||||
|  | ||||
| from ahriman.application.application import Application | ||||
| from ahriman.application.handlers.handler import Handler | ||||
| from ahriman.core.configuration import Configuration | ||||
| from ahriman.models.repository_paths import RepositoryPaths | ||||
|  | ||||
|  | ||||
| class Setup(Handler): | ||||
|     """ | ||||
|     setup handler | ||||
|     :cvar ARCHBUILD_COMMAND_PATH: default devtools command | ||||
|     :cvar BIN_DIR_PATH: directory for custom binaries | ||||
|     :cvar MIRRORLIST_PATH: path to pacman default mirrorlist (used by multilib repository) | ||||
|     :cvar SUDOERS_PATH: path to sudoers.d include configuration | ||||
|     """ | ||||
|  | ||||
|     ARCHBUILD_COMMAND_PATH = Path("/usr/bin/archbuild") | ||||
|     BIN_DIR_PATH = Path("/usr/local/bin") | ||||
|     MIRRORLIST_PATH = Path("/etc/pacman.d/mirrorlist") | ||||
|     SUDOERS_PATH = Path("/etc/sudoers.d/ahriman") | ||||
|  | ||||
|     @classmethod | ||||
|     def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, config: Configuration) -> None: | ||||
|         """ | ||||
|         callback for command line | ||||
|         :param args: command line args | ||||
|         :param architecture: repository architecture | ||||
|         :param config: configuration instance | ||||
|         """ | ||||
|         application = Application(architecture, config) | ||||
|         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_config), args.no_multilib, | ||||
|                                             args.repository, application.repository.paths) | ||||
|         Setup.create_ahriman_configuration(args.build_command, architecture, args.repository, config.include) | ||||
|         Setup.create_sudo_configuration(args.build_command, architecture) | ||||
|  | ||||
|     @staticmethod | ||||
|     def build_command(prefix: str, architecture: str) -> Path: | ||||
|         """ | ||||
|         generate build command name | ||||
|         :param prefix: command prefix in {prefix}-{architecture}-build | ||||
|         :param architecture: repository architecture | ||||
|         :return: valid devtools command name | ||||
|         """ | ||||
|         return Setup.BIN_DIR_PATH / f"{prefix}-{architecture}-build" | ||||
|  | ||||
|     @staticmethod | ||||
|     def create_ahriman_configuration(prefix: str, architecture: str, repository: str, include_path: Path) -> None: | ||||
|         """ | ||||
|         create service specific configuration | ||||
|         :param prefix: command prefix in {prefix}-{architecture}-build | ||||
|         :param architecture: repository architecture | ||||
|         :param repository: repository name | ||||
|         :param include_path: path to directory with configuration includes | ||||
|         """ | ||||
|         config = configparser.ConfigParser() | ||||
|  | ||||
|         config.add_section("build") | ||||
|         config.set("build", "build_command", str(Setup.build_command(prefix, architecture))) | ||||
|  | ||||
|         config.add_section("repository") | ||||
|         config.set("repository", "name", repository) | ||||
|  | ||||
|         target = include_path / "build-overrides.ini" | ||||
|         with target.open("w") as ahriman_config: | ||||
|             config.write(ahriman_config) | ||||
|  | ||||
|     @staticmethod | ||||
|     def create_devtools_configuration(prefix: str, architecture: str, source: Path, | ||||
|                                       no_multilib: bool, repository: str, paths: RepositoryPaths) -> None: | ||||
|         """ | ||||
|         create configuration for devtools based on `source` configuration | ||||
|         :param prefix: command prefix in {prefix}-{architecture}-build | ||||
|         :param architecture: repository architecture | ||||
|         :param source: path to source configuration file | ||||
|         :param no_multilib: do not add multilib repository | ||||
|         :param repository: repository name | ||||
|         :param paths: repository paths instance | ||||
|         """ | ||||
|         config = configparser.ConfigParser() | ||||
|         # preserve case | ||||
|         # stupid mypy thinks that it is impossible | ||||
|         config.optionxform = lambda key: key  # type: ignore | ||||
|  | ||||
|         # load default configuration first | ||||
|         # we cannot use Include here because it will be copied to new chroot, thus no includes there | ||||
|         config.read(source) | ||||
|  | ||||
|         # set our architecture now | ||||
|         config.set("options", "Architecture", architecture) | ||||
|  | ||||
|         # add multilib | ||||
|         if not no_multilib: | ||||
|             config.add_section("multilib") | ||||
|             config.set("multilib", "Include", str(Setup.MIRRORLIST_PATH)) | ||||
|  | ||||
|         # add repository itself | ||||
|         config.add_section(repository) | ||||
|         config.set(repository, "SigLevel", "Optional TrustAll")  # we don't care | ||||
|         config.set(repository, "Server", f"file://{paths.repository}") | ||||
|  | ||||
|         target = source.parent / f"pacman-{prefix}.conf" | ||||
|         with target.open("w") as devtools_config: | ||||
|             config.write(devtools_config) | ||||
|  | ||||
|     @staticmethod | ||||
|     def create_makepkg_configuration(packager: str, paths: RepositoryPaths) -> None: | ||||
|         """ | ||||
|         create configuration for makepkg | ||||
|         :param packager: packager identifier (e.g. name, email) | ||||
|         :param paths: repository paths instance | ||||
|         """ | ||||
|         (paths.root / ".makepkg.conf").write_text(f"PACKAGER='{packager}'\n") | ||||
|  | ||||
|     @staticmethod | ||||
|     def create_sudo_configuration(prefix: str, architecture: str) -> None: | ||||
|         """ | ||||
|         create configuration to run build command with sudo without password | ||||
|         :param prefix: command prefix in {prefix}-{architecture}-build | ||||
|         :param architecture: repository architecture | ||||
|         """ | ||||
|         command = Setup.build_command(prefix, architecture) | ||||
|         Setup.SUDOERS_PATH.write_text(f"ahriman ALL=(ALL) NOPASSWD: {command} *\n") | ||||
|         Setup.SUDOERS_PATH.chmod(0o400)  # security! | ||||
|  | ||||
|     @staticmethod | ||||
|     def create_executable(prefix: str, architecture: str) -> None: | ||||
|         """ | ||||
|         create executable for the service | ||||
|         :param prefix: command prefix in {prefix}-{architecture}-build | ||||
|         :param architecture: repository architecture | ||||
|         """ | ||||
|         command = Setup.build_command(prefix, architecture) | ||||
|         command.unlink(missing_ok=True) | ||||
|         command.symlink_to(Setup.ARCHBUILD_COMMAND_PATH) | ||||
| @ -6,12 +6,17 @@ from ahriman.application.handlers import Add | ||||
| from ahriman.core.configuration import Configuration | ||||
|  | ||||
|  | ||||
| def _default_args(args: argparse.Namespace) -> argparse.Namespace: | ||||
|     args.package = [] | ||||
|     args.without_dependencies = False | ||||
|     return args | ||||
|  | ||||
|  | ||||
| def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: | ||||
|     """ | ||||
|     must run command | ||||
|     """ | ||||
|     args.package = [] | ||||
|     args.without_dependencies = False | ||||
|     args = _default_args(args) | ||||
|     mocker.patch("pathlib.Path.mkdir") | ||||
|     application_mock = mocker.patch("ahriman.application.application.Application.add") | ||||
|  | ||||
|  | ||||
| @ -6,15 +6,20 @@ from ahriman.application.handlers import Clean | ||||
| from ahriman.core.configuration import Configuration | ||||
|  | ||||
|  | ||||
| def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: | ||||
|     """ | ||||
|     must run command | ||||
|     """ | ||||
| def _default_args(args: argparse.Namespace) -> argparse.Namespace: | ||||
|     args.no_build = False | ||||
|     args.no_cache = False | ||||
|     args.no_chroot = False | ||||
|     args.no_manual = False | ||||
|     args.no_packages = False | ||||
|     return args | ||||
|  | ||||
|  | ||||
| def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: | ||||
|     """ | ||||
|     must run command | ||||
|     """ | ||||
|     args = _default_args(args) | ||||
|     mocker.patch("pathlib.Path.mkdir") | ||||
|     application_mock = mocker.patch("ahriman.application.application.Application.clean") | ||||
|  | ||||
|  | ||||
| @ -6,11 +6,16 @@ from ahriman.application.handlers import Remove | ||||
| from ahriman.core.configuration import Configuration | ||||
|  | ||||
|  | ||||
| def _default_args(args: argparse.Namespace) -> argparse.Namespace: | ||||
|     args.package = [] | ||||
|     return args | ||||
|  | ||||
|  | ||||
| def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: | ||||
|     """ | ||||
|     must run command | ||||
|     """ | ||||
|     args.package = [] | ||||
|     args = _default_args(args) | ||||
|     mocker.patch("pathlib.Path.mkdir") | ||||
|     application_mock = mocker.patch("ahriman.application.application.Application.remove") | ||||
|  | ||||
|  | ||||
| @ -6,11 +6,16 @@ from ahriman.application.handlers import Report | ||||
| from ahriman.core.configuration import Configuration | ||||
|  | ||||
|  | ||||
| def _default_args(args: argparse.Namespace) -> argparse.Namespace: | ||||
|     args.target = [] | ||||
|     return args | ||||
|  | ||||
|  | ||||
| def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: | ||||
|     """ | ||||
|     must run command | ||||
|     """ | ||||
|     args.target = [] | ||||
|     args = _default_args(args) | ||||
|     mocker.patch("pathlib.Path.mkdir") | ||||
|     application_mock = mocker.patch("ahriman.application.application.Application.report") | ||||
|  | ||||
|  | ||||
							
								
								
									
										145
									
								
								tests/ahriman/application/handlers/test_handler_setup.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								tests/ahriman/application/handlers/test_handler_setup.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,145 @@ | ||||
| import argparse | ||||
|  | ||||
| from pathlib import Path | ||||
| from pytest_mock import MockerFixture | ||||
| from unittest import mock | ||||
|  | ||||
| from ahriman.application.handlers import Setup | ||||
| from ahriman.core.configuration import Configuration | ||||
| from ahriman.models.repository_paths import RepositoryPaths | ||||
|  | ||||
|  | ||||
| def _default_args(args: argparse.Namespace) -> argparse.Namespace: | ||||
|     args.build_command = "ahriman" | ||||
|     args.from_config = "/usr/share/devtools/pacman-extra.conf" | ||||
|     args.no_multilib = False | ||||
|     args.packager = "John Doe <john@doe.com>" | ||||
|     args.repository = "aur-clone" | ||||
|     return args | ||||
|  | ||||
|  | ||||
| def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: | ||||
|     """ | ||||
|     must run command | ||||
|     """ | ||||
|     args = _default_args(args) | ||||
|     mocker.patch("pathlib.Path.mkdir") | ||||
|     ahriman_configuration_mock = mocker.patch("ahriman.application.handlers.setup.Setup.create_ahriman_configuration") | ||||
|     devtools_configuration_mock = mocker.patch("ahriman.application.handlers.setup.Setup.create_devtools_configuration") | ||||
|     makepkg_configuration_mock = mocker.patch("ahriman.application.handlers.setup.Setup.create_makepkg_configuration") | ||||
|     sudo_configuration_mock = mocker.patch("ahriman.application.handlers.setup.Setup.create_sudo_configuration") | ||||
|     executable_mock = mocker.patch("ahriman.application.handlers.setup.Setup.create_executable") | ||||
|  | ||||
|     Setup.run(args, "x86_64", configuration) | ||||
|     ahriman_configuration_mock.assert_called_once() | ||||
|     devtools_configuration_mock.assert_called_once() | ||||
|     makepkg_configuration_mock.assert_called_once() | ||||
|     sudo_configuration_mock.assert_called_once() | ||||
|     executable_mock.assert_called_once() | ||||
|  | ||||
|  | ||||
| def test_build_command(args: argparse.Namespace) -> None: | ||||
|     """ | ||||
|     must generate correct build command name | ||||
|     """ | ||||
|     args = _default_args(args) | ||||
|     assert Setup.build_command(args.build_command, "x86_64").name == f"{args.build_command}-x86_64-build" | ||||
|  | ||||
|  | ||||
| def test_create_ahriman_configuration(args: argparse.Namespace, configuration: Configuration, | ||||
|                                       mocker: MockerFixture) -> None: | ||||
|     """ | ||||
|     must create configuration for the service | ||||
|     """ | ||||
|     args = _default_args(args) | ||||
|     mocker.patch("pathlib.Path.open") | ||||
|     add_section_mock = mocker.patch("configparser.RawConfigParser.add_section") | ||||
|     set_mock = mocker.patch("configparser.RawConfigParser.set") | ||||
|     write_mock = mocker.patch("configparser.RawConfigParser.write") | ||||
|  | ||||
|     command = Setup.build_command(args.build_command, "x86_64") | ||||
|     Setup.create_ahriman_configuration(args.build_command, "x86_64", args.repository, configuration.include) | ||||
|     add_section_mock.assert_has_calls([ | ||||
|         mock.call("build"), | ||||
|         mock.call("repository"), | ||||
|     ]) | ||||
|     set_mock.assert_has_calls([ | ||||
|         mock.call("build", "build_command", str(command)), | ||||
|         mock.call("repository", "name", args.repository), | ||||
|     ]) | ||||
|     write_mock.assert_called_once() | ||||
|  | ||||
|  | ||||
| def test_create_devtools_configuration(args: argparse.Namespace, repository_paths: RepositoryPaths, | ||||
|                                        mocker: MockerFixture) -> None: | ||||
|     """ | ||||
|     must create configuration for the devtools | ||||
|     """ | ||||
|     args = _default_args(args) | ||||
|     mocker.patch("pathlib.Path.open") | ||||
|     mocker.patch("configparser.RawConfigParser.set") | ||||
|     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_config), args.no_multilib, | ||||
|                                         args.repository, repository_paths) | ||||
|     add_section_mock.assert_has_calls([ | ||||
|         mock.call("multilib"), | ||||
|         mock.call(args.repository) | ||||
|     ]) | ||||
|     write_mock.assert_called_once() | ||||
|  | ||||
|  | ||||
| def test_create_devtools_configuration_no_multilib(args: argparse.Namespace, repository_paths: RepositoryPaths, | ||||
|                                                    mocker: MockerFixture) -> None: | ||||
|     """ | ||||
|     must create configuration for the devtools without multilib | ||||
|     """ | ||||
|     args = _default_args(args) | ||||
|     mocker.patch("pathlib.Path.open") | ||||
|     mocker.patch("configparser.RawConfigParser.set") | ||||
|     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_config), True, | ||||
|                                         args.repository, repository_paths) | ||||
|     add_section_mock.assert_called_once() | ||||
|     write_mock.assert_called_once() | ||||
|  | ||||
|  | ||||
| def test_create_makepkg_configuration(args: argparse.Namespace, repository_paths: RepositoryPaths, | ||||
|                                       mocker: MockerFixture) -> None: | ||||
|     """ | ||||
|     must create makepkg configuration | ||||
|     """ | ||||
|     args = _default_args(args) | ||||
|     write_text_mock = mocker.patch("pathlib.Path.write_text") | ||||
|  | ||||
|     Setup.create_makepkg_configuration(args.packager, repository_paths) | ||||
|     write_text_mock.assert_called_once() | ||||
|  | ||||
|  | ||||
| def test_create_sudo_configuration(args: argparse.Namespace, mocker: MockerFixture) -> None: | ||||
|     """ | ||||
|     must create sudo configuration | ||||
|     """ | ||||
|     args = _default_args(args) | ||||
|     chmod_text_mock = mocker.patch("pathlib.Path.chmod") | ||||
|     write_text_mock = mocker.patch("pathlib.Path.write_text") | ||||
|  | ||||
|     Setup.create_sudo_configuration(args.build_command, "x86_64") | ||||
|     chmod_text_mock.assert_called_with(0o400) | ||||
|     write_text_mock.assert_called_once() | ||||
|  | ||||
|  | ||||
| def test_create_executable(args: argparse.Namespace, mocker: MockerFixture) -> None: | ||||
|     """ | ||||
|     must create executable | ||||
|     """ | ||||
|     args = _default_args(args) | ||||
|     symlink_text_mock = mocker.patch("pathlib.Path.symlink_to") | ||||
|     unlink_text_mock = mocker.patch("pathlib.Path.unlink") | ||||
|  | ||||
|     Setup.create_executable(args.build_command, "x86_64") | ||||
|     symlink_text_mock.assert_called_once() | ||||
|     unlink_text_mock.assert_called_once() | ||||
| @ -6,11 +6,16 @@ from ahriman.application.handlers import Sign | ||||
| from ahriman.core.configuration import Configuration | ||||
|  | ||||
|  | ||||
| def _default_args(args: argparse.Namespace) -> argparse.Namespace: | ||||
|     args.package = [] | ||||
|     return args | ||||
|  | ||||
|  | ||||
| def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: | ||||
|     """ | ||||
|     must run command | ||||
|     """ | ||||
|     args.package = [] | ||||
|     args = _default_args(args) | ||||
|     mocker.patch("pathlib.Path.mkdir") | ||||
|     application_mock = mocker.patch("ahriman.application.application.Application.sign") | ||||
|  | ||||
|  | ||||
| @ -6,13 +6,17 @@ from ahriman.application.handlers import Status | ||||
| from ahriman.core.configuration import Configuration | ||||
|  | ||||
|  | ||||
| def _default_args(args: argparse.Namespace) -> argparse.Namespace: | ||||
|     args.ahriman = True | ||||
|     args.package = [] | ||||
|     return args | ||||
|  | ||||
|  | ||||
| def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: | ||||
|     """ | ||||
|     must run command | ||||
|     """ | ||||
|     args.ahriman = True | ||||
|     args.package = [] | ||||
|     args.without_dependencies = False | ||||
|     args = _default_args(args) | ||||
|     mocker.patch("pathlib.Path.mkdir") | ||||
|     application_mock = mocker.patch("ahriman.core.status.client.Client.get_self") | ||||
|     packages_mock = mocker.patch("ahriman.core.status.client.Client.get") | ||||
|  | ||||
| @ -6,11 +6,16 @@ from ahriman.application.handlers import Sync | ||||
| from ahriman.core.configuration import Configuration | ||||
|  | ||||
|  | ||||
| def _default_args(args: argparse.Namespace) -> argparse.Namespace: | ||||
|     args.target = [] | ||||
|     return args | ||||
|  | ||||
|  | ||||
| def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: | ||||
|     """ | ||||
|     must run command | ||||
|     """ | ||||
|     args.target = [] | ||||
|     args = _default_args(args) | ||||
|     mocker.patch("pathlib.Path.mkdir") | ||||
|     application_mock = mocker.patch("ahriman.application.application.Application.sync") | ||||
|  | ||||
|  | ||||
| @ -6,15 +6,20 @@ from ahriman.application.handlers import Update | ||||
| from ahriman.core.configuration import Configuration | ||||
|  | ||||
|  | ||||
| def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: | ||||
|     """ | ||||
|     must run command | ||||
|     """ | ||||
| def _default_args(args: argparse.Namespace) -> argparse.Namespace: | ||||
|     args.package = [] | ||||
|     args.dry_run = False | ||||
|     args.no_aur = False | ||||
|     args.no_manual = False | ||||
|     args.no_vcs = False | ||||
|     return args | ||||
|  | ||||
|  | ||||
| def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: | ||||
|     """ | ||||
|     must run command | ||||
|     """ | ||||
|     args = _default_args(args) | ||||
|     mocker.patch("pathlib.Path.mkdir") | ||||
|     application_mock = mocker.patch("ahriman.application.application.Application.update") | ||||
|     updates_mock = mocker.patch("ahriman.application.application.Application.get_updates") | ||||
| @ -28,11 +33,8 @@ def test_run_dry_run(args: argparse.Namespace, configuration: Configuration, moc | ||||
|     """ | ||||
|     must run simplified command | ||||
|     """ | ||||
|     args.package = [] | ||||
|     args = _default_args(args) | ||||
|     args.dry_run = True | ||||
|     args.no_aur = False | ||||
|     args.no_manual = False | ||||
|     args.no_vcs = False | ||||
|     mocker.patch("pathlib.Path.mkdir") | ||||
|     updates_mock = mocker.patch("ahriman.application.application.Application.get_updates") | ||||
|  | ||||
|  | ||||
| @ -26,6 +26,14 @@ def test_subparsers_check(parser: argparse.ArgumentParser) -> None: | ||||
|     assert args.dry_run | ||||
|  | ||||
|  | ||||
| def test_subparsers_clean(parser: argparse.ArgumentParser) -> None: | ||||
|     """ | ||||
|     clean command must imply unsafe | ||||
|     """ | ||||
|     args = parser.parse_args(["-a", "x86_64", "clean"]) | ||||
|     assert args.unsafe | ||||
|  | ||||
|  | ||||
| def test_subparsers_config(parser: argparse.ArgumentParser) -> None: | ||||
|     """ | ||||
|     config command must imply lock, no_report and unsafe | ||||
| @ -36,6 +44,16 @@ def test_subparsers_config(parser: argparse.ArgumentParser) -> None: | ||||
|     assert args.unsafe | ||||
|  | ||||
|  | ||||
| def test_subparsers_setup(parser: argparse.ArgumentParser) -> None: | ||||
|     """ | ||||
|     setup command must imply lock, no_report and unsafe | ||||
|     """ | ||||
|     args = parser.parse_args(["-a", "x86_64", "setup", "--packager", "John Doe <john@doe.com>"]) | ||||
|     assert args.lock is None | ||||
|     assert args.no_report | ||||
|     assert args.unsafe | ||||
|  | ||||
|  | ||||
| def test_subparsers_status(parser: argparse.ArgumentParser) -> None: | ||||
|     """ | ||||
|     status command must imply lock, no_report and unsafe | ||||
|  | ||||
| @ -1,4 +1,5 @@ | ||||
| [settings] | ||||
| include = . | ||||
| logging = logging.ini | ||||
|  | ||||
| [alpm] | ||||
|  | ||||
		Reference in New Issue
	
	Block a user