diff --git a/.github/workflows/setup.sh b/.github/workflows/setup.sh index 25692d41..c8d064ba 100755 --- a/.github/workflows/setup.sh +++ b/.github/workflows/setup.sh @@ -10,7 +10,7 @@ echo -e '[arcanisrepo]\nServer = http://repo.arcanis.me/$arch\nSigLevel = Never' # refresh the image pacman --noconfirm -Syu # main dependencies -pacman --noconfirm -Sy base-devel devtools git pyalpm python-aur python-passlib python-setuptools python-srcinfo sudo +pacman --noconfirm -Sy base-devel devtools git pyalpm python-cerberus python-inflection python-passlib python-requests python-setuptools python-srcinfo sudo # make dependencies pacman --noconfirm -Sy python-build python-installer python-wheel # optional dependencies @@ -39,6 +39,8 @@ sed -i "s/handlers = syslog_handler/handlers = console_handler/g" /etc/ahriman.i # initial setup command as root [[ -z $MINIMAL_INSTALL ]] && WEB_ARGS=("--web-port" "8080") ahriman -a x86_64 repo-setup --packager "ahriman bot " --repository "github" "${WEB_ARGS[@]}" +# validate configuration +ahriman -a x86_64 repo-config-validate --exit-code # enable services systemctl enable ahriman-web@x86_64 systemctl enable ahriman@x86_64.timer diff --git a/docs/ahriman.1 b/docs/ahriman.1 index 2b8112c7..baae1399 100644 --- a/docs/ahriman.1 +++ b/docs/ahriman.1 @@ -460,10 +460,15 @@ usage: ahriman repo\-config [\-h] dump configuration for the specified architecture .SH COMMAND \fI\,'ahriman repo\-config\-validate'\/\fR -usage: ahriman repo\-config\-validate [\-h] +usage: ahriman repo\-config\-validate [\-h] [\-e] validate configuration and print found errors +.SH OPTIONS \fI\,'ahriman repo\-config\-validate'\/\fR +.TP +\fB\-e\fR, \fB\-\-exit\-code\fR +return non\-zero exit status if configuration is invalid + .SH COMMAND \fI\,'ahriman repo\-rebuild'\/\fR usage: ahriman repo\-rebuild [\-h] [\-\-depends\-on DEPENDS_ON] [\-\-dry\-run] [\-\-from\-database] [\-e] diff --git a/docs/completions/bash/_ahriman b/docs/completions/bash/_ahriman index b1c11a90..ef5eb435 100644 --- a/docs/completions/bash/_ahriman +++ b/docs/completions/bash/_ahriman @@ -30,8 +30,8 @@ _shtab_ahriman_repo_clean_option_strings=('-h' '--help' '--cache' '--no-cache' ' _shtab_ahriman_clean_option_strings=('-h' '--help' '--cache' '--no-cache' '--chroot' '--no-chroot' '--manual' '--no-manual' '--packages' '--no-packages' '--pacman' '--no-pacman') _shtab_ahriman_repo_config_option_strings=('-h' '--help') _shtab_ahriman_config_option_strings=('-h' '--help') -_shtab_ahriman_repo_config_validate_option_strings=('-h' '--help') -_shtab_ahriman_config_validate_option_strings=('-h' '--help') +_shtab_ahriman_repo_config_validate_option_strings=('-h' '--help' '-e' '--exit-code') +_shtab_ahriman_config_validate_option_strings=('-h' '--help' '-e' '--exit-code') _shtab_ahriman_repo_rebuild_option_strings=('-h' '--help' '--depends-on' '--dry-run' '--from-database' '-e' '--exit-code') _shtab_ahriman_rebuild_option_strings=('-h' '--help' '--depends-on' '--dry-run' '--from-database' '-e' '--exit-code') _shtab_ahriman_repo_remove_unknown_option_strings=('-h' '--help' '--dry-run') @@ -253,8 +253,12 @@ _shtab_ahriman_config__h_nargs=0 _shtab_ahriman_config___help_nargs=0 _shtab_ahriman_repo_config_validate__h_nargs=0 _shtab_ahriman_repo_config_validate___help_nargs=0 +_shtab_ahriman_repo_config_validate__e_nargs=0 +_shtab_ahriman_repo_config_validate___exit_code_nargs=0 _shtab_ahriman_config_validate__h_nargs=0 _shtab_ahriman_config_validate___help_nargs=0 +_shtab_ahriman_config_validate__e_nargs=0 +_shtab_ahriman_config_validate___exit_code_nargs=0 _shtab_ahriman_repo_rebuild__h_nargs=0 _shtab_ahriman_repo_rebuild___help_nargs=0 _shtab_ahriman_repo_rebuild___dry_run_nargs=0 diff --git a/docs/completions/zsh/_ahriman b/docs/completions/zsh/_ahriman index a281a3e1..8e1aa3c6 100644 --- a/docs/completions/zsh/_ahriman +++ b/docs/completions/zsh/_ahriman @@ -117,6 +117,7 @@ _shtab_ahriman_config_options=( _shtab_ahriman_config_validate_options=( "(- : *)"{-h,--help}"[show this help message and exit]" + {-e,--exit-code}"[return non-zero exit status if configuration is invalid]" ) _shtab_ahriman_daemon_options=( @@ -277,6 +278,7 @@ _shtab_ahriman_repo_config_options=( _shtab_ahriman_repo_config_validate_options=( "(- : *)"{-h,--help}"[show this help message and exit]" + {-e,--exit-code}"[return non-zero exit status if configuration is invalid]" ) _shtab_ahriman_repo_init_options=( diff --git a/src/ahriman/application/ahriman.py b/src/ahriman/application/ahriman.py index 4c1597d6..cf609737 100644 --- a/src/ahriman/application/ahriman.py +++ b/src/ahriman/application/ahriman.py @@ -551,6 +551,8 @@ def _set_repo_config_validate_parser(root: SubParserAction) -> argparse.Argument parser = root.add_parser("repo-config-validate", aliases=["config-validate"], help="validate system configuration", description="validate configuration and print found errors", formatter_class=_formatter) + parser.add_argument("-e", "--exit-code", help="return non-zero exit status if configuration is invalid", + action="store_true") parser.set_defaults(handler=handlers.Validate, lock=None, report=False, quiet=True, unsafe=True) return parser diff --git a/src/ahriman/application/handlers/validate.py b/src/ahriman/application/handlers/validate.py index a129b5a5..f3f48f36 100644 --- a/src/ahriman/application/handlers/validate.py +++ b/src/ahriman/application/handlers/validate.py @@ -54,11 +54,15 @@ class Validate(Handler): """ schema = Validate.schema(architecture, configuration) validator = Validator(instance=configuration, schema=schema) + if validator.validate(configuration.dump()): return # no errors found for node, errors in validator.errors.items(): ValidationPrinter(node, errors).print(verbose=True) + # as we reach this part it means that we always have errors + Validate.check_if_empty(args.exit_code, True) + @staticmethod def schema(architecture: str, configuration: Configuration) -> Dict[str, Any]: """ diff --git a/tests/ahriman/application/handlers/test_handler_validate.py b/tests/ahriman/application/handlers/test_handler_validate.py index 39a82423..bc92097f 100644 --- a/tests/ahriman/application/handlers/test_handler_validate.py +++ b/tests/ahriman/application/handlers/test_handler_validate.py @@ -9,10 +9,25 @@ from ahriman.core.configuration.schema import CONFIGURATION_SCHEMA, GITREMOTE_RE from ahriman.core.configuration.validator import Validator +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.exit_code = False + return args + + def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: """ must run command """ + args = _default_args(args) mocker.patch.object(Validator, "errors", {"node": ["error"]}) print_mock = mocker.patch("ahriman.core.formatters.Printer.print") application_mock = mocker.patch("ahriman.core.configuration.validator.Validator.validate", return_value=False) @@ -27,6 +42,7 @@ def test_run_skip(args: argparse.Namespace, configuration: Configuration, mocker """ must skip print if no errors found """ + args = _default_args(args) mocker.patch("ahriman.core.configuration.validator.Validator.validate", return_value=True) print_mock = mocker.patch("ahriman.core.formatters.Printer.print")