more verbose help messages

This commit is contained in:
Evgenii Alekseev 2021-10-07 01:56:15 +03:00
parent 5cfffbcd46
commit ef44895b0d
15 changed files with 501 additions and 418 deletions

View File

@ -1,5 +1,5 @@
[loggers] [loggers]
keys = root,builder,build_details,http keys = root,builder,build_details,http,stderr
[handlers] [handlers]
keys = console_handler,syslog_handler keys = console_handler,syslog_handler
@ -49,3 +49,8 @@ level = DEBUG
handlers = syslog_handler handlers = syslog_handler
qualname = http qualname = http
propagate = 0 propagate = 0
[logger_stderr]
level = DEBUG
handlers = console_handler
qualname = stderr

View File

@ -67,105 +67,46 @@ def _parser() -> argparse.ArgumentParser:
parser.add_argument("--unsafe", help="allow to run ahriman as non-ahriman user", 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__) parser.add_argument("-v", "--version", action="version", version=version.__version__)
subparsers = parser.add_subparsers(title="command", help="command to run", dest="command") subparsers = parser.add_subparsers(title="command", help="command to run", dest="command", required=True)
_set_add_parser(subparsers) _set_aur_search_parser(subparsers)
_set_check_parser(subparsers)
_set_clean_parser(subparsers)
_set_config_parser(subparsers)
_set_init_parser(subparsers)
_set_key_import_parser(subparsers) _set_key_import_parser(subparsers)
_set_package_add_parser(subparsers)
_set_package_remove_parser(subparsers)
_set_package_status_parser(subparsers)
_set_package_status_remove_parser(subparsers)
_set_package_status_update_parser(subparsers)
_set_patch_add_parser(subparsers) _set_patch_add_parser(subparsers)
_set_patch_list_parser(subparsers) _set_patch_list_parser(subparsers)
_set_patch_remove_parser(subparsers) _set_patch_remove_parser(subparsers)
_set_rebuild_parser(subparsers) _set_repo_check_parser(subparsers)
_set_remove_parser(subparsers) _set_repo_clean_parser(subparsers)
_set_remove_unknown_parser(subparsers) _set_repo_config_parser(subparsers)
_set_report_parser(subparsers) _set_repo_init_parser(subparsers)
_set_search_parser(subparsers) _set_repo_rebuild_parser(subparsers)
_set_setup_parser(subparsers) _set_repo_remove_unknown_parser(subparsers)
_set_sign_parser(subparsers) _set_repo_report_parser(subparsers)
_set_status_parser(subparsers) _set_repo_setup_parser(subparsers)
_set_status_update_parser(subparsers) _set_repo_sign_parser(subparsers)
_set_sync_parser(subparsers) _set_repo_sync_parser(subparsers)
_set_update_parser(subparsers) _set_repo_update_parser(subparsers)
_set_user_parser(subparsers) _set_user_add_parser(subparsers)
_set_user_remove_parser(subparsers)
_set_web_parser(subparsers) _set_web_parser(subparsers)
return parser return parser
def _set_add_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_aur_search_parser(root: SubParserAction) -> argparse.ArgumentParser:
""" """
add parser for add subcommand add parser for AUR search subcommand
:param root: subparsers for the commands :param root: subparsers for the commands
:return: created argument parser :return: created argument parser
""" """
parser = root.add_parser("add", help="add package", description="add package", formatter_class=_formatter) parser = root.add_parser("aur-search", aliases=["search"], help="search for package",
parser.add_argument("package", help="package base/name or archive path", nargs="+") description="search for package in AUR using API", formatter_class=_formatter)
parser.add_argument("--now", help="run update function after", action="store_true") parser.add_argument("search", help="search terms, can be specified multiple times", nargs="+")
parser.add_argument("--source", help="package source", choices=PackageSource, type=PackageSource, parser.set_defaults(handler=handlers.Search, architecture=[""], lock=None, no_report=True, quiet=True, unsafe=True)
default=PackageSource.Auto)
parser.add_argument("--without-dependencies", help="do not add dependencies", action="store_true")
parser.set_defaults(handler=handlers.Add)
return parser
def _set_check_parser(root: SubParserAction) -> argparse.ArgumentParser:
"""
add parser for check subcommand
:param root: subparsers for the commands
:return: created argument parser
"""
parser = root.add_parser("check", help="check for updates",
description="check for updates. Same as update --dry-run --no-manual",
formatter_class=_formatter)
parser.add_argument("package", help="filter check by package base", nargs="*")
parser.add_argument("--no-vcs", help="do not check VCS packages", action="store_true")
parser.set_defaults(handler=handlers.Update, no_aur=False, no_manual=True, dry_run=True)
return parser
def _set_clean_parser(root: SubParserAction) -> argparse.ArgumentParser:
"""
add parser for clean subcommand
:param root: subparsers for the commands
:return: created argument parser
"""
parser = root.add_parser("clean", help="clean local caches", description="clear local caches",
formatter_class=_formatter)
parser.add_argument("--no-build", help="do not clear directory with package sources", action="store_true")
parser.add_argument("--no-cache", help="do not clear directory with package caches", action="store_true")
parser.add_argument("--no-chroot", help="do not clear build chroot", action="store_true")
parser.add_argument("--no-manual", help="do not clear directory with manually added packages", action="store_true")
parser.add_argument("--no-packages", help="do not clear directory with built packages", action="store_true")
parser.set_defaults(handler=handlers.Clean, quiet=True, unsafe=True)
return parser
def _set_config_parser(root: SubParserAction) -> argparse.ArgumentParser:
"""
add parser for config subcommand
:param root: subparsers for the commands
:return: created argument parser
"""
parser = root.add_parser("config", help="dump configuration",
description="dump configuration for specified architecture",
formatter_class=_formatter)
parser.set_defaults(handler=handlers.Dump, lock=None, quiet=True, no_report=True, unsafe=True)
return parser
def _set_init_parser(root: SubParserAction) -> argparse.ArgumentParser:
"""
add parser for init subcommand
:param root: subparsers for the commands
:return: created argument parser
"""
parser = root.add_parser("init", help="create repository tree",
description="create empty repository tree. Optional command for auto architecture support",
formatter_class=_formatter)
parser.set_defaults(handler=handlers.Init, no_report=True)
return parser return parser
@ -177,6 +118,10 @@ def _set_key_import_parser(root: SubParserAction) -> argparse.ArgumentParser:
""" """
parser = root.add_parser("key-import", help="import PGP key", parser = root.add_parser("key-import", help="import PGP key",
description="import PGP key from public sources to repository user", description="import PGP key from public sources to repository user",
epilog="By default ahriman runs build process with package sources validation "
"(in case if signature and keys are available in PKGBUILD). This process will "
"fail in case if key is not known for build user. This subcommand can be used "
"in order to import the PGP key to user keychain.",
formatter_class=_formatter) formatter_class=_formatter)
parser.add_argument("--key-server", help="key server for key import", default="pgp.mit.edu") parser.add_argument("--key-server", help="key server for key import", default="pgp.mit.edu")
parser.add_argument("key", help="PGP key to import from public server") parser.add_argument("key", help="PGP key to import from public server")
@ -184,6 +129,91 @@ def _set_key_import_parser(root: SubParserAction) -> argparse.ArgumentParser:
return parser return parser
def _set_package_add_parser(root: SubParserAction) -> argparse.ArgumentParser:
"""
add parser for package addition subcommand
:param root: subparsers for the commands
:return: created argument parser
"""
parser = root.add_parser("package-add", aliases=["add"], help="add package", description="add package",
epilog="This subcommand should be used for new package addition. It also supports flag "
"--now in case if you would like to build the package immediately.",
formatter_class=_formatter)
parser.add_argument("package", help="package base/name or archive path", nargs="+")
parser.add_argument("-n", "--now", help="run update function after", action="store_true")
parser.add_argument("-s", "--source", help="package source",
type=PackageSource, choices=PackageSource, default=PackageSource.Auto)
parser.add_argument("--without-dependencies", help="do not add dependencies", action="store_true")
parser.set_defaults(handler=handlers.Add)
return parser
def _set_package_remove_parser(root: SubParserAction) -> argparse.ArgumentParser:
"""
add parser for package removal subcommand
:param root: subparsers for the commands
:return: created argument parser
"""
parser = root.add_parser("package-remove", aliases=["remove"], help="remove package", description="remove package",
formatter_class=_formatter)
parser.add_argument("package", help="package name or base", nargs="+")
parser.set_defaults(handler=handlers.Remove)
return parser
def _set_package_status_parser(root: SubParserAction) -> argparse.ArgumentParser:
"""
add parser for package status subcommand
:param root: subparsers for the commands
:return: created argument parser
"""
parser = root.add_parser("package-status", aliases=["status"], help="get package status",
description="request status of the package",
epilog="This feature requests package status from the web interface if it is available.",
formatter_class=_formatter)
parser.add_argument("package", help="filter status by package base", nargs="*")
parser.add_argument("--ahriman", help="get service status itself", action="store_true")
parser.add_argument("-s", "--status", help="filter packages by status",
type=BuildStatusEnum, choices=BuildStatusEnum)
parser.set_defaults(handler=handlers.Status, lock=None, no_report=True, quiet=True, unsafe=True)
return parser
def _set_package_status_remove_parser(root: SubParserAction) -> argparse.ArgumentParser:
"""
add parser for package status remove subcommand
:param root: subparsers for the commands
:return: created argument parser
"""
parser = root.add_parser("package-status-remove", help="remove package status",
description="remove the package from the status page",
epilog="Please note that this subcommand does not remove the package itself, it just "
"clears the status page.",
formatter_class=_formatter)
parser.add_argument("package", help="remove specified packages", nargs="+")
parser.set_defaults(handler=handlers.StatusUpdate, action=Action.Remove, lock=None, no_report=True, quiet=True,
unsafe=True)
return parser
def _set_package_status_update_parser(root: SubParserAction) -> argparse.ArgumentParser:
"""
add parser for package status update subcommand
:param root: subparsers for the commands
:return: created argument parser
"""
parser = root.add_parser("package-status-update", aliases=["status-update"], help="update package status",
description="update package status on the status page", formatter_class=_formatter)
parser.add_argument("package", help="set status for specified packages. "
"If no packages supplied, service status will be updated",
nargs="*")
parser.add_argument("-s", "--status", help="new status",
type=BuildStatusEnum, choices=BuildStatusEnum, default=BuildStatusEnum.Success)
parser.set_defaults(handler=handlers.StatusUpdate, action=Action.Update, lock=None, no_report=True, quiet=True,
unsafe=True)
return parser
def _set_patch_add_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_patch_add_parser(root: SubParserAction) -> argparse.ArgumentParser:
""" """
add parser for new patch subcommand add parser for new patch subcommand
@ -230,38 +260,88 @@ def _set_patch_remove_parser(root: SubParserAction) -> argparse.ArgumentParser:
return parser return parser
def _set_rebuild_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_repo_check_parser(root: SubParserAction) -> argparse.ArgumentParser:
""" """
add parser for rebuild subcommand add parser for repository check subcommand
:param root: subparsers for the commands :param root: subparsers for the commands
:return: created argument parser :return: created argument parser
""" """
parser = root.add_parser("rebuild", help="rebuild repository", description="rebuild whole repository", parser = root.add_parser("repo-check", aliases=["check"], help="check for updates",
description="check for updates. Same as update --dry-run --no-manual",
formatter_class=_formatter) formatter_class=_formatter)
parser.add_argument("package", help="filter check by package base", nargs="*")
parser.add_argument("--no-vcs", help="do not check VCS packages", action="store_true")
parser.set_defaults(handler=handlers.Update, dry_run=True, no_aur=False, no_manual=True)
return parser
def _set_repo_clean_parser(root: SubParserAction) -> argparse.ArgumentParser:
"""
add parser for repository clean subcommand
:param root: subparsers for the commands
:return: created argument parser
"""
parser = root.add_parser("repo-clean", aliases=["clean"], help="clean local caches",
description="clear local caches",
epilog="The subcommand clears every temporary directories (builds, caches etc). Normally "
"you should not run this command manually. Also in case if you are going to clear "
"the chroot directories you will need root privileges.",
formatter_class=_formatter)
parser.add_argument("--no-build", help="do not clear directory with package sources", action="store_true")
parser.add_argument("--no-cache", help="do not clear directory with package caches", action="store_true")
parser.add_argument("--no-chroot", help="do not clear build chroot", action="store_true")
parser.add_argument("--no-manual", help="do not clear directory with manually added packages", action="store_true")
parser.add_argument("--no-packages", help="do not clear directory with built packages", action="store_true")
parser.set_defaults(handler=handlers.Clean, quiet=True, unsafe=True)
return parser
def _set_repo_config_parser(root: SubParserAction) -> argparse.ArgumentParser:
"""
add parser for config subcommand
:param root: subparsers for the commands
:return: created argument parser
"""
parser = root.add_parser("repo-config", aliases=["config"], help="dump configuration",
description="dump configuration for specified architecture",
formatter_class=_formatter)
parser.set_defaults(handler=handlers.Dump, lock=None, no_report=True, quiet=True, unsafe=True)
return parser
def _set_repo_init_parser(root: SubParserAction) -> argparse.ArgumentParser:
"""
add parser for repository init subcommand
:param root: subparsers for the commands
:return: created argument parser
"""
parser = root.add_parser("repo-init", aliases=["init"], help="create repository tree",
description="create empty repository tree. Optional command for auto architecture support",
formatter_class=_formatter)
parser.set_defaults(handler=handlers.Init, no_report=True)
return parser
def _set_repo_rebuild_parser(root: SubParserAction) -> argparse.ArgumentParser:
"""
add parser for repository rebuild subcommand
:param root: subparsers for the commands
:return: created argument parser
"""
parser = root.add_parser("repo-rebuild", aliases=["rebuild"], help="rebuild repository",
description="rebuild whole repository", formatter_class=_formatter)
parser.add_argument("--depends-on", help="only rebuild packages that depend on specified package", action="append") parser.add_argument("--depends-on", help="only rebuild packages that depend on specified package", action="append")
parser.set_defaults(handler=handlers.Rebuild) parser.set_defaults(handler=handlers.Rebuild)
return parser return parser
def _set_remove_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_repo_remove_unknown_parser(root: SubParserAction) -> argparse.ArgumentParser:
"""
add parser for remove subcommand
:param root: subparsers for the commands
:return: created argument parser
"""
parser = root.add_parser("remove", help="remove package", description="remove package", formatter_class=_formatter)
parser.add_argument("package", help="package name or base", nargs="+")
parser.set_defaults(handler=handlers.Remove)
return parser
def _set_remove_unknown_parser(root: SubParserAction) -> argparse.ArgumentParser:
""" """
add parser for remove unknown packages subcommand add parser for remove unknown packages subcommand
:param root: subparsers for the commands :param root: subparsers for the commands
:return: created argument parser :return: created argument parser
""" """
parser = root.add_parser("remove-unknown", help="remove unknown packages", parser = root.add_parser("repo-remove-unknown", aliases=["remove-unknown"], help="remove unknown packages",
description="remove packages which are missing in AUR", description="remove packages which are missing in AUR",
formatter_class=_formatter) formatter_class=_formatter)
parser.add_argument("--dry-run", help="just perform check for packages without removal", action="store_true") parser.add_argument("--dry-run", help="just perform check for packages without removal", action="store_true")
@ -269,39 +349,29 @@ def _set_remove_unknown_parser(root: SubParserAction) -> argparse.ArgumentParser
return parser return parser
def _set_report_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_repo_report_parser(root: SubParserAction) -> argparse.ArgumentParser:
""" """
add parser for report subcommand add parser for report subcommand
:param root: subparsers for the commands :param root: subparsers for the commands
:return: created argument parser :return: created argument parser
""" """
parser = root.add_parser("report", help="generate report", description="generate report", parser = root.add_parser("repo-report", aliases=["report"], help="generate report", description="generate report",
epilog="Create and/or update repository report as configured.",
formatter_class=_formatter) formatter_class=_formatter)
parser.add_argument("target", help="target to generate report", nargs="*") parser.add_argument("target", help="target to generate report", nargs="*")
parser.set_defaults(handler=handlers.Report) parser.set_defaults(handler=handlers.Report)
return parser return parser
def _set_search_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_repo_setup_parser(root: SubParserAction) -> argparse.ArgumentParser:
"""
add parser for search subcommand
:param root: subparsers for the commands
:return: created argument parser
"""
parser = root.add_parser("search", help="search for package", description="search for package in AUR using API")
parser.add_argument("search", help="search terms, can be specified multiple times", nargs="+")
parser.set_defaults(handler=handlers.Search, architecture=[""], lock=None, quiet=True, no_report=True, unsafe=True)
return parser
def _set_setup_parser(root: SubParserAction) -> argparse.ArgumentParser:
""" """
add parser for setup subcommand add parser for setup subcommand
:param root: subparsers for the commands :param root: subparsers for the commands
:return: created argument parser :return: created argument parser
""" """
parser = root.add_parser("setup", help="initial service configuration", parser = root.add_parser("repo-setup", aliases=["setup"], help="initial service configuration",
description="create initial service configuration, requires root", description="create initial service configuration, requires root",
epilog="Create _minimal_ configuration for the service according to provided options.",
formatter_class=_formatter) formatter_class=_formatter)
parser.add_argument("--build-command", help="build command prefix", default="ahriman") parser.add_argument("--build-command", help="build command prefix", default="ahriman")
parser.add_argument("--from-configuration", help="path to default devtools pacman configuration", parser.add_argument("--from-configuration", help="path to default devtools pacman configuration",
@ -310,80 +380,51 @@ def _set_setup_parser(root: SubParserAction) -> argparse.ArgumentParser:
parser.add_argument("--packager", help="packager name and email", required=True) parser.add_argument("--packager", help="packager name and email", required=True)
parser.add_argument("--repository", help="repository name", required=True) parser.add_argument("--repository", help="repository name", required=True)
parser.add_argument("--sign-key", help="sign key id") parser.add_argument("--sign-key", help="sign key id")
parser.add_argument("--sign-target", help="sign options", type=SignSettings.from_option, parser.add_argument("--sign-target", help="sign options", action="append",
choices=SignSettings, action="append") type=SignSettings.from_option, choices=SignSettings)
parser.add_argument("--web-port", help="port of the web service", type=int) parser.add_argument("--web-port", help="port of the web service", type=int)
parser.set_defaults(handler=handlers.Setup, lock=None, quiet=True, no_report=True, unsafe=True) parser.set_defaults(handler=handlers.Setup, lock=None, no_report=True, quiet=True, unsafe=True)
return parser return parser
def _set_sign_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_repo_sign_parser(root: SubParserAction) -> argparse.ArgumentParser:
""" """
add parser for sign subcommand add parser for sign subcommand
:param root: subparsers for the commands :param root: subparsers for the commands
:return: created argument parser :return: created argument parser
""" """
parser = root.add_parser("sign", help="sign packages", description="(re-)sign packages and repository database", parser = root.add_parser("repo-sign", aliases=["sign"], help="sign packages",
description="(re-)sign packages and repository database",
epilog="Sign repository and/or packages as configured.",
formatter_class=_formatter) formatter_class=_formatter)
parser.add_argument("package", help="sign only specified packages", nargs="*") parser.add_argument("package", help="sign only specified packages", nargs="*")
parser.set_defaults(handler=handlers.Sign) parser.set_defaults(handler=handlers.Sign)
return parser return parser
def _set_status_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_repo_sync_parser(root: SubParserAction) -> argparse.ArgumentParser:
""" """
add parser for status subcommand add parser for repository sync subcommand
:param root: subparsers for the commands :param root: subparsers for the commands
:return: created argument parser :return: created argument parser
""" """
parser = root.add_parser("status", help="get package status", description="request status of the package", parser = root.add_parser("repo-sync", aliases=["sync"], help="sync repository",
formatter_class=_formatter) description="sync packages to remote server",
parser.add_argument("--ahriman", help="get service status itself", action="store_true") epilog="Synchronize the repository to remote services as configured.",
parser.add_argument("--status", help="filter packages by status", choices=BuildStatusEnum, type=BuildStatusEnum)
parser.add_argument("package", help="filter status by package base", nargs="*")
parser.set_defaults(handler=handlers.Status, lock=None, quiet=True, no_report=True, unsafe=True)
return parser
def _set_status_update_parser(root: SubParserAction) -> argparse.ArgumentParser:
"""
add parser for status update subcommand
:param root: subparsers for the commands
:return: created argument parser
"""
parser = root.add_parser("status-update", help="update package status", description="request status of the package",
formatter_class=_formatter)
parser.add_argument(
"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=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, quiet=True, no_report=True, unsafe=True)
return parser
def _set_sync_parser(root: SubParserAction) -> argparse.ArgumentParser:
"""
add parser for sync subcommand
:param root: subparsers for the commands
:return: created argument parser
"""
parser = root.add_parser("sync", help="sync repository", description="sync packages to remote server",
formatter_class=_formatter) formatter_class=_formatter)
parser.add_argument("target", help="target to sync", nargs="*") parser.add_argument("target", help="target to sync", nargs="*")
parser.set_defaults(handler=handlers.Sync) parser.set_defaults(handler=handlers.Sync)
return parser return parser
def _set_update_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_repo_update_parser(root: SubParserAction) -> argparse.ArgumentParser:
""" """
add parser for update subcommand add parser for repository update subcommand
:param root: subparsers for the commands :param root: subparsers for the commands
:return: created argument parser :return: created argument parser
""" """
parser = root.add_parser("update", help="update packages", description="run updates", formatter_class=_formatter) parser = root.add_parser("repo-update", aliases=["update"], help="update packages", description="run updates",
formatter_class=_formatter)
parser.add_argument("package", help="filter check by package base", nargs="*") parser.add_argument("package", help="filter check by package base", nargs="*")
parser.add_argument("--dry-run", help="just perform check for updates, same as check command", action="store_true") parser.add_argument("--dry-run", help="just perform check for updates, same as check command", action="store_true")
parser.add_argument("--no-aur", help="do not check for AUR updates. Implies --no-vcs", action="store_true") parser.add_argument("--no-aur", help="do not check for AUR updates. Implies --no-vcs", action="store_true")
@ -393,31 +434,43 @@ def _set_update_parser(root: SubParserAction) -> argparse.ArgumentParser:
return parser return parser
def _set_user_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_user_add_parser(root: SubParserAction) -> argparse.ArgumentParser:
""" """
add parser for create user subcommand add parser for create user subcommand
:param root: subparsers for the commands :param root: subparsers for the commands
:return: created argument parser :return: created argument parser
""" """
parser = root.add_parser( parser = root.add_parser("user-add", help="create or update user for web services",
"user", description="update user for web services with the given password and role. "
help="manage users for web services", "In case if password was not entered it will be asked interactively",
description="manage users for web services with password and role. In case if password was not entered it will be asked interactively",
formatter_class=_formatter) formatter_class=_formatter)
parser.add_argument("username", help="username for web service") parser.add_argument("username", help="username for web service")
parser.add_argument("--as-service", help="add user as service user", action="store_true") parser.add_argument("--as-service", help="add user as service user", action="store_true")
parser.add_argument(
"-a",
"--access",
help="user access level",
type=UserAccess,
choices=UserAccess,
default=UserAccess.Read)
parser.add_argument("--no-reload", help="do not reload authentication module", action="store_true") parser.add_argument("--no-reload", help="do not reload authentication module", action="store_true")
parser.add_argument("-p", "--password", help="user password") parser.add_argument("-p", "--password", help="user password. Blank password will be treated as empty password, "
parser.add_argument("-r", "--remove", help="remove user from configuration", action="store_true") "which is in particular must be used for OAuth2 authorization type.")
parser.add_argument("--secure", help="set file permissions to user-only", action="store_true") parser.add_argument("-r", "--role", help="user access level",
parser.set_defaults(handler=handlers.User, architecture=[""], lock=None, quiet=True, no_report=True, unsafe=True) type=UserAccess, choices=UserAccess, default=UserAccess.Read)
parser.add_argument("-s", "--secure", help="set file permissions to user-only", action="store_true")
parser.set_defaults(handler=handlers.User, action=Action.Update, architecture=[""], lock=None, no_report=True,
quiet=True, unsafe=True)
return parser
def _set_user_remove_parser(root: SubParserAction) -> argparse.ArgumentParser:
"""
add parser for user removal subcommand
:param root: subparsers for the commands
:return: created argument parser
"""
parser = root.add_parser("user-remove", help="remove user for web services",
description="remove user from the user mapping and write the configuration",
formatter_class=_formatter)
parser.add_argument("username", help="username for web service")
parser.add_argument("--no-reload", help="do not reload authentication module", action="store_true")
parser.add_argument("-s", "--secure", help="set file permissions to user-only", action="store_true")
parser.set_defaults(handler=handlers.User, action=Action.Remove, architecture=[""], lock=None, no_report=True, # nosec
password="", quiet=True, role=UserAccess.Read, unsafe=True)
return parser return parser
@ -427,7 +480,7 @@ def _set_web_parser(root: SubParserAction) -> argparse.ArgumentParser:
:param root: subparsers for the commands :param root: subparsers for the commands
:return: created argument parser :return: created argument parser
""" """
parser = root.add_parser("web", help="start web server", description="start web server", formatter_class=_formatter) parser = root.add_parser("web", help="web server", description="start web server", formatter_class=_formatter)
parser.set_defaults(handler=handlers.Web, lock=None, no_report=True, parser=_parser) parser.set_defaults(handler=handlers.Web, lock=None, no_report=True, parser=_parser)
return parser return parser

View File

@ -55,7 +55,8 @@ class Handler:
cls.run(args, architecture, configuration, args.no_report) cls.run(args, architecture, configuration, args.no_report)
return True return True
except Exception: except Exception:
logging.getLogger("root").exception("process exception") # we are basically always want to print error to stderr instead of default logger
logging.getLogger("stderr").exception("process exception")
return False return False
@classmethod @classmethod

View File

@ -19,12 +19,12 @@
# #
import argparse import argparse
from typing import Callable, Type from typing import Type
from ahriman.application.application import Application from ahriman.application.application import Application
from ahriman.application.handlers.handler import Handler from ahriman.application.handlers.handler import Handler
from ahriman.core.configuration import Configuration from ahriman.core.configuration import Configuration
from ahriman.core.exceptions import InvalidCommand from ahriman.models.action import Action
class StatusUpdate(Handler): class StatusUpdate(Handler):
@ -46,13 +46,14 @@ class StatusUpdate(Handler):
""" """
# we are using reporter here # we are using reporter here
client = Application(architecture, configuration, no_report=False).repository.reporter client = Application(architecture, configuration, no_report=False).repository.reporter
callback: Callable[[str], None] = lambda p: client.remove(p) if args.remove else client.update(p, args.status)
if args.package: if args.action == Action.Update and args.package:
# update packages statuses # update packages statuses
for package in args.package: for package in args.package:
callback(package) client.update(package, args.status)
elif args.remove: elif args.action == Action.Update:
raise InvalidCommand("Remove option is supplied, but no packages set")
else:
# update service status # update service status
client.update_self(args.status) client.update_self(args.status)
elif args.action == Action.Remove:
for package in args.package:
client.remove(package)

View File

@ -26,6 +26,7 @@ from typing import Type
from ahriman.application.application import Application from ahriman.application.application import Application
from ahriman.application.handlers.handler import Handler from ahriman.application.handlers.handler import Handler
from ahriman.core.configuration import Configuration from ahriman.core.configuration import Configuration
from ahriman.models.action import Action
from ahriman.models.user import User as MUser from ahriman.models.user import User as MUser
from ahriman.models.user_access import UserAccess from ahriman.models.user_access import UserAccess
@ -52,7 +53,7 @@ class User(Handler):
auth_configuration = User.get_auth_configuration(configuration.include) auth_configuration = User.get_auth_configuration(configuration.include)
User.clear_user(auth_configuration, user) User.clear_user(auth_configuration, user)
if not args.remove: if args.action == Action.Update:
User.create_configuration(auth_configuration, user, salt, args.as_service) User.create_configuration(auth_configuration, user, salt, args.as_service)
User.write_configuration(auth_configuration, args.secure) User.write_configuration(auth_configuration, args.secure)
@ -97,7 +98,7 @@ class User(Handler):
:param args: command line args :param args: command line args
:return: built user descriptor :return: built user descriptor
""" """
user = MUser(args.username, args.password, args.access) user = MUser(args.username, args.password, args.role)
if user.password is None: if user.password is None:
user.password = getpass.getpass() user.password = getpass.getpass()
return user return user

View File

@ -150,10 +150,10 @@ class Configuration(configparser.RawConfigParser):
try: try:
path = self.logging_path path = self.logging_path
fileConfig(path) fileConfig(path)
except (FileNotFoundError, PermissionError): except Exception:
logging.basicConfig(filename=None, format=self.DEFAULT_LOG_FORMAT, logging.basicConfig(filename=None, format=self.DEFAULT_LOG_FORMAT,
level=self.DEFAULT_LOG_LEVEL) level=self.DEFAULT_LOG_LEVEL)
logging.exception("could not create logfile, fallback to stderr") logging.exception("could not load logging from configuration, fallback to stderr")
if quiet: if quiet:
logging.disable() logging.disable()

View File

@ -71,19 +71,6 @@ class InitializeException(RuntimeError):
RuntimeError.__init__(self, f"Could not load service: {details}") RuntimeError.__init__(self, f"Could not load service: {details}")
class InvalidCommand(ValueError):
"""
exception raised on invalid command line options
"""
def __init__(self, details: Any) -> None:
"""
default constructor
:param details" error details
"""
ValueError.__init__(self, details)
class InvalidOption(ValueError): class InvalidOption(ValueError):
""" """
exception which will be raised on configuration errors exception which will be raised on configuration errors

View File

@ -19,7 +19,7 @@
# #
from __future__ import annotations from __future__ import annotations
from enum import Enum, auto from enum import Enum
from typing import Type from typing import Type
from ahriman.core.exceptions import InvalidOption from ahriman.core.exceptions import InvalidOption
@ -33,9 +33,9 @@ class AuthSettings(Enum):
:cvar OAuth: OAuth based provider :cvar OAuth: OAuth based provider
""" """
Disabled = auto() Disabled = "disabled"
Configuration = auto() Configuration = "configuration"
OAuth = auto() OAuth = "oauth2"
@classmethod @classmethod
def from_option(cls: Type[AuthSettings], value: str) -> AuthSettings: def from_option(cls: Type[AuthSettings], value: str) -> AuthSettings:

View File

@ -19,7 +19,7 @@
# #
from __future__ import annotations from __future__ import annotations
from enum import Enum, auto from enum import Enum
from typing import Type from typing import Type
from ahriman.core.exceptions import InvalidOption from ahriman.core.exceptions import InvalidOption
@ -33,9 +33,9 @@ class ReportSettings(Enum):
:cvar Email: email report generation :cvar Email: email report generation
""" """
Disabled = auto() # for testing purpose Disabled = "disabled" # for testing purpose
HTML = auto() HTML = "html"
Email = auto() Email = "email"
@classmethod @classmethod
def from_option(cls: Type[ReportSettings], value: str) -> ReportSettings: def from_option(cls: Type[ReportSettings], value: str) -> ReportSettings:

View File

@ -19,7 +19,7 @@
# #
from __future__ import annotations from __future__ import annotations
from enum import Enum, auto from enum import Enum
from typing import Type from typing import Type
from ahriman.core.exceptions import InvalidOption from ahriman.core.exceptions import InvalidOption
@ -32,8 +32,8 @@ class SignSettings(Enum):
:cvar Repository: sign repository database file :cvar Repository: sign repository database file
""" """
Packages = auto() Packages = "pacakges"
Repository = auto() Repository = "repository"
@classmethod @classmethod
def from_option(cls: Type[SignSettings], value: str) -> SignSettings: def from_option(cls: Type[SignSettings], value: str) -> SignSettings:

View File

@ -19,7 +19,7 @@
# #
from __future__ import annotations from __future__ import annotations
from enum import Enum, auto from enum import Enum
from typing import Type from typing import Type
@ -31,9 +31,9 @@ class SmtpSSLSettings(Enum):
:cvar STARTTLS: use STARTTLS in normal SMTP client :cvar STARTTLS: use STARTTLS in normal SMTP client
""" """
Disabled = auto() Disabled = "disabled"
SSL = auto() SSL = "ssl"
STARTTLS = auto() STARTTLS = "starttls"
@classmethod @classmethod
def from_option(cls: Type[SmtpSSLSettings], value: str) -> SmtpSSLSettings: def from_option(cls: Type[SmtpSSLSettings], value: str) -> SmtpSSLSettings:

View File

@ -19,7 +19,7 @@
# #
from __future__ import annotations from __future__ import annotations
from enum import Enum, auto from enum import Enum
from typing import Type from typing import Type
from ahriman.core.exceptions import InvalidOption from ahriman.core.exceptions import InvalidOption
@ -33,9 +33,9 @@ class UploadSettings(Enum):
:cvar S3: sync to Amazon S3 :cvar S3: sync to Amazon S3
""" """
Disabled = auto() # for testing purpose Disabled = "disabled" # for testing purpose
Rsync = auto() Rsync = "rsync"
S3 = auto() S3 = "s3"
@classmethod @classmethod
def from_option(cls: Type[UploadSettings], value: str) -> UploadSettings: def from_option(cls: Type[UploadSettings], value: str) -> UploadSettings:

View File

@ -1,11 +1,10 @@
import argparse import argparse
import pytest
from pytest_mock import MockerFixture from pytest_mock import MockerFixture
from ahriman.application.handlers import StatusUpdate from ahriman.application.handlers import StatusUpdate
from ahriman.core.configuration import Configuration from ahriman.core.configuration import Configuration
from ahriman.core.exceptions import InvalidCommand from ahriman.models.action import Action
from ahriman.models.build_status import BuildStatusEnum from ahriman.models.build_status import BuildStatusEnum
from ahriman.models.package import Package from ahriman.models.package import Package
@ -16,9 +15,9 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace:
:param args: command line arguments fixture :param args: command line arguments fixture
:return: generated arguments for these test cases :return: generated arguments for these test cases
""" """
args.status = BuildStatusEnum.Success
args.package = None args.package = None
args.remove = False args.action = Action.Update
args.status = BuildStatusEnum.Success
return args return args
@ -55,7 +54,7 @@ def test_run_remove(args: argparse.Namespace, configuration: Configuration, pack
""" """
args = _default_args(args) args = _default_args(args)
args.package = [package_ahriman.base] args.package = [package_ahriman.base]
args.remove = True args.action = Action.Remove
mocker.patch("pathlib.Path.mkdir") mocker.patch("pathlib.Path.mkdir")
update_mock = mocker.patch("ahriman.core.status.client.Client.remove") update_mock = mocker.patch("ahriman.core.status.client.Client.remove")
@ -63,19 +62,6 @@ def test_run_remove(args: argparse.Namespace, configuration: Configuration, pack
update_mock.assert_called_once() update_mock.assert_called_once()
def test_run_remove_without_packages(args: argparse.Namespace, configuration: Configuration,
mocker: MockerFixture) -> None:
"""
must raise exception when no packages set and remove called
"""
args = _default_args(args)
args.remove = True
mocker.patch("pathlib.Path.mkdir")
with pytest.raises(InvalidCommand):
StatusUpdate.run(args, "x86_64", configuration, True)
def test_imply_with_report(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: def test_imply_with_report(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None:
""" """
must create application object with native reporting must create application object with native reporting

View File

@ -7,6 +7,7 @@ from unittest import mock
from ahriman.application.handlers import User from ahriman.application.handlers import User
from ahriman.core.configuration import Configuration from ahriman.core.configuration import Configuration
from ahriman.models.action import Action
from ahriman.models.user import User as MUser from ahriman.models.user import User as MUser
from ahriman.models.user_access import UserAccess from ahriman.models.user_access import UserAccess
@ -18,12 +19,12 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace:
:return: generated arguments for these test cases :return: generated arguments for these test cases
""" """
args.username = "user" args.username = "user"
args.password = "pa55w0rd" args.action = Action.Update
args.access = UserAccess.Read
args.as_service = False args.as_service = False
args.no_reload = False args.no_reload = False
args.password = "pa55w0rd"
args.role = UserAccess.Read
args.secure = False args.secure = False
args.remove = False
return args return args
@ -54,7 +55,7 @@ def test_run_remove(args: argparse.Namespace, configuration: Configuration, mock
must remove user if remove flag supplied must remove user if remove flag supplied
""" """
args = _default_args(args) args = _default_args(args)
args.remove = True args.action = Action.Remove
mocker.patch("pathlib.Path.mkdir") mocker.patch("pathlib.Path.mkdir")
get_auth_configuration_mock = mocker.patch("ahriman.application.handlers.User.get_auth_configuration") get_auth_configuration_mock = mocker.patch("ahriman.application.handlers.User.get_auth_configuration")
create_configuration_mock = mocker.patch("ahriman.application.handlers.User.create_configuration") create_configuration_mock = mocker.patch("ahriman.application.handlers.User.create_configuration")

View File

@ -14,16 +14,16 @@ def test_parser(parser: argparse.ArgumentParser) -> None:
""" """
must parse valid command line must parse valid command line
""" """
parser.parse_args(["-a", "x86_64", "config"]) parser.parse_args(["-a", "x86_64", "repo-config"])
def test_parser_option_configuration(parser: argparse.ArgumentParser) -> None: def test_parser_option_configuration(parser: argparse.ArgumentParser) -> None:
""" """
must convert configuration option to Path instance must convert configuration option to Path instance
""" """
args = parser.parse_args(["-a", "x86_64", "config"]) args = parser.parse_args(["-a", "x86_64", "repo-config"])
assert isinstance(args.configuration, Path) assert isinstance(args.configuration, Path)
args = parser.parse_args(["-a", "x86_64", "-c", "ahriman.ini", "config"]) args = parser.parse_args(["-a", "x86_64", "-c", "ahriman.ini", "repo-config"])
assert isinstance(args.configuration, Path) assert isinstance(args.configuration, Path)
@ -31,9 +31,9 @@ def test_parser_option_lock(parser: argparse.ArgumentParser) -> None:
""" """
must convert lock option to Path instance must convert lock option to Path instance
""" """
args = parser.parse_args(["update"]) args = parser.parse_args(["repo-update"])
assert isinstance(args.lock, Path) assert isinstance(args.lock, Path)
args = parser.parse_args(["-l", "ahriman.lock", "update"]) args = parser.parse_args(["-l", "ahriman.lock", "repo-update"])
assert isinstance(args.lock, Path) assert isinstance(args.lock, Path)
@ -41,78 +41,28 @@ def test_multiple_architectures(parser: argparse.ArgumentParser) -> None:
""" """
must accept multiple architectures must accept multiple architectures
""" """
args = parser.parse_args(["-a", "x86_64", "-a", "i686", "config"]) args = parser.parse_args(["-a", "x86_64", "-a", "i686", "repo-config"])
assert args.architecture == ["x86_64", "i686"] assert args.architecture == ["x86_64", "i686"]
def test_subparsers_add_architecture(parser: argparse.ArgumentParser) -> None: def test_subparsers_aur_search(parser: argparse.ArgumentParser) -> None:
""" """
add command must correctly parse architecture list aur-search command must imply architecture list, lock, no-report, quiet and unsafe
""" """
args = parser.parse_args(["add", "ahriman"]) args = parser.parse_args(["aur-search", "ahriman"])
assert args.architecture is None assert args.architecture == [""]
args = parser.parse_args(["-a", "x86_64", "add", "ahriman"])
assert args.architecture == ["x86_64"]
def test_subparsers_check(parser: argparse.ArgumentParser) -> None:
"""
check command must imply no-aur, no-manual and dry-run
"""
args = parser.parse_args(["check"])
assert not args.no_aur
assert args.no_manual
assert args.dry_run
def test_subparsers_check_architecture(parser: argparse.ArgumentParser) -> None:
"""
check command must correctly parse architecture list
"""
args = parser.parse_args(["check"])
assert args.architecture is None
args = parser.parse_args(["-a", "x86_64", "check"])
assert args.architecture == ["x86_64"]
def test_subparsers_clean(parser: argparse.ArgumentParser) -> None:
"""
clean command must imply unsafe and no-log
"""
args = parser.parse_args(["clean"])
assert args.quiet
assert args.unsafe
def test_subparsers_clean_architecture(parser: argparse.ArgumentParser) -> None:
"""
clean command must correctly parse architecture list
"""
args = parser.parse_args(["clean"])
assert args.architecture is None
args = parser.parse_args(["-a", "x86_64", "clean"])
assert args.architecture == ["x86_64"]
def test_subparsers_config(parser: argparse.ArgumentParser) -> None:
"""
config command must imply lock, no-log, no-report and unsafe
"""
args = parser.parse_args(["-a", "x86_64", "config"])
assert args.architecture == ["x86_64"]
assert args.lock is None assert args.lock is None
assert args.quiet
assert args.no_report assert args.no_report
assert args.quiet
assert args.unsafe assert args.unsafe
def test_subparsers_init(parser: argparse.ArgumentParser) -> None: def test_subparsers_aur_search_architecture(parser: argparse.ArgumentParser) -> None:
""" """
init command must imply no_report aur-search command must correctly parse architecture list
""" """
args = parser.parse_args(["-a", "x86_64", "init"]) args = parser.parse_args(["-a", "x86_64", "aur-search", "ahriman"])
assert args.architecture == ["x86_64"] assert args.architecture == [""]
assert args.no_report
def test_subparsers_key_import(parser: argparse.ArgumentParser) -> None: def test_subparsers_key_import(parser: argparse.ArgumentParser) -> None:
@ -133,6 +83,74 @@ def test_subparsers_key_import_architecture(parser: argparse.ArgumentParser) ->
assert args.architecture == [""] assert args.architecture == [""]
def test_subparsers_package_add_architecture(parser: argparse.ArgumentParser) -> None:
"""
package-add command must correctly parse architecture list
"""
args = parser.parse_args(["package-add", "ahriman"])
assert args.architecture is None
args = parser.parse_args(["-a", "x86_64", "package-add", "ahriman"])
assert args.architecture == ["x86_64"]
def test_subparsers_package_remove_architecture(parser: argparse.ArgumentParser) -> None:
"""
package-remove command must correctly parse architecture list
"""
args = parser.parse_args(["package-remove", "ahriman"])
assert args.architecture is None
args = parser.parse_args(["-a", "x86_64", "package-remove", "ahriman"])
assert args.architecture == ["x86_64"]
def test_subparsers_package_status(parser: argparse.ArgumentParser) -> None:
"""
package-status command must imply lock, no-report, quiet and unsafe
"""
args = parser.parse_args(["-a", "x86_64", "package-status"])
assert args.architecture == ["x86_64"]
assert args.lock is None
assert args.no_report
assert args.quiet
assert args.unsafe
def test_subparsers_package_status_remove(parser: argparse.ArgumentParser) -> None:
"""
package-status-remove command must imply action, lock, no-report, quiet and unsafe
"""
args = parser.parse_args(["-a", "x86_64", "package-status-remove", "ahriman"])
assert args.architecture == ["x86_64"]
assert args.action == Action.Remove
assert args.lock is None
assert args.no_report
assert args.quiet
assert args.unsafe
def test_subparsers_package_status_update(parser: argparse.ArgumentParser) -> None:
"""
package-status-update command must imply action, lock, no-report, quiet and unsafe
"""
args = parser.parse_args(["-a", "x86_64", "package-status-update"])
assert args.architecture == ["x86_64"]
assert args.action == Action.Update
assert args.lock is None
assert args.no_report
assert args.quiet
assert args.unsafe
def test_subparsers_package_status_update_option_status(parser: argparse.ArgumentParser) -> None:
"""
package-status-update command must convert status option to buildstatusenum instance
"""
args = parser.parse_args(["-a", "x86_64", "package-status-update"])
assert isinstance(args.status, BuildStatusEnum)
args = parser.parse_args(["-a", "x86_64", "package-status-update", "--status", "failed"])
assert isinstance(args.status, BuildStatusEnum)
def test_subparsers_patch_add(parser: argparse.ArgumentParser) -> None: def test_subparsers_patch_add(parser: argparse.ArgumentParser) -> None:
""" """
patch-add command must imply action, architecture list, lock and no-report patch-add command must imply action, architecture list, lock and no-report
@ -198,183 +216,213 @@ def test_subparsers_patch_remove_architecture(parser: argparse.ArgumentParser) -
assert args.architecture == [""] assert args.architecture == [""]
def test_subparsers_rebuild_architecture(parser: argparse.ArgumentParser) -> None: def test_subparsers_repo_check(parser: argparse.ArgumentParser) -> None:
""" """
rebuild command must correctly parse architecture list repo-check command must imply dry-run, no-aur and no-manual
""" """
args = parser.parse_args(["rebuild"]) args = parser.parse_args(["repo-check"])
assert args.dry_run
assert not args.no_aur
assert args.no_manual
def test_subparsers_repo_check_architecture(parser: argparse.ArgumentParser) -> None:
"""
repo-check command must correctly parse architecture list
"""
args = parser.parse_args(["repo-check"])
assert args.architecture is None assert args.architecture is None
args = parser.parse_args(["-a", "x86_64", "rebuild"]) args = parser.parse_args(["-a", "x86_64", "repo-check"])
assert args.architecture == ["x86_64"] assert args.architecture == ["x86_64"]
def test_subparsers_remove_architecture(parser: argparse.ArgumentParser) -> None: def test_subparsers_repo_clean(parser: argparse.ArgumentParser) -> None:
""" """
remove command must correctly parse architecture list repo-clean command must imply quiet and unsafe
""" """
args = parser.parse_args(["remove", "ahriman"]) args = parser.parse_args(["repo-clean"])
assert args.architecture is None
args = parser.parse_args(["-a", "x86_64", "remove", "ahriman"])
assert args.architecture == ["x86_64"]
def test_subparsers_report_architecture(parser: argparse.ArgumentParser) -> None:
"""
report command must correctly parse architecture list
"""
args = parser.parse_args(["report"])
assert args.architecture is None
args = parser.parse_args(["-a", "x86_64", "report"])
assert args.architecture == ["x86_64"]
def test_subparsers_search(parser: argparse.ArgumentParser) -> None:
"""
search command must imply architecture list, lock, no-log, no-report and unsafe
"""
args = parser.parse_args(["search", "ahriman"])
assert args.architecture == [""]
assert args.lock is None
assert args.quiet assert args.quiet
assert args.no_report
assert args.unsafe assert args.unsafe
def test_subparsers_search_architecture(parser: argparse.ArgumentParser) -> None: def test_subparsers_repo_clean_architecture(parser: argparse.ArgumentParser) -> None:
""" """
search command must correctly parse architecture list repo-clean command must correctly parse architecture list
""" """
args = parser.parse_args(["-a", "x86_64", "search", "ahriman"]) args = parser.parse_args(["repo-clean"])
assert args.architecture == [""] assert args.architecture is None
args = parser.parse_args(["-a", "x86_64", "repo-clean"])
assert args.architecture == ["x86_64"]
def test_subparsers_setup(parser: argparse.ArgumentParser) -> None: def test_subparsers_repo_config(parser: argparse.ArgumentParser) -> None:
""" """
setup command must imply lock, no-log, no-report and unsafe repo-config command must imply lock, no-report, quiet and unsafe
""" """
args = parser.parse_args(["-a", "x86_64", "setup", "--packager", "John Doe <john@doe.com>", args = parser.parse_args(["-a", "x86_64", "repo-config"])
assert args.architecture == ["x86_64"]
assert args.lock is None
assert args.no_report
assert args.quiet
assert args.unsafe
def test_subparsers_repo_init(parser: argparse.ArgumentParser) -> None:
"""
repo-init command must imply no_report
"""
args = parser.parse_args(["-a", "x86_64", "repo-init"])
assert args.architecture == ["x86_64"]
assert args.no_report
def test_subparsers_repo_rebuild_architecture(parser: argparse.ArgumentParser) -> None:
"""
repo-rebuild command must correctly parse architecture list
"""
args = parser.parse_args(["repo-rebuild"])
assert args.architecture is None
args = parser.parse_args(["-a", "x86_64", "repo-rebuild"])
assert args.architecture == ["x86_64"]
def test_subparsers_repo_remove_unknown_architecture(parser: argparse.ArgumentParser) -> None:
"""
repo-remove-unknown command must correctly parse architecture list
"""
args = parser.parse_args(["repo-remove-unknown"])
assert args.architecture is None
args = parser.parse_args(["-a", "x86_64", "repo-remove-unknown"])
assert args.architecture == ["x86_64"]
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_setup(parser: argparse.ArgumentParser) -> None:
"""
repo-setup command must imply lock, no-report, quiet and unsafe
"""
args = parser.parse_args(["-a", "x86_64", "repo-setup", "--packager", "John Doe <john@doe.com>",
"--repository", "aur-clone"]) "--repository", "aur-clone"])
assert args.architecture == ["x86_64"] assert args.architecture == ["x86_64"]
assert args.lock is None assert args.lock is None
assert args.quiet
assert args.no_report assert args.no_report
assert args.quiet
assert args.unsafe assert args.unsafe
def test_subparsers_setup_option_from_configuration(parser: argparse.ArgumentParser) -> None: def test_subparsers_repo_setup_option_from_configuration(parser: argparse.ArgumentParser) -> None:
""" """
setup command must convert from-configuration option to path instance repo-setup command must convert from-configuration option to path instance
""" """
args = parser.parse_args(["-a", "x86_64", "setup", "--packager", "John Doe <john@doe.com>", args = parser.parse_args(["-a", "x86_64", "repo-setup", "--packager", "John Doe <john@doe.com>",
"--repository", "aur-clone"]) "--repository", "aur-clone"])
assert isinstance(args.from_configuration, Path) assert isinstance(args.from_configuration, Path)
args = parser.parse_args(["-a", "x86_64", "setup", "--packager", "John Doe <john@doe.com>", args = parser.parse_args(["-a", "x86_64", "repo-setup", "--packager", "John Doe <john@doe.com>",
"--repository", "aur-clone", "--from-configuration", "path"]) "--repository", "aur-clone", "--from-configuration", "path"])
assert isinstance(args.from_configuration, Path) assert isinstance(args.from_configuration, Path)
def test_subparsers_setup_option_sign_target(parser: argparse.ArgumentParser) -> None: def test_subparsers_repo_setup_option_sign_target(parser: argparse.ArgumentParser) -> None:
""" """
setup command must convert sign-target option to signsettings instance repo-setup command must convert sign-target option to signsettings instance
""" """
args = parser.parse_args(["-a", "x86_64", "setup", "--packager", "John Doe <john@doe.com>", args = parser.parse_args(["-a", "x86_64", "repo-setup", "--packager", "John Doe <john@doe.com>",
"--repository", "aur-clone", "--sign-target", "packages"]) "--repository", "aur-clone", "--sign-target", "packages"])
assert args.sign_target assert args.sign_target
assert all(isinstance(target, SignSettings) for target in args.sign_target) assert all(isinstance(target, SignSettings) for target in args.sign_target)
def test_subparsers_sign_architecture(parser: argparse.ArgumentParser) -> None: def test_subparsers_repo_sign_architecture(parser: argparse.ArgumentParser) -> None:
""" """
sign command must correctly parse architecture list repo-sign command must correctly parse architecture list
""" """
args = parser.parse_args(["sign"]) args = parser.parse_args(["repo-sign"])
assert args.architecture is None assert args.architecture is None
args = parser.parse_args(["-a", "x86_64", "sign"]) args = parser.parse_args(["-a", "x86_64", "repo-sign"])
assert args.architecture == ["x86_64"] assert args.architecture == ["x86_64"]
def test_subparsers_status(parser: argparse.ArgumentParser) -> None: def test_subparsers_repo_sync_architecture(parser: argparse.ArgumentParser) -> None:
""" """
status command must imply lock, no-log, no-report and unsafe repo-sync command must correctly parse architecture list
""" """
args = parser.parse_args(["-a", "x86_64", "status"]) args = parser.parse_args(["repo-sync"])
assert args.architecture == ["x86_64"]
assert args.lock is None
assert args.quiet
assert args.no_report
assert args.unsafe
def test_subparsers_status_update(parser: argparse.ArgumentParser) -> None:
"""
status-update command must imply lock, no-log, no-report and unsafe
"""
args = parser.parse_args(["-a", "x86_64", "status-update"])
assert args.architecture == ["x86_64"]
assert args.lock is None
assert args.quiet
assert args.no_report
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_sync_architecture(parser: argparse.ArgumentParser) -> None:
"""
sync command must correctly parse architecture list
"""
args = parser.parse_args(["sync"])
assert args.architecture is None assert args.architecture is None
args = parser.parse_args(["-a", "x86_64", "sync"]) args = parser.parse_args(["-a", "x86_64", "repo-sync"])
assert args.architecture == ["x86_64"] assert args.architecture == ["x86_64"]
def test_subparsers_update_architecture(parser: argparse.ArgumentParser) -> None: def test_subparsers_repo_update_architecture(parser: argparse.ArgumentParser) -> None:
""" """
update command must correctly parse architecture list repo-update command must correctly parse architecture list
""" """
args = parser.parse_args(["update"]) args = parser.parse_args(["repo-update"])
assert args.architecture is None assert args.architecture is None
args = parser.parse_args(["-a", "x86_64", "update"]) args = parser.parse_args(["-a", "x86_64", "repo-update"])
assert args.architecture == ["x86_64"] assert args.architecture == ["x86_64"]
def test_subparsers_user(parser: argparse.ArgumentParser) -> None: def test_subparsers_user_add(parser: argparse.ArgumentParser) -> None:
""" """
user command must imply architecture, lock, no-log, no-report and unsafe user-add command must imply action, architecture, lock, no-report, quiet and unsafe
""" """
args = parser.parse_args(["user", "username"]) args = parser.parse_args(["user-add", "username"])
assert args.action == Action.Update
assert args.architecture == [""] assert args.architecture == [""]
assert args.lock is None assert args.lock is None
assert args.quiet
assert args.no_report assert args.no_report
assert args.quiet
assert args.unsafe assert args.unsafe
def test_subparsers_user_architecture(parser: argparse.ArgumentParser) -> None: def test_subparsers_user_add_architecture(parser: argparse.ArgumentParser) -> None:
""" """
user command must correctly parse architecture list user-add command must correctly parse architecture list
""" """
args = parser.parse_args(["-a", "x86_64", "user", "username"]) args = parser.parse_args(["-a", "x86_64", "user-add", "username"])
assert args.architecture == [""] assert args.architecture == [""]
def test_subparsers_user_option_role(parser: argparse.ArgumentParser) -> None: def test_subparsers_user_add_option_role(parser: argparse.ArgumentParser) -> None:
""" """
user command must convert role option to useraccess instance user-add command must convert role option to useraccess instance
""" """
args = parser.parse_args(["user", "username"]) args = parser.parse_args(["user-add", "username"])
assert isinstance(args.access, UserAccess) assert isinstance(args.role, UserAccess)
args = parser.parse_args(["user", "username", "--access", "write"]) args = parser.parse_args(["user-add", "username", "--role", "write"])
assert isinstance(args.access, UserAccess) assert isinstance(args.role, UserAccess)
def test_subparsers_user_remove(parser: argparse.ArgumentParser) -> None:
"""
user-remove command must imply action, architecture, lock, no-report, password, quiet, role and unsafe
"""
args = parser.parse_args(["user-remove", "username"])
assert args.action == Action.Remove
assert args.architecture == [""]
assert args.lock is None
assert args.no_report
assert args.password is not None
assert args.quiet
assert args.role is not None
assert args.unsafe
def test_subparsers_user_remove_architecture(parser: argparse.ArgumentParser) -> None:
"""
user-remove command must correctly parse architecture list
"""
args = parser.parse_args(["-a", "x86_64", "user-remove", "username"])
assert args.architecture == [""]
def test_subparsers_web(parser: argparse.ArgumentParser) -> None: def test_subparsers_web(parser: argparse.ArgumentParser) -> None: