mirror of
https://github.com/arcan1s/ahriman.git
synced 2026-03-11 04:23:38 +00:00
feat: add pkgbuild subscommands
This commit is contained in:
@@ -92,6 +92,14 @@ ahriman.application.handlers.patch module
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.application.handlers.pkgbuild module
|
||||
--------------------------------------------
|
||||
|
||||
.. automodule:: ahriman.application.handlers.pkgbuild
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.application.handlers.rebuild module
|
||||
-------------------------------------------
|
||||
|
||||
|
||||
@@ -76,6 +76,14 @@ ahriman.core.formatters.patch\_printer module
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.core.formatters.pkgbuild\_printer module
|
||||
------------------------------------------------
|
||||
|
||||
.. automodule:: ahriman.core.formatters.pkgbuild_printer
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.core.formatters.printer module
|
||||
--------------------------------------
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ class Change(Handler):
|
||||
case Action.List:
|
||||
changes = client.package_changes_get(args.package)
|
||||
ChangesPrinter(changes)(verbose=True, separator="")
|
||||
Change.check_status(args.exit_code, not changes.is_empty)
|
||||
Change.check_status(args.exit_code, changes.changes is not None)
|
||||
case Action.Remove:
|
||||
client.package_changes_update(args.package, Changes())
|
||||
|
||||
|
||||
101
src/ahriman/application/handlers/pkgbuild.py
Normal file
101
src/ahriman/application/handlers/pkgbuild.py
Normal file
@@ -0,0 +1,101 @@
|
||||
#
|
||||
# Copyright (c) 2021-2026 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
|
||||
|
||||
from dataclasses import replace
|
||||
|
||||
from ahriman.application.application import Application
|
||||
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.formatters import PkgbuildPrinter
|
||||
from ahriman.models.action import Action
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
|
||||
|
||||
class Pkgbuild(Handler):
|
||||
"""
|
||||
package pkgbuild handler
|
||||
"""
|
||||
|
||||
ALLOW_MULTI_ARCHITECTURE_RUN = False # conflicting io
|
||||
|
||||
@classmethod
|
||||
def run(cls, args: argparse.Namespace, repository_id: RepositoryId, configuration: Configuration, *,
|
||||
report: bool) -> None:
|
||||
"""
|
||||
callback for command line
|
||||
|
||||
Args:
|
||||
args(argparse.Namespace): command line args
|
||||
repository_id(RepositoryId): repository unique identifier
|
||||
configuration(Configuration): configuration instance
|
||||
report(bool): force enable or disable reporting
|
||||
"""
|
||||
application = Application(repository_id, configuration, report=True)
|
||||
client = application.repository.reporter
|
||||
|
||||
match args.action:
|
||||
case Action.List:
|
||||
changes = client.package_changes_get(args.package)
|
||||
PkgbuildPrinter(changes)(verbose=True, separator="")
|
||||
Pkgbuild.check_status(args.exit_code, changes.pkgbuild is not None)
|
||||
case Action.Remove:
|
||||
changes = client.package_changes_get(args.package)
|
||||
client.package_changes_update(args.package, replace(changes, pkgbuild=None))
|
||||
|
||||
@staticmethod
|
||||
def _set_package_pkgbuild_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||
"""
|
||||
add parser for package pkgbuild subcommand
|
||||
|
||||
Args:
|
||||
root(SubParserAction): subparsers for the commands
|
||||
|
||||
Returns:
|
||||
argparse.ArgumentParser: created argument parser
|
||||
"""
|
||||
parser = root.add_parser("package-pkgbuild", help="get package pkgbuild",
|
||||
description="retrieve package PKGBUILD stored in database",
|
||||
epilog="This command requests package status from the web interface "
|
||||
"if it is available.")
|
||||
parser.add_argument("package", help="package base")
|
||||
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty",
|
||||
action="store_true")
|
||||
parser.set_defaults(action=Action.List, lock=None, quiet=True, report=False, unsafe=True)
|
||||
return parser
|
||||
|
||||
@staticmethod
|
||||
def _set_package_pkgbuild_remove_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||
"""
|
||||
add parser for package pkgbuild remove subcommand
|
||||
|
||||
Args:
|
||||
root(SubParserAction): subparsers for the commands
|
||||
|
||||
Returns:
|
||||
argparse.ArgumentParser: created argument parser
|
||||
"""
|
||||
parser = root.add_parser("package-pkgbuild-remove", help="remove package pkgbuild",
|
||||
description="remove the package PKGBUILD stored remotely")
|
||||
parser.add_argument("package", help="package base")
|
||||
parser.set_defaults(action=Action.Remove, exit_code=False, lock=None, quiet=True, report=False, unsafe=True)
|
||||
return parser
|
||||
|
||||
arguments = [_set_package_pkgbuild_parser, _set_package_pkgbuild_remove_parser]
|
||||
@@ -26,6 +26,7 @@ from ahriman.core.formatters.event_stats_printer import EventStatsPrinter
|
||||
from ahriman.core.formatters.package_printer import PackagePrinter
|
||||
from ahriman.core.formatters.package_stats_printer import PackageStatsPrinter
|
||||
from ahriman.core.formatters.patch_printer import PatchPrinter
|
||||
from ahriman.core.formatters.pkgbuild_printer import PkgbuildPrinter
|
||||
from ahriman.core.formatters.printer import Printer
|
||||
from ahriman.core.formatters.repository_printer import RepositoryPrinter
|
||||
from ahriman.core.formatters.repository_stats_printer import RepositoryStatsPrinter
|
||||
|
||||
@@ -45,7 +45,7 @@ class ChangesPrinter(Printer):
|
||||
Returns:
|
||||
list[Property]: list of content properties
|
||||
"""
|
||||
if self.changes.is_empty:
|
||||
if self.changes.changes is None:
|
||||
return []
|
||||
return [Property("", self.changes.changes, is_required=True, indent=0)]
|
||||
|
||||
@@ -57,6 +57,6 @@ class ChangesPrinter(Printer):
|
||||
Returns:
|
||||
str | None: content title if it can be generated and ``None`` otherwise
|
||||
"""
|
||||
if self.changes.is_empty:
|
||||
if self.changes.changes is None:
|
||||
return None
|
||||
return self.changes.last_commit_sha
|
||||
|
||||
62
src/ahriman/core/formatters/pkgbuild_printer.py
Normal file
62
src/ahriman/core/formatters/pkgbuild_printer.py
Normal file
@@ -0,0 +1,62 @@
|
||||
#
|
||||
# Copyright (c) 2021-2026 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/>.
|
||||
#
|
||||
from ahriman.core.formatters.printer import Printer
|
||||
from ahriman.models.changes import Changes
|
||||
from ahriman.models.property import Property
|
||||
|
||||
|
||||
class PkgbuildPrinter(Printer):
|
||||
"""
|
||||
print content of the pkgbuild stored in changes
|
||||
|
||||
Attributes:
|
||||
changes(Changes): package changes
|
||||
"""
|
||||
|
||||
def __init__(self, changes: Changes) -> None:
|
||||
"""
|
||||
Args:
|
||||
changes(Changes): package changes
|
||||
"""
|
||||
Printer.__init__(self)
|
||||
self.changes = changes
|
||||
|
||||
def properties(self) -> list[Property]:
|
||||
"""
|
||||
convert content into printable data
|
||||
|
||||
Returns:
|
||||
list[Property]: list of content properties
|
||||
"""
|
||||
if self.changes.pkgbuild is None:
|
||||
return []
|
||||
return [Property("", self.changes.pkgbuild, is_required=True, indent=0)]
|
||||
|
||||
# pylint: disable=redundant-returns-doc
|
||||
def title(self) -> str | None:
|
||||
"""
|
||||
generate entry title from content
|
||||
|
||||
Returns:
|
||||
str | None: content title if it can be generated and ``None`` otherwise
|
||||
"""
|
||||
if self.changes.pkgbuild is None:
|
||||
return None
|
||||
return self.changes.last_commit_sha
|
||||
@@ -38,16 +38,6 @@ class Changes:
|
||||
changes: str | None = None
|
||||
pkgbuild: str | None = None
|
||||
|
||||
@property
|
||||
def is_empty(self) -> bool:
|
||||
"""
|
||||
validate that changes are not empty
|
||||
|
||||
Returns:
|
||||
bool: ``True`` in case if changes are not set and ``False`` otherwise
|
||||
"""
|
||||
return self.changes is None
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, dump: dict[str, Any]) -> Self:
|
||||
"""
|
||||
|
||||
100
tests/ahriman/application/handlers/test_handler_pkgbuild.py
Normal file
100
tests/ahriman/application/handlers/test_handler_pkgbuild.py
Normal file
@@ -0,0 +1,100 @@
|
||||
import argparse
|
||||
import pytest
|
||||
|
||||
from pytest_mock import MockerFixture
|
||||
|
||||
from ahriman.application.handlers.pkgbuild import Pkgbuild
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.database import SQLite
|
||||
from ahriman.core.repository import Repository
|
||||
from ahriman.models.action import Action
|
||||
from ahriman.models.changes import Changes
|
||||
|
||||
|
||||
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.action = Action.List
|
||||
args.exit_code = False
|
||||
args.package = "package"
|
||||
return args
|
||||
|
||||
|
||||
def test_run(args: argparse.Namespace, configuration: Configuration, repository: Repository,
|
||||
mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must run command
|
||||
"""
|
||||
args = _default_args(args)
|
||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||
application_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.package_changes_get",
|
||||
return_value=Changes("sha", "change", "pkgbuild content"))
|
||||
check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_status")
|
||||
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
||||
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Pkgbuild.run(args, repository_id, configuration, report=False)
|
||||
application_mock.assert_called_once_with(args.package)
|
||||
check_mock.assert_called_once_with(False, True)
|
||||
print_mock.assert_called_once_with(verbose=True, log_fn=pytest.helpers.anyvar(int), separator="")
|
||||
|
||||
|
||||
def test_run_empty_exception(args: argparse.Namespace, configuration: Configuration, repository: Repository,
|
||||
mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must raise ExitCode exception on empty pkgbuild result
|
||||
"""
|
||||
args = _default_args(args)
|
||||
args.exit_code = True
|
||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||
mocker.patch("ahriman.core.status.local_client.LocalClient.package_changes_get", return_value=Changes())
|
||||
check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_status")
|
||||
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Pkgbuild.run(args, repository_id, configuration, report=False)
|
||||
check_mock.assert_called_once_with(True, False)
|
||||
|
||||
|
||||
def test_run_remove(args: argparse.Namespace, configuration: Configuration, repository: Repository,
|
||||
mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must remove package pkgbuild
|
||||
"""
|
||||
args = _default_args(args)
|
||||
args.action = Action.Remove
|
||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||
changes = Changes("sha", "change", "pkgbuild content")
|
||||
mocker.patch("ahriman.core.status.local_client.LocalClient.package_changes_get", return_value=changes)
|
||||
update_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.package_changes_update")
|
||||
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Pkgbuild.run(args, repository_id, configuration, report=False)
|
||||
update_mock.assert_called_once_with(args.package, Changes("sha", "change", None))
|
||||
|
||||
|
||||
def test_imply_with_report(args: argparse.Namespace, configuration: Configuration, database: SQLite,
|
||||
mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must create application object with native reporting
|
||||
"""
|
||||
args = _default_args(args)
|
||||
mocker.patch("ahriman.core.database.SQLite.load", return_value=database)
|
||||
load_mock = mocker.patch("ahriman.core.repository.Repository.load")
|
||||
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Pkgbuild.run(args, repository_id, configuration, report=False)
|
||||
load_mock.assert_called_once_with(repository_id, configuration, database, report=True, refresh_pacman_database=0)
|
||||
|
||||
|
||||
def test_disallow_multi_architecture_run() -> None:
|
||||
"""
|
||||
must not allow multi architecture run
|
||||
"""
|
||||
assert not Pkgbuild.ALLOW_MULTI_ARCHITECTURE_RUN
|
||||
@@ -2,24 +2,26 @@ import pytest
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from ahriman.core.formatters import \
|
||||
AurPrinter, \
|
||||
ChangesPrinter, \
|
||||
ConfigurationPathsPrinter, \
|
||||
ConfigurationPrinter, \
|
||||
EventStatsPrinter, \
|
||||
PackagePrinter, \
|
||||
PackageStatsPrinter, \
|
||||
PatchPrinter, \
|
||||
RepositoryPrinter, \
|
||||
RepositoryStatsPrinter, \
|
||||
StatusPrinter, \
|
||||
StringPrinter, \
|
||||
TreePrinter, \
|
||||
UpdatePrinter, \
|
||||
UserPrinter, \
|
||||
ValidationPrinter, \
|
||||
from ahriman.core.formatters import (
|
||||
AurPrinter,
|
||||
ChangesPrinter,
|
||||
ConfigurationPathsPrinter,
|
||||
ConfigurationPrinter,
|
||||
EventStatsPrinter,
|
||||
PackagePrinter,
|
||||
PackageStatsPrinter,
|
||||
PatchPrinter,
|
||||
PkgbuildPrinter,
|
||||
RepositoryPrinter,
|
||||
RepositoryStatsPrinter,
|
||||
StatusPrinter,
|
||||
StringPrinter,
|
||||
TreePrinter,
|
||||
UpdatePrinter,
|
||||
UserPrinter,
|
||||
ValidationPrinter,
|
||||
VersionPrinter
|
||||
)
|
||||
from ahriman.models.aur_package import AURPackage
|
||||
from ahriman.models.build_status import BuildStatus
|
||||
from ahriman.models.changes import Changes
|
||||
@@ -55,6 +57,17 @@ def changes_printer() -> ChangesPrinter:
|
||||
return ChangesPrinter(Changes("sha", "changes"))
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def pkgbuild_printer() -> PkgbuildPrinter:
|
||||
"""
|
||||
fixture for pkgbuild printer
|
||||
|
||||
Returns:
|
||||
PkgbuildPrinter: pkgbuild printer test instance
|
||||
"""
|
||||
return PkgbuildPrinter(Changes("sha", "changes", "pkgbuild content"))
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def configuration_paths_printer() -> ConfigurationPathsPrinter:
|
||||
"""
|
||||
|
||||
32
tests/ahriman/core/formatters/test_pkgbuild_printer.py
Normal file
32
tests/ahriman/core/formatters/test_pkgbuild_printer.py
Normal file
@@ -0,0 +1,32 @@
|
||||
from ahriman.core.formatters import PkgbuildPrinter
|
||||
from ahriman.models.changes import Changes
|
||||
|
||||
|
||||
def test_properties(pkgbuild_printer: PkgbuildPrinter) -> None:
|
||||
"""
|
||||
must return non-empty properties list
|
||||
"""
|
||||
assert pkgbuild_printer.properties()
|
||||
|
||||
|
||||
def test_properties_empty() -> None:
|
||||
"""
|
||||
must return empty properties list if pkgbuild is empty
|
||||
"""
|
||||
assert not PkgbuildPrinter(Changes()).properties()
|
||||
assert not PkgbuildPrinter(Changes("sha", "changes")).properties()
|
||||
|
||||
|
||||
def test_title(pkgbuild_printer: PkgbuildPrinter) -> None:
|
||||
"""
|
||||
must return non-empty title
|
||||
"""
|
||||
assert pkgbuild_printer.title()
|
||||
|
||||
|
||||
def test_title_empty() -> None:
|
||||
"""
|
||||
must return empty title if change is empty
|
||||
"""
|
||||
assert not PkgbuildPrinter(Changes()).title()
|
||||
assert not PkgbuildPrinter(Changes("sha")).title()
|
||||
@@ -1,17 +1,6 @@
|
||||
from ahriman.models.changes import Changes
|
||||
|
||||
|
||||
def test_is_empty() -> None:
|
||||
"""
|
||||
must check if changes are empty
|
||||
"""
|
||||
assert Changes().is_empty
|
||||
assert Changes("sha").is_empty
|
||||
|
||||
assert not Changes("sha", "change").is_empty
|
||||
assert not Changes(None, "change").is_empty # well, ok
|
||||
|
||||
|
||||
def test_changes_from_json_view() -> None:
|
||||
"""
|
||||
must construct same object from json
|
||||
|
||||
Reference in New Issue
Block a user