allow to filter packages for rebuild by their statuses

This commit is contained in:
Evgenii Alekseev 2023-05-25 17:41:54 +03:00
parent d96e3c97db
commit 8f0a6cf6b5
7 changed files with 58 additions and 15 deletions

View File

@ -1,4 +1,4 @@
.TH AHRIMAN "1" "2023\-05\-22" "ahriman" "Generated Python Manual"
.TH AHRIMAN "1" "2023\-05\-25" "ahriman" "Generated Python Manual"
.SH NAME
ahriman
.SH SYNOPSIS
@ -453,6 +453,7 @@ download fresh package databases from the mirror before actions, \-yy to force r
.SH COMMAND \fI\,'ahriman repo\-rebuild'\/\fR
usage: ahriman repo\-rebuild [\-h] [\-\-depends\-on DEPENDS_ON] [\-\-dry\-run] [\-\-from\-database] [\-e]
[\-s {unknown,pending,building,failed,success}]
force rebuild whole repository
@ -475,6 +476,10 @@ original ahriman instance run with web service and have run repo\-update at leas
\fB\-e\fR, \fB\-\-exit\-code\fR
return non\-zero exit status if result is empty
.TP
\fB\-s\fR \fI\,{unknown,pending,building,failed,success}\/\fR, \fB\-\-status\fR \fI\,{unknown,pending,building,failed,success}\/\fR
filter packages by status. Requires \-\-from\-database to be set
.SH COMMAND \fI\,'ahriman repo\-remove\-unknown'\/\fR
usage: ahriman repo\-remove\-unknown [\-h] [\-\-dry\-run]

View File

@ -31,8 +31,8 @@ _shtab_ahriman_repo_create_keyring_option_strings=('-h' '--help')
_shtab_ahriman_repo_create_mirrorlist_option_strings=('-h' '--help')
_shtab_ahriman_repo_daemon_option_strings=('-h' '--help' '-i' '--interval' '--aur' '--no-aur' '--dependencies' '--no-dependencies' '--local' '--no-local' '--manual' '--no-manual' '--vcs' '--no-vcs' '-y' '--refresh')
_shtab_ahriman_daemon_option_strings=('-h' '--help' '-i' '--interval' '--aur' '--no-aur' '--dependencies' '--no-dependencies' '--local' '--no-local' '--manual' '--no-manual' '--vcs' '--no-vcs' '-y' '--refresh')
_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_rebuild_option_strings=('-h' '--help' '--depends-on' '--dry-run' '--from-database' '-e' '--exit-code' '-s' '--status')
_shtab_ahriman_rebuild_option_strings=('-h' '--help' '--depends-on' '--dry-run' '--from-database' '-e' '--exit-code' '-s' '--status')
_shtab_ahriman_repo_remove_unknown_option_strings=('-h' '--help' '--dry-run')
_shtab_ahriman_remove_unknown_option_strings=('-h' '--help' '--dry-run')
_shtab_ahriman_repo_report_option_strings=('-h' '--help')
@ -89,6 +89,10 @@ _shtab_ahriman_package_status_update__s_choices=('unknown' 'pending' 'building'
_shtab_ahriman_package_status_update___status_choices=('unknown' 'pending' 'building' 'failed' 'success')
_shtab_ahriman_status_update__s_choices=('unknown' 'pending' 'building' 'failed' 'success')
_shtab_ahriman_status_update___status_choices=('unknown' 'pending' 'building' 'failed' 'success')
_shtab_ahriman_repo_rebuild__s_choices=('unknown' 'pending' 'building' 'failed' 'success')
_shtab_ahriman_repo_rebuild___status_choices=('unknown' 'pending' 'building' 'failed' 'success')
_shtab_ahriman_rebuild__s_choices=('unknown' 'pending' 'building' 'failed' 'success')
_shtab_ahriman_rebuild___status_choices=('unknown' 'pending' 'building' 'failed' 'success')
_shtab_ahriman_repo_status_update__s_choices=('unknown' 'pending' 'building' 'failed' 'success')
_shtab_ahriman_repo_status_update___status_choices=('unknown' 'pending' 'building' 'failed' 'success')
_shtab_ahriman_service_setup___sign_target_choices=('disabled' 'packages' 'repository')

View File

@ -261,6 +261,7 @@ _shtab_ahriman_rebuild_options=(
"--dry-run[just perform check for packages without rebuild process itself]"
"--from-database[read packages from database instead of filesystem. This feature in particular is required in case if you would like to restore repository from another repository instance. Note, however, that in order to restore packages you need to have original ahriman instance run with web service and have run repo-update at least once.]"
{-e,--exit-code}"[return non-zero exit status if result is empty]"
{-s,--status}"[filter packages by status. Requires --from-database to be set]:status:(unknown pending building failed success)"
)
_shtab_ahriman_remove_options=(
@ -346,6 +347,7 @@ _shtab_ahriman_repo_rebuild_options=(
"--dry-run[just perform check for packages without rebuild process itself]"
"--from-database[read packages from database instead of filesystem. This feature in particular is required in case if you would like to restore repository from another repository instance. Note, however, that in order to restore packages you need to have original ahriman instance run with web service and have run repo-update at least once.]"
{-e,--exit-code}"[return non-zero exit status if result is empty]"
{-s,--status}"[filter packages by status. Requires --from-database to be set]:status:(unknown pending building failed success)"
)
_shtab_ahriman_repo_remove_unknown_options=(

View File

@ -571,6 +571,8 @@ def _set_repo_rebuild_parser(root: SubParserAction) -> argparse.ArgumentParser:
"ahriman instance run with web service and have run repo-update at least once.",
action="store_true")
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty", action="store_true")
parser.add_argument("-s", "--status", help="filter packages by status. Requires --from-database to be set",
type=BuildStatusEnum, choices=enum_values(BuildStatusEnum))
parser.set_defaults(handler=handlers.Rebuild)
return parser

View File

@ -23,6 +23,7 @@ from ahriman.application.application import Application
from ahriman.application.handlers import Handler
from ahriman.core.configuration import Configuration
from ahriman.core.formatters import UpdatePrinter
from ahriman.models.build_status import BuildStatusEnum
from ahriman.models.package import Package
@ -47,7 +48,7 @@ class Rebuild(Handler):
application = Application(architecture, configuration, report=report, unsafe=unsafe)
application.on_start()
packages = Rebuild.extract_packages(application, from_database=args.from_database)
packages = Rebuild.extract_packages(application, args.status, from_database=args.from_database)
updates = application.repository.packages_depend_on(packages, args.depends_on or None)
Rebuild.check_if_empty(args.exit_code, not updates)
@ -60,17 +61,24 @@ class Rebuild(Handler):
Rebuild.check_if_empty(args.exit_code, result.is_empty)
@staticmethod
def extract_packages(application: Application, *, from_database: bool) -> list[Package]:
def extract_packages(application: Application, status: BuildStatusEnum | None, *,
from_database: bool) -> list[Package]:
"""
extract packages from database file
Args:
application(Application): application instance
status(BuildStatusEnum | None): optional filter by package status
from_database(bool): extract packages from database instead of repository filesystem
Returns:
list[Package]: list of packages which were stored in database
"""
if from_database:
return [package for (package, _) in application.database.packages_get()]
return [
package
for (package, last_status) in application.database.packages_get()
if status is None or last_status.status == status
]
return application.repository.packages()

View File

@ -8,6 +8,7 @@ from ahriman.application.application import Application
from ahriman.application.handlers import Rebuild
from ahriman.core.configuration import Configuration
from ahriman.core.repository import Repository
from ahriman.models.build_status import BuildStatus, BuildStatusEnum
from ahriman.models.package import Package
from ahriman.models.result import Result
@ -26,6 +27,7 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace:
args.dry_run = False
args.from_database = False
args.exit_code = False
args.status = None
return args
@ -46,7 +48,7 @@ def test_run(args: argparse.Namespace, package_ahriman: Package, configuration:
on_start_mock = mocker.patch("ahriman.application.application.Application.on_start")
Rebuild.run(args, "x86_64", configuration, report=False, unsafe=False)
extract_mock.assert_called_once_with(pytest.helpers.anyvar(int), from_database=args.from_database)
extract_mock.assert_called_once_with(pytest.helpers.anyvar(int), args.status, from_database=args.from_database)
application_packages_mock.assert_called_once_with([package_ahriman], None)
application_mock.assert_called_once_with([package_ahriman])
check_mock.assert_has_calls([MockCall(False, False), MockCall(False, False)])
@ -56,7 +58,7 @@ def test_run(args: argparse.Namespace, package_ahriman: Package, configuration:
def test_run_extract_packages(args: argparse.Namespace, configuration: Configuration, repository: Repository,
mocker: MockerFixture) -> None:
"""
must run command
must run command from database
"""
args = _default_args(args)
args.from_database = True
@ -66,7 +68,7 @@ def test_run_extract_packages(args: argparse.Namespace, configuration: Configura
extract_mock = mocker.patch("ahriman.application.handlers.Rebuild.extract_packages", return_value=[])
Rebuild.run(args, "x86_64", configuration, report=False, unsafe=False)
extract_mock.assert_called_once_with(pytest.helpers.anyvar(int), from_database=args.from_database)
extract_mock.assert_called_once_with(pytest.helpers.anyvar(int), args.status, from_database=args.from_database)
def test_run_dry_run(args: argparse.Namespace, configuration: Configuration, repository: Repository,
@ -156,7 +158,19 @@ def test_extract_packages(application: Application, mocker: MockerFixture) -> No
must extract packages from database
"""
packages_mock = mocker.patch("ahriman.core.repository.repository.Repository.packages")
Rebuild.extract_packages(application, from_database=False)
Rebuild.extract_packages(application, None, from_database=False)
packages_mock.assert_called_once_with()
def test_extract_packages_by_status(application: Application, mocker: MockerFixture) -> None:
"""
must extract packages from database and filter them by status
"""
packages_mock = mocker.patch("ahriman.core.database.SQLite.packages_get", return_value=[
("package1", BuildStatus(BuildStatusEnum.Success)),
("package2", BuildStatus(BuildStatusEnum.Failed)),
])
assert Rebuild.extract_packages(application, BuildStatusEnum.Failed, from_database=True) == ["package2"]
packages_mock.assert_called_once_with()
@ -165,5 +179,5 @@ def test_extract_packages_from_database(application: Application, mocker: Mocker
must extract packages from database
"""
packages_mock = mocker.patch("ahriman.core.database.SQLite.packages_get")
Rebuild.extract_packages(application, from_database=True)
Rebuild.extract_packages(application, None, from_database=True)
packages_mock.assert_called_once_with()

View File

@ -451,6 +451,14 @@ def test_subparsers_repo_rebuild_architecture(parser: argparse.ArgumentParser) -
assert args.architecture == ["x86_64"]
def test_subparsers_repo_rebuild_option_status(parser: argparse.ArgumentParser) -> None:
"""
repo-rebuild command must convert status option to BuildStatusEnum instance
"""
args = parser.parse_args(["-a", "x86_64", "repo-rebuild", "--status", "failed"])
assert isinstance(args.status, BuildStatusEnum)
def test_subparsers_repo_remove_unknown_architecture(parser: argparse.ArgumentParser) -> None:
"""
repo-remove-unknown command must correctly parse architecture list
@ -524,7 +532,7 @@ def test_subparsers_repo_status_update(parser: argparse.ArgumentParser) -> None:
def test_subparsers_repo_status_update_option_status(parser: argparse.ArgumentParser) -> None:
"""
repo-status-update command must convert status option to buildstatusenum instance
repo-status-update command must convert status option to BuildStatusEnum instance
"""
args = parser.parse_args(["-a", "x86_64", "repo-status-update"])
assert isinstance(args.status, BuildStatusEnum)
@ -691,7 +699,7 @@ def test_subparsers_service_setup_option_from_configuration(parser: argparse.Arg
def test_subparsers_service_setup_option_sign_target(parser: argparse.ArgumentParser) -> None:
"""
service-setup command must convert sign-target option to signsettings instance
service-setup command must convert sign-target option to SignSettings instance
"""
args = parser.parse_args(["-a", "x86_64", "service-setup", "--packager", "John Doe <john@doe.com>",
"--repository", "aur-clone", "--sign-target", "packages"])
@ -730,7 +738,7 @@ def test_subparsers_user_add_architecture(parser: argparse.ArgumentParser) -> No
def test_subparsers_user_add_option_role(parser: argparse.ArgumentParser) -> None:
"""
user-add command must convert role option to useraccess instance
user-add command must convert role option to UserAccess instance
"""
args = parser.parse_args(["user-add", "username"])
assert isinstance(args.role, UserAccess)
@ -762,7 +770,7 @@ def test_subparsers_user_list_architecture(parser: argparse.ArgumentParser) -> N
def test_subparsers_user_list_option_role(parser: argparse.ArgumentParser) -> None:
"""
user-list command must convert role option to useraccess instance
user-list command must convert role option to UserAccess instance
"""
args = parser.parse_args(["user-list", "--role", "full"])
assert isinstance(args.role, UserAccess)