mirror of
https://github.com/arcan1s/ahriman.git
synced 2025-05-01 10:47:17 +00:00
Compare commits
2 Commits
b9203c38e0
...
1a8d3efaf1
Author | SHA1 | Date | |
---|---|---|---|
1a8d3efaf1 | |||
6612510d12 |
@ -40,12 +40,12 @@ fi
|
||||
if [ -n "$AHRIMAN_PACMAN_MIRROR" ]; then
|
||||
AHRIMAN_SETUP_ARGS+=("--mirror" "$AHRIMAN_PACMAN_MIRROR")
|
||||
fi
|
||||
if [ -n "$AHRIMAN_PORT" ]; then
|
||||
AHRIMAN_SETUP_ARGS+=("--web-port" "$AHRIMAN_PORT")
|
||||
fi
|
||||
if [ -n "$AHRIMAN_REPOSITORY_SERVER" ]; then
|
||||
AHRIMAN_SETUP_ARGS+=("--server" "$AHRIMAN_REPOSITORY_SERVER")
|
||||
fi
|
||||
if [ -n "$AHRIMAN_PORT" ]; then
|
||||
AHRIMAN_SETUP_ARGS+=("--web-port" "$AHRIMAN_PORT")
|
||||
fi
|
||||
if [ -n "$AHRIMAN_UNIX_SOCKET" ]; then
|
||||
AHRIMAN_SETUP_ARGS+=("--web-unix-socket" "$AHRIMAN_UNIX_SOCKET")
|
||||
fi
|
||||
|
@ -1,7 +1,12 @@
|
||||
Configuration
|
||||
=============
|
||||
|
||||
Some groups can be specified for each architecture separately. E.g. if there are ``build`` and ``build:x86_64`` groups it will use an option from ``build:x86_64`` for the ``x86_64`` architecture and ``build`` for any other (architecture specific group has higher priority). In case if both groups are presented, architecture specific options will be merged into global ones overriding them.
|
||||
Some groups can be specified for each architecture and/or repository separately. E.g. if there are ``build`` and ``build:x86_64`` groups it will use an option from ``build:x86_64`` for the ``x86_64`` architecture and ``build`` for any other (architecture specific group has higher priority). In case if both groups are presented, architecture specific options will be merged into global ones overriding them. The order which will be used for option resolution is the following:
|
||||
|
||||
1. Repository and architecture specific, e.g. ``build:aur-clone:x86_64``.
|
||||
2. Repository specific, e.g. ``build:aur-clone``.
|
||||
2. Architecture specific, e.g. ``build:x86_64``.
|
||||
2. Default section, e.g. ``build``.
|
||||
|
||||
There are two variable types which have been added to default ones, they are paths and lists. List values will be read in the same way as shell does:
|
||||
|
||||
@ -86,7 +91,6 @@ Build related configuration. Group name can refer to architecture, e.g. ``build:
|
||||
|
||||
Base repository settings.
|
||||
|
||||
* ``name`` - repository name, string, required.
|
||||
* ``root`` - root path for application, string, required.
|
||||
|
||||
``sign:*`` groups
|
||||
@ -291,20 +295,21 @@ Type will be read from several sources:
|
||||
``github`` type
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
This feature requires Github key creation (see below). Section name must be either ``github`` (plus optional architecture name, e.g. ``github:x86_64``) or random name with ``type`` set.
|
||||
This feature requires GitHub key creation (see below). Section name must be either ``github`` (plus optional architecture name, e.g. ``github:x86_64``) or random name with ``type`` set.
|
||||
|
||||
* ``type`` - type of the upload, string, optional, must be set to ``github`` if exists.
|
||||
* ``owner`` - Github repository owner, string, required.
|
||||
* ``password`` - created Github API key. In order to create it do the following:
|
||||
* ``owner`` - GitHub repository owner, string, required.
|
||||
* ``password`` - created GitHub API key. In order to create it do the following:
|
||||
|
||||
#. Go to `settings page <https://github.com/settings/profile>`_.
|
||||
#. Switch to `developers settings <https://github.com/settings/apps>`_.
|
||||
#. Switch to `personal access tokens <https://github.com/settings/tokens>`_.
|
||||
#. Generate new token. Required scope is ``public_repo`` (or ``repo`` for private repository support).
|
||||
|
||||
* ``repository`` - Github repository name, string, required. Repository must be created before any action and must have active branch (e.g. with readme).
|
||||
* ``repository`` - GitHub repository name, string, required. Repository must be created before any action and must have active branch (e.g. with readme).
|
||||
* ``timeout`` - HTTP request timeout in seconds, int, optional, default is ``30``.
|
||||
* ``username`` - Github authorization user, string, required. Basically the same as ``owner``.
|
||||
* ``use_full_release_name`` - if set to ``yes``, the release will contain both repository name and architecture, and only architecture otherwise, boolean, optional, default ``no``.
|
||||
* ``username`` - GitHub authorization user, string, required. Basically the same as ``owner``.
|
||||
|
||||
``remote-service`` type
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -328,7 +333,7 @@ Requires ``rsync`` package to be installed. Do not forget to configure ssh for u
|
||||
|
||||
Requires ``boto3`` library to be installed. Section name must be either ``s3`` (plus optional architecture name, e.g. ``s3:x86_64``) or random name with ``type`` set.
|
||||
|
||||
* ``type`` - type of the upload, string, optional, must be set to ``github`` if exists.
|
||||
* ``type`` - type of the upload, string, optional, must be set to ``s3`` if exists.
|
||||
* ``access_key`` - AWS access key ID, string, required.
|
||||
* ``bucket`` - bucket name (e.g. ``bucket``), string, required.
|
||||
* ``chunk_size`` - chunk size for calculating entity tags, int, optional, default 8 * 1024 * 1024.
|
||||
|
20
docs/faq.rst
20
docs/faq.rst
@ -17,7 +17,7 @@ TL;DR
|
||||
.. code-block:: shell
|
||||
|
||||
yay -S ahriman
|
||||
ahriman -a x86_64 service-setup --packager "ahriman bot <ahriman@example.com>" --repository "repository"
|
||||
ahriman -a x86_64 -r aur-clone service-setup --packager "ahriman bot <ahriman@example.com>"
|
||||
systemctl enable --now ahriman@x86_64.timer
|
||||
|
||||
Long answer
|
||||
@ -32,7 +32,7 @@ There is special command which can be used in order to validate current configur
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
ahriman -a x86_64 service-config-validate --exit-code
|
||||
ahriman -a x86_64 -r aur-clone service-config-validate --exit-code
|
||||
|
||||
This command will print found errors, based on `cerberus <https://docs.python-cerberus.org/>`_, e.g.:
|
||||
|
||||
@ -317,7 +317,7 @@ Add the following lines to your ``pacman.conf``:
|
||||
.. code-block:: ini
|
||||
|
||||
[repository]
|
||||
Server = file:///var/lib/ahriman/repository/x86_64
|
||||
Server = file:///var/lib/ahriman/repository/$repo/$arch
|
||||
|
||||
(You might need to add ``SigLevel`` option according to the pacman documentation.)
|
||||
|
||||
@ -554,8 +554,8 @@ There are several choices:
|
||||
.. code-block::
|
||||
|
||||
server {
|
||||
location /x86_64 {
|
||||
root /var/lib/ahriman/repository/x86_64;
|
||||
location /aur-clone/x86_64 {
|
||||
root /var/lib/ahriman/repository/aur-clone/x86_64;
|
||||
autoindex on;
|
||||
}
|
||||
}
|
||||
@ -571,7 +571,7 @@ There are several choices:
|
||||
[rsync]
|
||||
remote = 192.168.0.1:/srv/repo
|
||||
|
||||
After that just add ``/srv/repo`` to the ``pacman.conf`` as usual. You can also upload to S3 (e.g. ``Server = https://s3.eu-central-1.amazonaws.com/repository/x86_64``) or to Github (e.g. ``Server = https://github.com/ahriman/repository/releases/download/x86_64``).
|
||||
After that just add ``/srv/repo`` to the ``pacman.conf`` as usual. You can also upload to S3 (e.g. ``Server = https://s3.eu-central-1.amazonaws.com/repository/aur-clone/x86_64``) or to Github (e.g. ``Server = https://github.com/ahriman/repository/releases/download/aur-clone-x86_64``).
|
||||
|
||||
How to sync to S3
|
||||
^^^^^^^^^^^^^^^^^
|
||||
@ -676,7 +676,7 @@ How to report by email
|
||||
|
||||
[email]
|
||||
host = smtp.example.com
|
||||
link_path = http://example.com/x86_64
|
||||
link_path = http://example.com/aur-clone/x86_64
|
||||
password = ...
|
||||
port = 465
|
||||
receivers = me@example.com
|
||||
@ -702,8 +702,8 @@ How to generate index page for S3
|
||||
target = html
|
||||
|
||||
[html]
|
||||
path = /var/lib/ahriman/repository/x86_64/index.html
|
||||
link_path = http://example.com/x86_64
|
||||
path = /var/lib/ahriman/repository/aur-clone/x86_64/index.html
|
||||
link_path = http://example.com/aur-clone/x86_64
|
||||
|
||||
After these steps ``index.html`` file will be automatically synced to S3
|
||||
|
||||
@ -741,7 +741,7 @@ How to post build report to telegram
|
||||
[telegram]
|
||||
api_key = aaAAbbBBccCC
|
||||
chat_id = @ahriman
|
||||
link_path = http://example.com/x86_64
|
||||
link_path = http://example.com/aur-clone/x86_64
|
||||
|
||||
``api_key`` is the one sent by `@BotFather <https://t.me/botfather>`_, ``chat_id`` is the value retrieved from previous step.
|
||||
|
||||
|
@ -10,7 +10,7 @@ Initial setup
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
sudo ahriman -a x86_64 service-setup ...
|
||||
sudo ahriman -a x86_64 -r aur-clone service-setup ...
|
||||
|
||||
``service-setup`` literally does the following steps:
|
||||
|
||||
@ -29,26 +29,26 @@ Initial setup
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
ln -s /usr/bin/archbuild /usr/local/bin/ahriman-x86_64-build
|
||||
ln -s /usr/bin/archbuild /usr/local/bin/aur-clone-x86_64-build
|
||||
|
||||
#.
|
||||
Create configuration file (same as previous ``{name}.conf``):
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
cp /usr/share/devtools/pacman.conf.d/{extra,ahriman}.conf
|
||||
cp /usr/share/devtools/pacman.conf.d/{extra,aur-clone}.conf
|
||||
|
||||
#.
|
||||
Change configuration file, add your own repository, add multilib repository etc:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
echo '[multilib]' | tee -a /usr/share/devtools/pacman-ahriman.conf
|
||||
echo 'Include = /etc/pacman.d/mirrorlist' | tee -a /usr/share/devtools/pacman.conf.d/ahriman.conf
|
||||
echo '[multilib]' | tee -a /usr/share/devtools/pacman.conf.d/aur-clone-x86_64.conf
|
||||
echo 'Include = /etc/pacman.d/mirrorlist' | tee -a /usr/share/devtools/pacman.conf.d/aur-clone-x86_64.conf
|
||||
|
||||
echo '[aur-clone]' | tee -a /usr/share/devtools/pacman-ahriman.conf
|
||||
echo 'SigLevel = Optional TrustAll' | tee -a /usr/share/devtools/pacman.conf.d/ahriman.conf
|
||||
echo 'Server = file:///var/lib/ahriman/repository/$arch' | tee -a /usr/share/devtools/pacman.conf.d/ahriman.conf
|
||||
echo '[aur-clone]' | tee -a /usr/share/devtools/pacman.conf.d/aur-clone-x86_64.conf
|
||||
echo 'SigLevel = Optional TrustAll' | tee -a /usr/share/devtools/pacman.conf.d/aur-clone-x86_64.conf
|
||||
echo 'Server = file:///var/lib/ahriman/repository/$repo/$arch' | tee -a /usr/share/devtools/pacman.conf.d/aur-clone-x86_64.conf
|
||||
|
||||
#.
|
||||
Set ``build_command`` option to point to your command:
|
||||
@ -56,14 +56,14 @@ Initial setup
|
||||
.. code-block:: shell
|
||||
|
||||
echo '[build]' | tee -a /etc/ahriman.ini.d/build.ini
|
||||
echo 'build_command = ahriman-x86_64-build' | tee -a /etc/ahriman.ini.d/build.ini
|
||||
echo 'build_command = aur-clone-x86_64-build' | tee -a /etc/ahriman.ini.d/build.ini
|
||||
|
||||
#.
|
||||
Configure ``/etc/sudoers.d/ahriman`` to allow running command without a password:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
echo 'Cmnd_Alias CARCHBUILD_CMD = /usr/local/bin/ahriman-x86_64-build *' | tee -a /etc/sudoers.d/ahriman
|
||||
echo 'Cmnd_Alias CARCHBUILD_CMD = /usr/local/bin/aur-clone-x86_64-build *' | tee -a /etc/sudoers.d/ahriman
|
||||
echo 'ahriman ALL=(ALL) NOPASSWD:SETENV: CARCHBUILD_CMD' | tee -a /etc/sudoers.d/ahriman
|
||||
chmod 400 /etc/sudoers.d/ahriman
|
||||
|
||||
@ -88,6 +88,6 @@ Initial setup
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
sudo -u ahriman ahriman -a x86_64 package-add ahriman --now --refresh
|
||||
sudo -u ahriman ahriman package-add ahriman --now --refresh
|
||||
|
||||
The ``--refresh`` flag is required in order to handle local database update.
|
||||
|
@ -20,7 +20,6 @@ allow_read_only = yes
|
||||
|
||||
[build]
|
||||
archbuild_flags =
|
||||
build_command = extra-x86_64-build
|
||||
ignore_packages =
|
||||
makechrootpkg_flags =
|
||||
makepkg_flags = --nocolor --ignorearch
|
||||
@ -29,7 +28,6 @@ triggers_known = ahriman.core.gitremote.RemotePullTrigger ahriman.core.gitremote
|
||||
vcs_allowed_age = 604800
|
||||
|
||||
[repository]
|
||||
name = aur-clone
|
||||
root = /var/lib/ahriman
|
||||
|
||||
[sign]
|
||||
|
@ -81,7 +81,7 @@ def _parser() -> argparse.ArgumentParser:
|
||||
type=LogHandler, choices=enum_values(LogHandler))
|
||||
parser.add_argument("--report", help="force enable or disable reporting to web service",
|
||||
action=argparse.BooleanOptionalAction, default=True)
|
||||
parser.add_argument("-R", "--repository", help="target repository. For several subcommands it can be used "
|
||||
parser.add_argument("-r", "--repository", help="target repository. For several subcommands it can be used "
|
||||
"multiple times", action="append")
|
||||
parser.add_argument("-q", "--quiet", help="force disable any logging", action="store_true")
|
||||
parser.add_argument("--unsafe", help="allow to run ahriman as non-ahriman user. Some actions might be unavailable",
|
||||
@ -943,7 +943,7 @@ def _set_user_add_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||
"`Name Surname <mail@example.com>`")
|
||||
parser.add_argument("-p", "--password", help="user password. Blank password will be treated as empty password, "
|
||||
"which is in particular must be used for OAuth2 authorization type.")
|
||||
parser.add_argument("-r", "--role", help="user access level",
|
||||
parser.add_argument("-R", "--role", help="user access level",
|
||||
type=UserAccess, choices=enum_values(UserAccess), default=UserAccess.Read)
|
||||
parser.set_defaults(handler=handlers.Users, action=Action.Update, architecture=[""], lock=None, report=False,
|
||||
quiet=True)
|
||||
@ -965,7 +965,7 @@ def _set_user_list_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||
formatter_class=_formatter)
|
||||
parser.add_argument("username", help="filter users by username", nargs="?")
|
||||
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty", action="store_true")
|
||||
parser.add_argument("-r", "--role", help="filter users by role", type=UserAccess, choices=enum_values(UserAccess))
|
||||
parser.add_argument("-R", "--role", help="filter users by role", type=UserAccess, choices=enum_values(UserAccess))
|
||||
parser.set_defaults(handler=handlers.Users, action=Action.List, architecture=[""], lock=None, report=False,
|
||||
quiet=True, unsafe=True)
|
||||
return parser
|
||||
|
@ -40,7 +40,7 @@ class Application(ApplicationPackages, ApplicationRepository):
|
||||
>>> from ahriman.models.repository_id import RepositoryId
|
||||
>>>
|
||||
>>> configuration = Configuration()
|
||||
>>> application = Application(RepositoryId("x86_64", None), configuration, report=True)
|
||||
>>> application = Application(RepositoryId("x86_64", "x86_64"), configuration, report=True)
|
||||
>>> # add packages to build queue
|
||||
>>> application.add(["ahriman"], PackageSource.AUR)
|
||||
>>>
|
||||
|
@ -25,7 +25,7 @@ from multiprocessing import Pool
|
||||
from ahriman.application.lock import Lock
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.exceptions import ExitCode, MissingArchitectureError, MultipleArchitecturesError
|
||||
from ahriman.core.log import Log
|
||||
from ahriman.core.log.log_loader import LogLoader
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
from ahriman.models.repository_paths import RepositoryPaths
|
||||
|
||||
@ -65,8 +65,8 @@ class Handler:
|
||||
try:
|
||||
configuration = Configuration.from_path(args.configuration, repository_id)
|
||||
|
||||
log_handler = Log.handler(args.log_handler)
|
||||
Log.load(configuration, log_handler, quiet=args.quiet, report=args.report)
|
||||
log_handler = LogLoader.handler(args.log_handler)
|
||||
LogLoader.load(configuration, log_handler, quiet=args.quiet, report=args.report)
|
||||
|
||||
with Lock(args, repository_id, configuration):
|
||||
cls.run(args, repository_id, configuration, report=args.report)
|
||||
@ -116,7 +116,7 @@ class Handler:
|
||||
args(argparse.Namespace): command line args
|
||||
|
||||
Returns:
|
||||
tuple[str | None, str]: list of repository names and architectures for which tree is created
|
||||
list[RepositoryId]: list of repository names and architectures for which tree is created
|
||||
|
||||
Raises:
|
||||
MissingArchitectureError: if no architecture set and automatic detection is not allowed or failed
|
||||
@ -125,8 +125,13 @@ class Handler:
|
||||
# for some parsers (e.g. config) we need to run with specific architecture
|
||||
# for those cases architecture must be set explicitly
|
||||
raise MissingArchitectureError(args.command)
|
||||
|
||||
configuration = Configuration()
|
||||
configuration.load(args.configuration)
|
||||
name = configuration.get("repository", "name", fallback="") # will only be used for legacy mode
|
||||
|
||||
if args.architecture: # architecture is specified explicitly
|
||||
repositories = args.repository or [None] # fallback for legacy mode
|
||||
repositories = args.repository or [name] # fallback for legacy mode
|
||||
return sorted(
|
||||
set(
|
||||
RepositoryId(architecture, repository)
|
||||
@ -135,11 +140,8 @@ class Handler:
|
||||
)
|
||||
)
|
||||
|
||||
configuration = Configuration()
|
||||
configuration.load(args.configuration)
|
||||
# wtf???
|
||||
root = configuration.getpath("repository", "root") # pylint: disable=assignment-from-no-return
|
||||
name = configuration.get("repository", "name", fallback="") # will only be used for legacy mode
|
||||
architectures = RepositoryPaths.known_architectures(root, name)
|
||||
|
||||
if not architectures: # well we did not find anything
|
||||
|
@ -66,8 +66,8 @@ class Setup(Handler):
|
||||
Setup.configuration_create_makepkg(args.packager, args.makeflags_jobs, application.repository.paths)
|
||||
Setup.executable_create(application.repository.paths, repository_id)
|
||||
repository_server = f"file://{application.repository.paths.repository}" if args.server is None else args.server
|
||||
Setup.configuration_create_devtools(repository_id, args.from_configuration, args.mirror, args.multilib,
|
||||
repository_server)
|
||||
Setup.configuration_create_devtools(
|
||||
repository_id, args.from_configuration, args.mirror, args.multilib, repository_server)
|
||||
Setup.configuration_create_sudo(application.repository.paths, repository_id)
|
||||
|
||||
application.repository.repo.init()
|
||||
@ -89,10 +89,8 @@ class Setup(Handler):
|
||||
return root / f"{repository_id.name}-{repository_id.architecture}-build"
|
||||
|
||||
@staticmethod
|
||||
def configuration_create_ahriman(
|
||||
args: argparse.Namespace,
|
||||
repository_id: RepositoryId,
|
||||
root: Configuration) -> None:
|
||||
def configuration_create_ahriman(args: argparse.Namespace, repository_id: RepositoryId,
|
||||
root: Configuration) -> None:
|
||||
"""
|
||||
create service specific configuration
|
||||
|
||||
@ -106,7 +104,7 @@ class Setup(Handler):
|
||||
section = Configuration.section_name("build", repository_id.name, repository_id.architecture)
|
||||
build_command = Setup.build_command(root.repository_paths.root, repository_id)
|
||||
configuration.set_option(section, "build_command", str(build_command))
|
||||
configuration.set_option("repository", "name", repository_id.name)
|
||||
configuration.set_option("repository", "name", repository_id.name) # backward compatibility for docker
|
||||
if args.build_as_user is not None:
|
||||
configuration.set_option(section, "makechrootpkg_flags", f"-U {args.build_as_user}")
|
||||
|
||||
|
@ -77,8 +77,7 @@ class Web(Handler):
|
||||
"""
|
||||
# read architecture from the same argument list
|
||||
yield from ["--architecture", repository_id.architecture]
|
||||
if repository_id.name is not None:
|
||||
yield from ["--repository", repository_id.name]
|
||||
yield from ["--repository", repository_id.name]
|
||||
# read configuration path from current settings
|
||||
if (configuration_path := configuration.path) is not None:
|
||||
yield from ["--configuration", str(configuration_path)]
|
||||
|
@ -55,7 +55,7 @@ class Lock(LazyLogging):
|
||||
>>>
|
||||
>>> configuration = Configuration()
|
||||
>>> try:
|
||||
>>> with Lock(args, RepositoryId("x86_64", None), configuration):
|
||||
>>> with Lock(args, RepositoryId("x86_64", "aur-clone"), configuration):
|
||||
>>> perform_actions()
|
||||
>>> except Exception as exception:
|
||||
>>> handle_exceptions(exception)
|
||||
|
@ -50,7 +50,7 @@ class Configuration(configparser.RawConfigParser):
|
||||
|
||||
>>> from pathlib import Path
|
||||
>>>
|
||||
>>> configuration = Configuration.from_path(Path("/etc/ahriman.ini"), RepositoryId("x86_64", None))
|
||||
>>> configuration = Configuration.from_path(Path("/etc/ahriman.ini"), RepositoryId("x86_64", "aur-clone"))
|
||||
>>> repository_name = configuration.get("repository", "name")
|
||||
>>> makepkg_flags = configuration.getlist("build", "makepkg_flags")
|
||||
|
||||
@ -109,6 +109,17 @@ class Configuration(configparser.RawConfigParser):
|
||||
"""
|
||||
return self.getpath("settings", "logging")
|
||||
|
||||
@property
|
||||
def repository_name(self) -> str:
|
||||
"""
|
||||
repository name for backward compatibility
|
||||
|
||||
Returns:
|
||||
str: repository name
|
||||
"""
|
||||
_, repository_id = self.check_loaded()
|
||||
return repository_id.name
|
||||
|
||||
@property
|
||||
def repository_paths(self) -> RepositoryPaths:
|
||||
"""
|
||||
|
@ -183,7 +183,6 @@ CONFIGURATION_SCHEMA: ConfigurationSchema = {
|
||||
"schema": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"required": True,
|
||||
},
|
||||
"root": {
|
||||
"type": "string",
|
||||
|
@ -71,7 +71,18 @@ def migrate_package_remotes(connection: Connection, paths: RepositoryPaths) -> N
|
||||
paths(RepositoryPaths): repository paths instance
|
||||
"""
|
||||
from ahriman.core.alpm.remote import AUR
|
||||
from ahriman.core.database.operations import PackageOperations
|
||||
from ahriman.models.package import Package
|
||||
|
||||
def get_packages() -> dict[str, Package]:
|
||||
return {
|
||||
row["package_base"]: Package(
|
||||
base=row["package_base"],
|
||||
version=row["version"],
|
||||
remote=RemoteSource.from_json(row),
|
||||
packages={},
|
||||
packager=row["packager"] or None,
|
||||
) for row in connection.execute("""select * from package_bases""")
|
||||
}
|
||||
|
||||
def insert_remote(base: str, remote: RemoteSource) -> None:
|
||||
connection.execute(
|
||||
@ -88,8 +99,7 @@ def migrate_package_remotes(connection: Connection, paths: RepositoryPaths) -> N
|
||||
}
|
||||
)
|
||||
|
||||
packages = PackageOperations._packages_get_select_package_bases(connection)
|
||||
for package_base, package in packages.items():
|
||||
for package_base, package in get_packages().items():
|
||||
local_cache = paths.cache_for(package_base)
|
||||
if local_cache.exists() and not package.is_vcs:
|
||||
continue # skip packages which are not VCS and with local cache
|
||||
|
@ -45,9 +45,9 @@ steps = [
|
||||
)
|
||||
""",
|
||||
"""
|
||||
insert into packages select * from packages_ where architecture is not null;
|
||||
insert into packages select * from packages_ where architecture is not null
|
||||
""",
|
||||
"""
|
||||
drop table packages_;
|
||||
drop table packages_
|
||||
""",
|
||||
]
|
||||
|
245
src/ahriman/core/database/migrations/m011_repository_name.py
Normal file
245
src/ahriman/core/database/migrations/m011_repository_name.py
Normal file
@ -0,0 +1,245 @@
|
||||
#
|
||||
# Copyright (c) 2021-2023 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 sqlite3 import Connection
|
||||
|
||||
from ahriman.core.configuration import Configuration
|
||||
|
||||
|
||||
__all__ = ["migrate_data", "steps"]
|
||||
|
||||
|
||||
steps = [
|
||||
# set correct types for schema
|
||||
"""
|
||||
alter table users rename to users_
|
||||
""",
|
||||
"""
|
||||
create table users (
|
||||
username text not null unique,
|
||||
access text not null,
|
||||
password text,
|
||||
packager_id text,
|
||||
key_id text
|
||||
)
|
||||
""",
|
||||
"""
|
||||
insert into users select * from users_
|
||||
""",
|
||||
"""
|
||||
drop table users_
|
||||
""",
|
||||
# update base tables
|
||||
# build_queue
|
||||
"""
|
||||
alter table build_queue add column repository text not null default ''
|
||||
""",
|
||||
"""
|
||||
alter table build_queue rename to build_queue_
|
||||
""",
|
||||
"""
|
||||
create table build_queue (
|
||||
package_base text not null,
|
||||
properties json not null,
|
||||
repository text not null,
|
||||
primary key (package_base, repository)
|
||||
)
|
||||
""",
|
||||
"""
|
||||
insert into build_queue select * from build_queue_
|
||||
""",
|
||||
"""
|
||||
drop table build_queue_
|
||||
""",
|
||||
# package_bases
|
||||
"""
|
||||
alter table package_bases add column repository text not null default ''
|
||||
""",
|
||||
"""
|
||||
alter table package_bases rename to package_bases_
|
||||
""",
|
||||
"""
|
||||
create table package_bases (
|
||||
package_base text not null,
|
||||
version text not null,
|
||||
branch text,
|
||||
git_url text,
|
||||
path text,
|
||||
web_url text,
|
||||
source text,
|
||||
packager text,
|
||||
repository text not null,
|
||||
primary key (package_base, repository)
|
||||
)
|
||||
""",
|
||||
"""
|
||||
insert into package_bases select * from package_bases_
|
||||
""",
|
||||
"""
|
||||
drop table package_bases_
|
||||
""",
|
||||
# package_statuses
|
||||
"""
|
||||
alter table package_statuses add column repository text not null default ''
|
||||
""",
|
||||
"""
|
||||
alter table package_statuses rename to package_statuses_
|
||||
""",
|
||||
"""
|
||||
create table package_statuses (
|
||||
package_base text not null,
|
||||
status text not null,
|
||||
last_updated integer,
|
||||
repository text not null,
|
||||
primary key (package_base, repository)
|
||||
)
|
||||
""",
|
||||
"""
|
||||
insert into package_statuses select * from package_statuses_
|
||||
""",
|
||||
"""
|
||||
drop table package_statuses_
|
||||
""",
|
||||
# packages
|
||||
"""
|
||||
alter table packages add column repository text not null default ''
|
||||
""",
|
||||
"""
|
||||
alter table packages rename to packages_
|
||||
""",
|
||||
"""
|
||||
create table packages (
|
||||
package text not null,
|
||||
package_base text not null,
|
||||
architecture text not null,
|
||||
archive_size integer,
|
||||
build_date integer,
|
||||
depends json,
|
||||
description text,
|
||||
filename text,
|
||||
"groups" json,
|
||||
installed_size integer,
|
||||
licenses json,
|
||||
provides json,
|
||||
url text,
|
||||
make_depends json,
|
||||
opt_depends json,
|
||||
check_depends json,
|
||||
repository text not null,
|
||||
primary key (package, architecture, repository)
|
||||
)
|
||||
""",
|
||||
"""
|
||||
insert into packages select * from packages_
|
||||
""",
|
||||
"""
|
||||
drop table packages_
|
||||
""",
|
||||
# patches
|
||||
"""
|
||||
alter table patches add column repository text not null default ''
|
||||
""",
|
||||
"""
|
||||
drop index patches_package_base_variable
|
||||
""",
|
||||
"""
|
||||
alter table patches rename to patches_
|
||||
""",
|
||||
"""
|
||||
create table patches (
|
||||
package_base text not null,
|
||||
variable text,
|
||||
patch blob not null,
|
||||
repository text not null
|
||||
)
|
||||
""",
|
||||
"""
|
||||
create unique index patches_package_base_variable_repository
|
||||
on patches (package_base, coalesce(variable, ''), repository)
|
||||
""",
|
||||
"""
|
||||
insert into patches select * from patches_
|
||||
""",
|
||||
"""
|
||||
drop table patches_
|
||||
""",
|
||||
# logs
|
||||
"""
|
||||
alter table logs add column repository text not null default ''
|
||||
""",
|
||||
"""
|
||||
drop index logs_package_base_version
|
||||
""",
|
||||
"""
|
||||
alter table logs rename to logs_
|
||||
""",
|
||||
"""
|
||||
create table logs (
|
||||
package_base text not null,
|
||||
created real not null,
|
||||
record text,
|
||||
version text not null,
|
||||
repository text not null
|
||||
)
|
||||
""",
|
||||
"""
|
||||
insert into logs select * from logs_
|
||||
""",
|
||||
"""
|
||||
create index logs_package_base_version on logs (package_base, version)
|
||||
""",
|
||||
"""
|
||||
drop table logs_
|
||||
""",
|
||||
]
|
||||
|
||||
|
||||
def migrate_data(connection: Connection, configuration: Configuration) -> None:
|
||||
"""
|
||||
perform data migration
|
||||
|
||||
Args:
|
||||
connection(Connection): database connection
|
||||
configuration(Configuration): configuration instance
|
||||
"""
|
||||
migrate_package_repository(connection, configuration)
|
||||
|
||||
|
||||
def migrate_package_repository(connection: Connection, configuration: Configuration) -> None:
|
||||
"""
|
||||
update repository name from current settings
|
||||
|
||||
Args:
|
||||
connection(Connection): database connection
|
||||
configuration(Configuration): configuration instance
|
||||
"""
|
||||
_, repository_id = configuration.check_loaded()
|
||||
|
||||
connection.execute("""update build_queue set repository = :repository""",
|
||||
{"repository": repository_id.name, })
|
||||
connection.execute("""update package_bases set repository = :repository""",
|
||||
{"repository": repository_id.name, })
|
||||
connection.execute("""update package_statuses set repository = :repository""",
|
||||
{"repository": repository_id.name, })
|
||||
connection.execute("""update packages set repository = :repository""",
|
||||
{"repository": repository_id.name, })
|
||||
connection.execute("""update patches set repository = :repository""",
|
||||
{"repository": repository_id.name, })
|
||||
connection.execute("""update logs set repository = :repository""",
|
||||
{"repository": repository_id.name, })
|
@ -39,9 +39,9 @@ class BuildOperations(Operations):
|
||||
connection.execute(
|
||||
"""
|
||||
delete from build_queue
|
||||
where :package_base is null or package_base = :package_base
|
||||
where (:package_base is null or package_base = :package_base) and repository = :repository
|
||||
""",
|
||||
{"package_base": package_base})
|
||||
{"package_base": package_base, "repository": self.repository_id.name})
|
||||
|
||||
return self.with_connection(run, commit=True)
|
||||
|
||||
@ -55,7 +55,10 @@ class BuildOperations(Operations):
|
||||
def run(connection: Connection) -> list[Package]:
|
||||
return [
|
||||
Package.from_json(row["properties"])
|
||||
for row in connection.execute("""select * from build_queue""")
|
||||
for row in connection.execute(
|
||||
"""select properties from build_queue where repository = :repository""",
|
||||
{"repository": self.repository_id.name}
|
||||
)
|
||||
]
|
||||
|
||||
return self.with_connection(run)
|
||||
@ -71,12 +74,12 @@ class BuildOperations(Operations):
|
||||
connection.execute(
|
||||
"""
|
||||
insert into build_queue
|
||||
(package_base, properties)
|
||||
(package_base, properties, repository)
|
||||
values
|
||||
(:package_base, :properties)
|
||||
on conflict (package_base) do update set
|
||||
(:package_base, :properties, :repository)
|
||||
on conflict (package_base, repository) do update set
|
||||
properties = :properties
|
||||
""",
|
||||
{"package_base": package.base, "properties": package.view()})
|
||||
{"package_base": package.base, "properties": package.view(), "repository": self.repository_id.name})
|
||||
|
||||
return self.with_connection(run, commit=True)
|
||||
|
@ -44,10 +44,11 @@ class LogsOperations(Operations):
|
||||
f"""[{pretty_datetime(row["created"])}] {row["record"]}"""
|
||||
for row in connection.execute(
|
||||
"""
|
||||
select created, record from logs where package_base = :package_base
|
||||
select created, record from logs
|
||||
where package_base = :package_base and repository = :repository
|
||||
order by created
|
||||
""",
|
||||
{"package_base": package_base})
|
||||
{"package_base": package_base, "repository": self.repository_id.name})
|
||||
]
|
||||
|
||||
records = self.with_connection(run)
|
||||
@ -66,15 +67,16 @@ class LogsOperations(Operations):
|
||||
connection.execute(
|
||||
"""
|
||||
insert into logs
|
||||
(package_base, version, created, record)
|
||||
(package_base, version, created, record, repository)
|
||||
values
|
||||
(:package_base, :version, :created, :record)
|
||||
(:package_base, :version, :created, :record, :repository)
|
||||
""",
|
||||
{
|
||||
"package_base": log_record_id.package_base,
|
||||
"version": log_record_id.version,
|
||||
"created": created,
|
||||
"record": record,
|
||||
"repository": self.repository_id.name,
|
||||
}
|
||||
)
|
||||
|
||||
@ -93,9 +95,10 @@ class LogsOperations(Operations):
|
||||
connection.execute(
|
||||
"""
|
||||
delete from logs
|
||||
where package_base = :package_base and (:version is null or version <> :version)
|
||||
where package_base = :package_base and repository = :repository
|
||||
and (:version is null or version <> :version)
|
||||
""",
|
||||
{"package_base": package_base, "version": version}
|
||||
{"package_base": package_base, "version": version, "repository": self.repository_id.name}
|
||||
)
|
||||
|
||||
return self.with_connection(run, commit=True)
|
||||
|
@ -24,6 +24,7 @@ from pathlib import Path
|
||||
from typing import Any, TypeVar
|
||||
|
||||
from ahriman.core.log import LazyLogging
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
|
||||
|
||||
T = TypeVar("T")
|
||||
@ -35,16 +36,19 @@ class Operations(LazyLogging):
|
||||
|
||||
Attributes:
|
||||
path(Path): path to the database file
|
||||
repository_id(RepositoryId): repository unique identifier to perform implicit filtering
|
||||
"""
|
||||
|
||||
def __init__(self, path: Path) -> None:
|
||||
def __init__(self, path: Path, repository_id: RepositoryId) -> None:
|
||||
"""
|
||||
default constructor
|
||||
|
||||
Args:
|
||||
path(Path): path to the database file
|
||||
repository_id(RepositoryId): repository unique identifier
|
||||
"""
|
||||
self.path = path
|
||||
self.repository_id = repository_id
|
||||
|
||||
@staticmethod
|
||||
def factory(cursor: sqlite3.Cursor, row: tuple[Any, ...]) -> dict[str, Any]:
|
||||
|
@ -32,8 +32,7 @@ class PackageOperations(Operations):
|
||||
package operations
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def _package_remove_package_base(connection: Connection, package_base: str) -> None:
|
||||
def _package_remove_package_base(self, connection: Connection, package_base: str) -> None:
|
||||
"""
|
||||
remove package base information
|
||||
|
||||
@ -41,13 +40,20 @@ class PackageOperations(Operations):
|
||||
connection(Connection): database connection
|
||||
package_base(str): package base name
|
||||
"""
|
||||
connection.execute("""delete from package_statuses where package_base = :package_base""",
|
||||
{"package_base": package_base})
|
||||
connection.execute("""delete from package_bases where package_base = :package_base""",
|
||||
{"package_base": package_base})
|
||||
connection.execute(
|
||||
"""
|
||||
delete from package_statuses
|
||||
where package_base = :package_base and repository = :repository
|
||||
""",
|
||||
{"package_base": package_base, "repository": self.repository_id.name})
|
||||
connection.execute(
|
||||
"""
|
||||
delete from package_bases
|
||||
where package_base = :package_base and repository = :repository""",
|
||||
{"package_base": package_base, "repository": self.repository_id.name})
|
||||
|
||||
@staticmethod
|
||||
def _package_remove_packages(connection: Connection, package_base: str, current_packages: Iterable[str]) -> None:
|
||||
def _package_remove_packages(self, connection: Connection, package_base: str,
|
||||
current_packages: Iterable[str]) -> None:
|
||||
"""
|
||||
remove packages belong to the package base
|
||||
|
||||
@ -59,13 +65,20 @@ class PackageOperations(Operations):
|
||||
packages = [
|
||||
package
|
||||
for package in connection.execute(
|
||||
"""select package from packages where package_base = :package_base""", {"package_base": package_base})
|
||||
"""
|
||||
select package, repository from packages
|
||||
where package_base = :package_base and repository = :repository""",
|
||||
{"package_base": package_base, "repository": self.repository_id.name})
|
||||
if package["package"] not in current_packages
|
||||
]
|
||||
connection.executemany("""delete from packages where package = :package""", packages)
|
||||
connection.executemany(
|
||||
"""
|
||||
delete from packages
|
||||
where package = :package and repository = :repository
|
||||
""",
|
||||
packages)
|
||||
|
||||
@staticmethod
|
||||
def _package_update_insert_base(connection: Connection, package: Package) -> None:
|
||||
def _package_update_insert_base(self, connection: Connection, package: Package) -> None:
|
||||
"""
|
||||
insert base package into table
|
||||
|
||||
@ -76,10 +89,10 @@ class PackageOperations(Operations):
|
||||
connection.execute(
|
||||
"""
|
||||
insert into package_bases
|
||||
(package_base, version, source, branch, git_url, path, web_url, packager)
|
||||
(package_base, version, source, branch, git_url, path, web_url, packager, repository)
|
||||
values
|
||||
(:package_base, :version, :source, :branch, :git_url, :path, :web_url, :packager)
|
||||
on conflict (package_base) do update set
|
||||
(:package_base, :version, :source, :branch, :git_url, :path, :web_url, :packager, :repository)
|
||||
on conflict (package_base, repository) do update set
|
||||
version = :version, branch = :branch, git_url = :git_url, path = :path, web_url = :web_url,
|
||||
source = :source, packager = :packager
|
||||
""",
|
||||
@ -92,11 +105,11 @@ class PackageOperations(Operations):
|
||||
"web_url": package.remote.web_url,
|
||||
"source": package.remote.source.value,
|
||||
"packager": package.packager,
|
||||
"repository": self.repository_id.name,
|
||||
}
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _package_update_insert_packages(connection: Connection, package: Package) -> None:
|
||||
def _package_update_insert_packages(self, connection: Connection, package: Package) -> None:
|
||||
"""
|
||||
insert packages into table
|
||||
|
||||
@ -108,20 +121,27 @@ class PackageOperations(Operations):
|
||||
for name, description in package.packages.items():
|
||||
if description.architecture is None:
|
||||
continue # architecture is required
|
||||
package_list.append({"package": name, "package_base": package.base, **description.view()})
|
||||
package_list.append({
|
||||
"package": name,
|
||||
"package_base": package.base,
|
||||
"repository": self.repository_id.name,
|
||||
**description.view(),
|
||||
})
|
||||
connection.executemany(
|
||||
"""
|
||||
insert into packages
|
||||
(package, package_base, architecture, archive_size,
|
||||
build_date, depends, description, filename,
|
||||
"groups", installed_size, licenses, provides,
|
||||
url, make_depends, opt_depends, check_depends)
|
||||
url, make_depends, opt_depends, check_depends,
|
||||
repository)
|
||||
values
|
||||
(:package, :package_base, :architecture, :archive_size,
|
||||
:build_date, :depends, :description, :filename,
|
||||
:groups, :installed_size, :licenses, :provides,
|
||||
:url, :make_depends, :opt_depends, :check_depends)
|
||||
on conflict (package, architecture) do update set
|
||||
:url, :make_depends, :opt_depends, :check_depends,
|
||||
:repository)
|
||||
on conflict (package, architecture, repository) do update set
|
||||
package_base = :package_base, archive_size = :archive_size,
|
||||
build_date = :build_date, depends = :depends, description = :description, filename = :filename,
|
||||
"groups" = :groups, installed_size = :installed_size, licenses = :licenses, provides = :provides,
|
||||
@ -129,8 +149,7 @@ class PackageOperations(Operations):
|
||||
""",
|
||||
package_list)
|
||||
|
||||
@staticmethod
|
||||
def _package_update_insert_status(connection: Connection, package_base: str, status: BuildStatus) -> None:
|
||||
def _package_update_insert_status(self, connection: Connection, package_base: str, status: BuildStatus) -> None:
|
||||
"""
|
||||
insert base package status into table
|
||||
|
||||
@ -141,16 +160,21 @@ class PackageOperations(Operations):
|
||||
"""
|
||||
connection.execute(
|
||||
"""
|
||||
insert into package_statuses (package_base, status, last_updated)
|
||||
insert into package_statuses
|
||||
(package_base, status, last_updated, repository)
|
||||
values
|
||||
(:package_base, :status, :last_updated)
|
||||
on conflict (package_base) do update set
|
||||
(:package_base, :status, :last_updated, :repository)
|
||||
on conflict (package_base, repository) do update set
|
||||
status = :status, last_updated = :last_updated
|
||||
""",
|
||||
{"package_base": package_base, "status": status.status.value, "last_updated": status.timestamp})
|
||||
{
|
||||
"package_base": package_base,
|
||||
"status": status.status.value,
|
||||
"last_updated": status.timestamp,
|
||||
"repository": self.repository_id.name,
|
||||
})
|
||||
|
||||
@staticmethod
|
||||
def _packages_get_select_package_bases(connection: Connection) -> dict[str, Package]:
|
||||
def _packages_get_select_package_bases(self, connection: Connection) -> dict[str, Package]:
|
||||
"""
|
||||
select package bases from the table
|
||||
|
||||
@ -167,11 +191,13 @@ class PackageOperations(Operations):
|
||||
remote=RemoteSource.from_json(row),
|
||||
packages={},
|
||||
packager=row["packager"] or None,
|
||||
) for row in connection.execute("""select * from package_bases""")
|
||||
) for row in connection.execute(
|
||||
"""select * from package_bases where repository = :repository""",
|
||||
{"repository": self.repository_id.name}
|
||||
)
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _packages_get_select_packages(connection: Connection, packages: dict[str, Package]) -> dict[str, Package]:
|
||||
def _packages_get_select_packages(self, connection: Connection, packages: dict[str, Package]) -> dict[str, Package]:
|
||||
"""
|
||||
select packages from the table
|
||||
|
||||
@ -182,14 +208,15 @@ class PackageOperations(Operations):
|
||||
Returns:
|
||||
dict[str, Package]: map of the package base to its descriptor including individual packages
|
||||
"""
|
||||
for row in connection.execute("""select * from packages"""):
|
||||
for row in connection.execute(
|
||||
"""select * from packages where repository = :repository""",
|
||||
{"repository": self.repository_id.name}):
|
||||
if row["package_base"] not in packages:
|
||||
continue # normally must never happen though
|
||||
packages[row["package_base"]].packages[row["package"]] = PackageDescription.from_json(row)
|
||||
return packages
|
||||
|
||||
@staticmethod
|
||||
def _packages_get_select_statuses(connection: Connection) -> dict[str, BuildStatus]:
|
||||
def _packages_get_select_statuses(self, connection: Connection) -> dict[str, BuildStatus]:
|
||||
"""
|
||||
select package build statuses from the table
|
||||
|
||||
@ -201,7 +228,10 @@ class PackageOperations(Operations):
|
||||
"""
|
||||
return {
|
||||
row["package_base"]: BuildStatus.from_json({"status": row["status"], "timestamp": row["last_updated"]})
|
||||
for row in connection.execute("""select * from package_statuses""")
|
||||
for row in connection.execute(
|
||||
"""select * from package_statuses where repository = :repository""",
|
||||
{"repository": self.repository_id.name}
|
||||
)
|
||||
}
|
||||
|
||||
def package_remove(self, package_base: str) -> None:
|
||||
|
@ -54,13 +54,19 @@ class PatchOperations(Operations):
|
||||
connection.execute(
|
||||
"""
|
||||
insert into patches
|
||||
(package_base, variable, patch)
|
||||
(package_base, variable, patch, repository)
|
||||
values
|
||||
(:package_base, :variable, :patch)
|
||||
on conflict (package_base, coalesce(variable, '')) do update set
|
||||
(:package_base, :variable, :patch, :repository)
|
||||
on conflict (package_base, coalesce(variable, ''), repository) do update set
|
||||
patch = :patch
|
||||
""",
|
||||
{"package_base": package_base, "variable": patch.key, "patch": patch.value})
|
||||
{
|
||||
"package_base": package_base,
|
||||
"variable": patch.key,
|
||||
"patch": patch.value,
|
||||
"repository": self.repository_id.name,
|
||||
}
|
||||
)
|
||||
|
||||
return self.with_connection(run, commit=True)
|
||||
|
||||
@ -79,8 +85,10 @@ class PatchOperations(Operations):
|
||||
return [
|
||||
(row["package_base"], PkgbuildPatch(row["variable"], row["patch"]))
|
||||
for row in connection.execute(
|
||||
"""select * from patches where :package_base is null or package_base = :package_base""",
|
||||
{"package_base": package_base})
|
||||
"""
|
||||
select * from patches
|
||||
where (:package_base is null or package_base = :package_base) and repository = :repository""",
|
||||
{"package_base": package_base, "repository": self.repository_id.name})
|
||||
]
|
||||
|
||||
# we could use itertools & operator but why?
|
||||
@ -101,13 +109,23 @@ class PatchOperations(Operations):
|
||||
"""
|
||||
def run_many(connection: Connection) -> None:
|
||||
connection.executemany(
|
||||
"""delete from patches where package_base = :package_base and variable = :variable""",
|
||||
[{"package_base": package_base, "variable": variable} for variable in variables])
|
||||
"""
|
||||
delete from patches
|
||||
where package_base = :package_base and variable = :variable and repository = :repository
|
||||
""",
|
||||
[
|
||||
{
|
||||
"package_base": package_base,
|
||||
"variable": variable,
|
||||
"repository": self.repository_id.name,
|
||||
} for variable in variables
|
||||
]
|
||||
)
|
||||
|
||||
def run(connection: Connection) -> None:
|
||||
connection.execute(
|
||||
"""delete from patches where package_base = :package_base""",
|
||||
{"package_base": package_base})
|
||||
"""delete from patches where package_base = :package_base and repository = :repository""",
|
||||
{"package_base": package_base, "repository": self.repository_id.name})
|
||||
|
||||
if variables:
|
||||
return self.with_connection(run_many, commit=True)
|
||||
|
@ -56,8 +56,11 @@ class SQLite(AuthOperations, BuildOperations, LogsOperations, PackageOperations,
|
||||
Self: fully initialized instance of the database
|
||||
"""
|
||||
path = cls.database_path(configuration)
|
||||
database = cls(path)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
|
||||
database = cls(path, repository_id)
|
||||
database.init(configuration)
|
||||
|
||||
return database
|
||||
|
||||
@staticmethod
|
||||
|
@ -41,14 +41,14 @@ class SyncHttpClient(LazyLogging):
|
||||
timeout(int): HTTP request timeout in seconds
|
||||
"""
|
||||
|
||||
def __init__(self, section: str | None = None, configuration: Configuration | None = None, *,
|
||||
def __init__(self, configuration: Configuration | None = None, section: str | None = None, *,
|
||||
suppress_errors: bool = False) -> None:
|
||||
"""
|
||||
default constructor
|
||||
|
||||
Args:
|
||||
section(str, optional): settings section name (Default value = None)
|
||||
configuration(Configuration | None): configuration instance (Default value = None)
|
||||
section(str, optional): settings section name (Default value = None)
|
||||
suppress_errors(bool, optional): suppress logging of request errors (Default value = False)
|
||||
"""
|
||||
if configuration is None:
|
||||
|
@ -18,4 +18,3 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from ahriman.core.log.lazy_logging import LazyLogging
|
||||
from ahriman.core.log.log import Log
|
||||
|
@ -27,7 +27,7 @@ from ahriman.core.log.http_log_handler import HttpLogHandler
|
||||
from ahriman.models.log_handler import LogHandler
|
||||
|
||||
|
||||
class Log:
|
||||
class LogLoader:
|
||||
"""
|
||||
simple static method class which setups application loggers
|
||||
|
||||
@ -63,7 +63,7 @@ class Log:
|
||||
del JournalHandler
|
||||
return LogHandler.Journald # journald import was found
|
||||
except ImportError:
|
||||
if Log.DEFAULT_SYSLOG_DEVICE.exists():
|
||||
if LogLoader.DEFAULT_SYSLOG_DEVICE.exists():
|
||||
return LogHandler.Syslog
|
||||
return LogHandler.Console
|
||||
|
||||
@ -94,8 +94,7 @@ class Log:
|
||||
fileConfig(log_configuration, disable_existing_loggers=True)
|
||||
logging.debug("using %s logger", default_handler)
|
||||
except Exception:
|
||||
logging.basicConfig(filename=None, format=Log.DEFAULT_LOG_FORMAT,
|
||||
level=Log.DEFAULT_LOG_LEVEL)
|
||||
logging.basicConfig(filename=None, format=LogLoader.DEFAULT_LOG_FORMAT, level=LogLoader.DEFAULT_LOG_LEVEL)
|
||||
logging.exception("could not load logging from configuration, fallback to stderr")
|
||||
|
||||
HttpLogHandler.load(configuration, report=report)
|
@ -41,7 +41,7 @@ class Report(LazyLogging):
|
||||
method ``load`` which can be used in order to determine right report instance::
|
||||
|
||||
>>> configuration = Configuration()
|
||||
>>> report = Report.load(RepositoryId("x86_64", None), configuration, "email")
|
||||
>>> report = Report.load(RepositoryId("x86_64", "aur-clone"), configuration, "email")
|
||||
|
||||
The ``generate`` method can be used in order to perform the report itself, whereas ``run`` method handles
|
||||
exception and raises ``ReportFailed`` instead::
|
||||
|
@ -53,7 +53,7 @@ class Telegram(Report, JinjaTemplate, SyncHttpClient):
|
||||
"""
|
||||
Report.__init__(self, repository_id, configuration)
|
||||
JinjaTemplate.__init__(self, repository_id, configuration, section)
|
||||
SyncHttpClient.__init__(self, section, configuration)
|
||||
SyncHttpClient.__init__(self, configuration, section)
|
||||
|
||||
self.api_key = configuration.get(section, "api_key")
|
||||
self.chat_id = configuration.get(section, "chat_id")
|
||||
|
@ -48,7 +48,7 @@ class Repository(Executor, UpdateHandler):
|
||||
>>>
|
||||
>>> configuration = Configuration()
|
||||
>>> database = SQLite.load(configuration)
|
||||
>>> repository = Repository.load(RepositoryId("x86_64", None), configuration, database, report=True)
|
||||
>>> repository = Repository.load(RepositoryId("x86_64", "x86_64"), configuration, database, report=True)
|
||||
>>> known_packages = repository.packages()
|
||||
>>>
|
||||
>>> build_result = repository.process_build(known_packages)
|
||||
|
@ -51,7 +51,7 @@ class WebClient(Client, SyncHttpClient):
|
||||
configuration(Configuration): configuration instance
|
||||
"""
|
||||
suppress_errors = configuration.getboolean("settings", "suppress_http_log_errors", fallback=False)
|
||||
SyncHttpClient.__init__(self, "web", configuration, suppress_errors=suppress_errors)
|
||||
SyncHttpClient.__init__(self, configuration, "web", suppress_errors=suppress_errors)
|
||||
|
||||
self.address, self.use_unix_socket = self.parse_address(configuration)
|
||||
|
||||
|
@ -106,7 +106,7 @@ class Tree:
|
||||
>>>
|
||||
>>> configuration = Configuration()
|
||||
>>> database = SQLite.load(configuration)
|
||||
>>> repository = Repository.load(RepositoryId("x86_64", None), configuration, database, report=True)
|
||||
>>> repository = Repository.load(RepositoryId("x86_64", "aur-clone"), configuration, database, report=True)
|
||||
>>> packages = repository.packages()
|
||||
>>>
|
||||
>>> tree = Tree.resolve(packages)
|
||||
|
@ -52,7 +52,7 @@ class Trigger(LazyLogging):
|
||||
>>> configuration = Configuration()
|
||||
>>> configuration.set_option("build", "triggers", "my.awesome.package.CustomTrigger")
|
||||
>>>
|
||||
>>> loader = TriggerLoader.load(RepositoryId("x86_64", None), configuration)
|
||||
>>> loader = TriggerLoader.load(RepositoryId("x86_64", "aur-clone"), configuration)
|
||||
>>> loader.on_result(Result(), [])
|
||||
"""
|
||||
|
||||
@ -70,6 +70,16 @@ class Trigger(LazyLogging):
|
||||
self.repository_id = repository_id
|
||||
self.configuration = configuration
|
||||
|
||||
@property
|
||||
def architecture(self) -> str:
|
||||
"""
|
||||
repository architecture for backward compatibility
|
||||
|
||||
Returns:
|
||||
str: repository architecture
|
||||
"""
|
||||
return self.repository_id.architecture
|
||||
|
||||
@classmethod
|
||||
def configuration_schema(cls, repository_id: RepositoryId,
|
||||
configuration: Configuration | None) -> ConfigurationSchema:
|
||||
|
@ -50,7 +50,7 @@ class TriggerLoader(LazyLogging):
|
||||
|
||||
Having such configuration you can create instance of the loader::
|
||||
|
||||
>>> loader = TriggerLoader.load(RepositoryId("x86_64", None), configuration)
|
||||
>>> loader = TriggerLoader.load(RepositoryId("x86_64", "aur-clone"), configuration)
|
||||
>>> print(loader.triggers)
|
||||
|
||||
After that you are free to run triggers::
|
||||
|
@ -31,7 +31,7 @@ from ahriman.models.package import Package
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
|
||||
|
||||
class Github(Upload, HttpUpload):
|
||||
class GitHub(Upload, HttpUpload):
|
||||
"""
|
||||
upload files to GitHub releases
|
||||
|
||||
@ -52,12 +52,12 @@ class Github(Upload, HttpUpload):
|
||||
section(str): settings section name
|
||||
"""
|
||||
Upload.__init__(self, repository_id, configuration)
|
||||
HttpUpload.__init__(self, section, configuration)
|
||||
HttpUpload.__init__(self, configuration, section)
|
||||
|
||||
self.github_owner = configuration.get(section, "owner")
|
||||
self.github_repository = configuration.get(section, "repository")
|
||||
|
||||
if repository_id.name is not None:
|
||||
if configuration.getboolean(section, "use_full_release_name", fallback=False):
|
||||
self.github_release_tag = f"{repository_id.name}-{repository_id.architecture}"
|
||||
self.github_release_tag_name = f"{repository_id.name} {repository_id.architecture}"
|
||||
else:
|
||||
|
@ -50,7 +50,7 @@ class RemoteService(Upload, HttpUpload):
|
||||
section(str): settings section name
|
||||
"""
|
||||
Upload.__init__(self, repository_id, configuration)
|
||||
HttpUpload.__init__(self, section, configuration)
|
||||
HttpUpload.__init__(self, configuration, section)
|
||||
self.client = WebClient(configuration)
|
||||
|
||||
@cached_property
|
||||
|
@ -43,7 +43,7 @@ class Upload(LazyLogging):
|
||||
wraps any internal exceptions into the ``SyncFailed`` exception::
|
||||
|
||||
>>> configuration = Configuration()
|
||||
>>> upload = Upload.load(RepositoryId("x86_64", None), configuration, "s3")
|
||||
>>> upload = Upload.load(RepositoryId("x86_64", "aur-clone"), configuration, "s3")
|
||||
>>> upload.run(configuration.repository_paths.repository, [])
|
||||
|
||||
Or in case if direct access to exception is required, the ``sync`` method can be used::
|
||||
@ -87,8 +87,8 @@ class Upload(LazyLogging):
|
||||
from ahriman.core.upload.s3 import S3
|
||||
return S3(repository_id, configuration, section)
|
||||
case UploadSettings.GitHub:
|
||||
from ahriman.core.upload.github import Github
|
||||
return Github(repository_id, configuration, section)
|
||||
from ahriman.core.upload.github import GitHub
|
||||
return GitHub(repository_id, configuration, section)
|
||||
case UploadSettings.RemoteService:
|
||||
from ahriman.core.upload.remote_service import RemoteService
|
||||
return RemoteService(repository_id, configuration, section)
|
||||
|
@ -68,6 +68,10 @@ class UploadTrigger(Trigger):
|
||||
"coerce": "integer",
|
||||
"min": 0,
|
||||
},
|
||||
"use_full_release_name": {
|
||||
"type": "boolean",
|
||||
"coerce": "boolean",
|
||||
},
|
||||
"username": {
|
||||
"type": "string",
|
||||
},
|
||||
|
@ -71,7 +71,7 @@ class AURPackage:
|
||||
>>> from ahriman.models.repository_id import RepositoryId
|
||||
>>>
|
||||
>>> configuration = Configuration()
|
||||
>>> pacman = Pacman(RepositoryId("x86_64", None), configuration)
|
||||
>>> pacman = Pacman(RepositoryId("x86_64", "aur-clone"), configuration)
|
||||
>>> metadata = pacman.package_get("pacman")
|
||||
>>> package = AURPackage.from_pacman(next(metadata)) # load package from pyalpm wrapper
|
||||
"""
|
||||
|
@ -59,7 +59,7 @@ class PackageDescription:
|
||||
>>> from ahriman.models.repository_id import RepositoryId
|
||||
>>>
|
||||
>>> configuration = Configuration()
|
||||
>>> pacman = Pacman(RepositoryId("x86_64", None), configuration)
|
||||
>>> pacman = Pacman(RepositoryId("x86_64", "aur-clone"), configuration)
|
||||
>>> pyalpm_description = next(package for package in pacman.package_get("pacman"))
|
||||
>>> description = PackageDescription.from_package(
|
||||
>>> pyalpm_description, Path("/var/cache/pacman/pkg/pacman-6.0.1-4-x86_64.pkg.tar.zst"))
|
||||
|
@ -21,15 +21,17 @@ import os
|
||||
import shutil
|
||||
|
||||
from collections.abc import Generator
|
||||
from dataclasses import dataclass, field
|
||||
from dataclasses import dataclass
|
||||
from functools import cached_property
|
||||
from pathlib import Path
|
||||
|
||||
from ahriman.core.exceptions import PathError
|
||||
from ahriman.core.log import LazyLogging
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class RepositoryPaths:
|
||||
class RepositoryPaths(LazyLogging):
|
||||
"""
|
||||
repository paths holder. For the most operations with paths you want to use this object
|
||||
|
||||
@ -40,7 +42,7 @@ class RepositoryPaths:
|
||||
Examples:
|
||||
This class can be used in order to access the repository tree structure::
|
||||
|
||||
>>> paths = RepositoryPaths(Path("/var/lib/ahriman"), RepositoryId("x86_64", None))
|
||||
>>> paths = RepositoryPaths(Path("/var/lib/ahriman"), RepositoryId("x86_64", "aur-clone"))
|
||||
|
||||
Additional methods can be used in order to ensure that tree is created::
|
||||
|
||||
@ -54,18 +56,20 @@ class RepositoryPaths:
|
||||
|
||||
root: Path
|
||||
repository_id: RepositoryId
|
||||
_suffix: Path = field(init=False)
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
@cached_property
|
||||
def _suffix(self) -> Path:
|
||||
"""
|
||||
load suffix for different modes (legacy or not
|
||||
suffix of the paths as defined by repository structure
|
||||
|
||||
Returns:
|
||||
Path: relative path which contains only architecture segment in case if legacy tree is used and repository
|
||||
name and architecture otherwise
|
||||
"""
|
||||
if self.repository.parent.with_name(self.repository_id.architecture).exists():
|
||||
# there is created legacy tree
|
||||
_suffix = Path(self.repository_id.architecture)
|
||||
else:
|
||||
_suffix = Path(self.repository_id.name) / self.repository_id.architecture
|
||||
object.__setattr__(self, "_suffix", _suffix)
|
||||
if (self.root / "repository" / self.repository_id.architecture).is_dir():
|
||||
self.logger.warning("legacy single repository tree has been found")
|
||||
return Path(self.repository_id.architecture)
|
||||
return Path(self.repository_id.name) / self.repository_id.architecture
|
||||
|
||||
@property
|
||||
def cache(self) -> Path:
|
||||
|
@ -27,7 +27,8 @@ def application_packages(configuration: Configuration, database: SQLite, reposit
|
||||
"""
|
||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||
mocker.patch("ahriman.core.database.SQLite.load", return_value=database)
|
||||
return ApplicationPackages("x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
return ApplicationPackages(repository_id, configuration, report=False)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@ -47,7 +48,8 @@ def application_properties(configuration: Configuration, database: SQLite, repos
|
||||
"""
|
||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||
mocker.patch("ahriman.core.database.SQLite.load", return_value=database)
|
||||
return ApplicationProperties("x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
return ApplicationProperties(repository_id, configuration, report=False)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@ -67,4 +69,5 @@ def application_repository(configuration: Configuration, database: SQLite, repos
|
||||
"""
|
||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||
mocker.patch("ahriman.core.database.SQLite.load", return_value=database)
|
||||
return ApplicationRepository("x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
return ApplicationRepository(repository_id, configuration, report=False)
|
||||
|
@ -6,3 +6,10 @@ def test_create_tree(application_properties: ApplicationProperties) -> None:
|
||||
must have repository attribute
|
||||
"""
|
||||
assert application_properties.repository
|
||||
|
||||
|
||||
def test_architecture(application_properties: ApplicationProperties) -> None:
|
||||
"""
|
||||
must return repository architecture
|
||||
"""
|
||||
assert application_properties.architecture == application_properties.repository_id.architecture
|
||||
|
@ -28,7 +28,8 @@ def application(configuration: Configuration, repository: Repository, database:
|
||||
"""
|
||||
mocker.patch("ahriman.core.database.SQLite.load", return_value=database)
|
||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||
return Application("x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
return Application(repository_id, configuration, report=False)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@ -54,7 +55,8 @@ def lock(args: argparse.Namespace, configuration: Configuration) -> Lock:
|
||||
Returns:
|
||||
Lock: file lock test instance
|
||||
"""
|
||||
return Lock(args, "x86_64", configuration)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
return Lock(args, repository_id, configuration)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
@ -8,48 +8,7 @@ from ahriman.application.handlers import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.exceptions import ExitCode, MissingArchitectureError, MultipleArchitecturesError
|
||||
from ahriman.models.log_handler import LogHandler
|
||||
|
||||
|
||||
def test_architectures_extract(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must generate list of available architectures
|
||||
"""
|
||||
args.configuration = configuration.path
|
||||
known_architectures_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.known_architectures")
|
||||
|
||||
Handler.architectures_extract(args)
|
||||
known_architectures_mock.assert_called_once_with(configuration.getpath("repository", "root"))
|
||||
|
||||
|
||||
def test_architectures_extract_empty(args: argparse.Namespace, configuration: Configuration,
|
||||
mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must raise exception if no available architectures found
|
||||
"""
|
||||
args.command = "config"
|
||||
args.configuration = configuration.path
|
||||
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.known_architectures", return_value=set())
|
||||
|
||||
with pytest.raises(MissingArchitectureError):
|
||||
Handler.architectures_extract(args)
|
||||
|
||||
|
||||
def test_architectures_extract_exception(args: argparse.Namespace, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must raise exception on missing architectures
|
||||
"""
|
||||
args.command = "config"
|
||||
mocker.patch.object(Handler, "ALLOW_AUTO_ARCHITECTURE_RUN", False)
|
||||
with pytest.raises(MissingArchitectureError):
|
||||
Handler.architectures_extract(args)
|
||||
|
||||
|
||||
def test_architectures_extract_specified(args: argparse.Namespace) -> None:
|
||||
"""
|
||||
must return architecture list if it has been specified
|
||||
"""
|
||||
architectures = args.architecture = ["i686", "x86_64"]
|
||||
assert Handler.architectures_extract(args) == sorted(set(architectures))
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
|
||||
|
||||
def test_call(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None:
|
||||
@ -62,20 +21,21 @@ def test_call(args: argparse.Namespace, configuration: Configuration, mocker: Mo
|
||||
args.report = False
|
||||
mocker.patch("ahriman.application.handlers.Handler.run")
|
||||
configuration_mock = mocker.patch("ahriman.core.configuration.Configuration.from_path", return_value=configuration)
|
||||
log_handler_mock = mocker.patch("ahriman.core.log.Log.handler", return_value=args.log_handler)
|
||||
log_load_mock = mocker.patch("ahriman.core.log.Log.load")
|
||||
log_handler_mock = mocker.patch("ahriman.core.log.log_loader.LogLoader.handler", return_value=args.log_handler)
|
||||
log_load_mock = mocker.patch("ahriman.core.log.log_loader.LogLoader.load")
|
||||
enter_mock = mocker.patch("ahriman.application.lock.Lock.__enter__")
|
||||
exit_mock = mocker.patch("ahriman.application.lock.Lock.__exit__")
|
||||
|
||||
assert Handler.call(args, "x86_64")
|
||||
configuration_mock.assert_called_once_with(args.configuration, "x86_64")
|
||||
_, repository_id = configuration.check_loaded()
|
||||
assert Handler.call(args, repository_id)
|
||||
configuration_mock.assert_called_once_with(args.configuration, repository_id)
|
||||
log_handler_mock.assert_called_once_with(args.log_handler)
|
||||
log_load_mock.assert_called_once_with(configuration, args.log_handler, quiet=args.quiet, report=args.report)
|
||||
enter_mock.assert_called_once_with()
|
||||
exit_mock.assert_called_once_with(None, None, None)
|
||||
|
||||
|
||||
def test_call_exception(args: argparse.Namespace, mocker: MockerFixture) -> None:
|
||||
def test_call_exception(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must process exception
|
||||
"""
|
||||
@ -84,11 +44,12 @@ def test_call_exception(args: argparse.Namespace, mocker: MockerFixture) -> None
|
||||
mocker.patch("ahriman.core.configuration.Configuration.from_path", side_effect=Exception())
|
||||
logging_mock = mocker.patch("logging.Logger.exception")
|
||||
|
||||
assert not Handler.call(args, "x86_64")
|
||||
_, repository_id = configuration.check_loaded()
|
||||
assert not Handler.call(args, repository_id)
|
||||
logging_mock.assert_called_once_with(pytest.helpers.anyvar(str, strict=True))
|
||||
|
||||
|
||||
def test_call_exit_code(args: argparse.Namespace, mocker: MockerFixture) -> None:
|
||||
def test_call_exit_code(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must process exitcode exception
|
||||
"""
|
||||
@ -97,7 +58,8 @@ def test_call_exit_code(args: argparse.Namespace, mocker: MockerFixture) -> None
|
||||
mocker.patch("ahriman.core.configuration.Configuration.from_path", side_effect=ExitCode())
|
||||
logging_mock = mocker.patch("logging.Logger.exception")
|
||||
|
||||
assert not Handler.call(args, "x86_64")
|
||||
_, repository_id = configuration.check_loaded()
|
||||
assert not Handler.call(args, repository_id)
|
||||
logging_mock.assert_not_called()
|
||||
|
||||
|
||||
@ -105,33 +67,39 @@ def test_execute(args: argparse.Namespace, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must run execution in multiple processes
|
||||
"""
|
||||
args.architecture = ["i686", "x86_64"]
|
||||
ids = [
|
||||
RepositoryId("i686", "aur-clone"),
|
||||
RepositoryId("x86_64", "aur-clone"),
|
||||
]
|
||||
mocker.patch("ahriman.application.handlers.Handler.repositories_extract", return_value=ids)
|
||||
starmap_mock = mocker.patch("multiprocessing.pool.Pool.starmap")
|
||||
|
||||
Handler.execute(args)
|
||||
starmap_mock.assert_called_once_with(Handler.call, [(args, architecture) for architecture in args.architecture])
|
||||
starmap_mock.assert_called_once_with(Handler.call, [(args, repository_id) for repository_id in ids])
|
||||
|
||||
|
||||
def test_execute_multiple_not_supported(args: argparse.Namespace, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must raise an exception if multiple architectures are not supported by the handler
|
||||
"""
|
||||
args.architecture = ["i686", "x86_64"]
|
||||
args.command = "web"
|
||||
mocker.patch("ahriman.application.handlers.Handler.repositories_extract", return_value=[
|
||||
RepositoryId("i686", "aur-clone"),
|
||||
RepositoryId("x86_64", "aur-clone"),
|
||||
])
|
||||
mocker.patch.object(Handler, "ALLOW_MULTI_ARCHITECTURE_RUN", False)
|
||||
|
||||
with pytest.raises(MultipleArchitecturesError):
|
||||
Handler.execute(args)
|
||||
|
||||
|
||||
def test_execute_single(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None:
|
||||
def test_execute_single(args: argparse.Namespace, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must run execution in current process if only one architecture supplied
|
||||
"""
|
||||
args.architecture = ["x86_64"]
|
||||
args.configuration = Path("")
|
||||
args.quiet = False
|
||||
mocker.patch("ahriman.core.configuration.Configuration.from_path", return_value=configuration)
|
||||
mocker.patch("ahriman.application.handlers.Handler.repositories_extract", return_value=[
|
||||
RepositoryId("x86_64", "aur-clone"),
|
||||
])
|
||||
starmap_mock = mocker.patch("multiprocessing.pool.Pool.starmap")
|
||||
|
||||
Handler.execute(args)
|
||||
@ -142,8 +110,73 @@ def test_run(args: argparse.Namespace, configuration: Configuration) -> None:
|
||||
"""
|
||||
must raise NotImplemented for missing method
|
||||
"""
|
||||
_, repository_id = configuration.check_loaded()
|
||||
with pytest.raises(NotImplementedError):
|
||||
Handler.run(args, "x86_64", configuration, report=True)
|
||||
Handler.run(args, repository_id, configuration, report=True)
|
||||
|
||||
|
||||
def test_repositories_extract(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must generate list of available architectures
|
||||
"""
|
||||
args.configuration = configuration.path
|
||||
_, repository_id = configuration.check_loaded()
|
||||
known_architectures_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.known_architectures")
|
||||
|
||||
Handler.repositories_extract(args)
|
||||
known_architectures_mock.assert_called_once_with(configuration.getpath("repository", "root"), repository_id.name)
|
||||
|
||||
|
||||
def test_repositories_extract_empty(args: argparse.Namespace, configuration: Configuration,
|
||||
mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must raise exception if no available architectures found
|
||||
"""
|
||||
args.command = "config"
|
||||
args.configuration = configuration.path
|
||||
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.known_architectures", return_value=set())
|
||||
|
||||
with pytest.raises(MissingArchitectureError):
|
||||
Handler.repositories_extract(args)
|
||||
|
||||
|
||||
def test_repositories_extract_exception(args: argparse.Namespace, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must raise exception on missing architectures
|
||||
"""
|
||||
args.command = "config"
|
||||
mocker.patch.object(Handler, "ALLOW_AUTO_ARCHITECTURE_RUN", False)
|
||||
with pytest.raises(MissingArchitectureError):
|
||||
Handler.repositories_extract(args)
|
||||
|
||||
|
||||
def test_repositories_extract_specified(args: argparse.Namespace, configuration: Configuration) -> None:
|
||||
"""
|
||||
must return architecture list if it has been specified
|
||||
"""
|
||||
args.configuration = configuration.path
|
||||
args.architecture = ["i686", "x86_64"]
|
||||
args.repository = []
|
||||
_, repository_id = configuration.check_loaded()
|
||||
|
||||
ids = [RepositoryId(architecture, repository_id.name) for architecture in args.architecture]
|
||||
assert Handler.repositories_extract(args) == sorted(set(ids))
|
||||
|
||||
|
||||
def test_repositories_extract_specified_with_repository(args: argparse.Namespace, configuration: Configuration) -> None:
|
||||
"""
|
||||
must return architecture list if it has been specified together with repositories
|
||||
"""
|
||||
args.configuration = configuration.path
|
||||
args.architecture = ["i686", "x86_64"]
|
||||
args.repository = ["repo1", "repo2"]
|
||||
|
||||
ids = [
|
||||
RepositoryId(architecture, name)
|
||||
for architecture in args.architecture
|
||||
for name in args.repository
|
||||
]
|
||||
assert Handler.repositories_extract(args) == sorted(set(ids))
|
||||
|
||||
|
||||
def test_check_if_empty() -> None:
|
||||
|
@ -44,7 +44,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
|
||||
dependencies_mock = mocker.patch("ahriman.application.application.Application.with_dependencies")
|
||||
on_start_mock = mocker.patch("ahriman.application.application.Application.on_start")
|
||||
|
||||
Add.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Add.run(args, repository_id, configuration, report=False)
|
||||
application_mock.assert_called_once_with(args.package, args.source, args.username)
|
||||
dependencies_mock.assert_not_called()
|
||||
on_start_mock.assert_called_once_with()
|
||||
@ -68,7 +69,8 @@ def test_run_with_updates(args: argparse.Namespace, configuration: Configuration
|
||||
return_value=[package_ahriman])
|
||||
print_mock = mocker.patch("ahriman.application.application.Application.print_updates")
|
||||
|
||||
Add.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Add.run(args, repository_id, configuration, report=False)
|
||||
updates_mock.assert_called_once_with(args.package, aur=False, local=False, manual=True, vcs=False)
|
||||
application_mock.assert_called_once_with([package_ahriman],
|
||||
Packagers(args.username, {package_ahriman.base: "packager"}),
|
||||
@ -94,5 +96,6 @@ def test_run_empty_exception(args: argparse.Namespace, configuration: Configurat
|
||||
mocker.patch("ahriman.application.application.Application.print_updates")
|
||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty")
|
||||
|
||||
Add.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Add.run(args, repository_id, configuration, report=False)
|
||||
check_mock.assert_called_once_with(True, True)
|
||||
|
@ -33,7 +33,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
|
||||
add_mock = tarfile.__enter__.return_value = MagicMock()
|
||||
mocker.patch("tarfile.TarFile.__new__", return_value=tarfile)
|
||||
|
||||
Backup.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Backup.run(args, repository_id, configuration, report=False)
|
||||
add_mock.add.assert_called_once_with(Path("path"))
|
||||
|
||||
|
||||
|
@ -35,6 +35,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
|
||||
application_mock = mocker.patch("ahriman.application.application.Application.clean")
|
||||
on_start_mock = mocker.patch("ahriman.application.application.Application.on_start")
|
||||
|
||||
Clean.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Clean.run(args, repository_id, configuration, report=False)
|
||||
application_mock.assert_called_once_with(cache=False, chroot=False, manual=False, packages=False, pacman=False)
|
||||
on_start_mock.assert_called_once_with()
|
||||
|
@ -33,7 +33,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
|
||||
start_mock = mocker.patch("threading.Timer.start")
|
||||
join_mock = mocker.patch("threading.Timer.join")
|
||||
|
||||
Daemon.run(args, "x86_64", configuration, report=True)
|
||||
run_mock.assert_called_once_with(args, "x86_64", configuration, report=True)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Daemon.run(args, repository_id, configuration, report=True)
|
||||
run_mock.assert_called_once_with(args, repository_id, configuration, report=True)
|
||||
start_mock.assert_called_once_with()
|
||||
join_mock.assert_called_once_with()
|
||||
|
@ -29,7 +29,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
|
||||
application_mock = mocker.patch("ahriman.core.configuration.Configuration.dump",
|
||||
return_value=configuration.dump())
|
||||
|
||||
Dump.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Dump.run(args, repository_id, configuration, report=False)
|
||||
application_mock.assert_called_once_with()
|
||||
print_mock.assert_called()
|
||||
|
||||
|
@ -29,7 +29,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
|
||||
args = _default_args(args)
|
||||
parse_mock = mocker.patch("argparse.ArgumentParser.parse_args")
|
||||
|
||||
Help.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Help.run(args, repository_id, configuration, report=False)
|
||||
parse_mock.assert_called_once_with(["--help"])
|
||||
|
||||
|
||||
@ -41,7 +42,8 @@ def test_run_command(args: argparse.Namespace, configuration: Configuration, moc
|
||||
args.command = "aur-search"
|
||||
parse_mock = mocker.patch("argparse.ArgumentParser.parse_args")
|
||||
|
||||
Help.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Help.run(args, repository_id, configuration, report=False)
|
||||
parse_mock.assert_called_once_with(["aur-search", "--help"])
|
||||
|
||||
|
||||
|
@ -31,7 +31,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
|
||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||
application_mock = mocker.patch("ahriman.core.sign.gpg.GPG.key_import")
|
||||
|
||||
KeyImport.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
KeyImport.run(args, repository_id, configuration, report=False)
|
||||
application_mock.assert_called_once_with(args.key_server, args.key)
|
||||
|
||||
|
||||
|
@ -44,8 +44,9 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
|
||||
return_value=(args.package, PkgbuildPatch(None, "patch")))
|
||||
application_mock = mocker.patch("ahriman.application.handlers.Patch.patch_set_create")
|
||||
|
||||
Patch.run(args, "x86_64", configuration, report=False)
|
||||
patch_mock.assert_called_once_with(args.package, "x86_64", args.track)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Patch.run(args, repository_id, configuration, report=False)
|
||||
patch_mock.assert_called_once_with(args.package, repository_id.architecture, args.track)
|
||||
application_mock.assert_called_once_with(pytest.helpers.anyvar(int), args.package, PkgbuildPatch(None, "patch"))
|
||||
|
||||
|
||||
@ -63,7 +64,8 @@ def test_run_function(args: argparse.Namespace, configuration: Configuration, re
|
||||
patch_mock = mocker.patch("ahriman.application.handlers.Patch.patch_create_from_function", return_value=patch)
|
||||
application_mock = mocker.patch("ahriman.application.handlers.Patch.patch_set_create")
|
||||
|
||||
Patch.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Patch.run(args, repository_id, configuration, report=False)
|
||||
patch_mock.assert_called_once_with(args.variable, args.patch)
|
||||
application_mock.assert_called_once_with(pytest.helpers.anyvar(int), args.package, patch)
|
||||
|
||||
@ -79,7 +81,8 @@ def test_run_list(args: argparse.Namespace, configuration: Configuration, reposi
|
||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||
application_mock = mocker.patch("ahriman.application.handlers.Patch.patch_set_list")
|
||||
|
||||
Patch.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Patch.run(args, repository_id, configuration, report=False)
|
||||
application_mock.assert_called_once_with(pytest.helpers.anyvar(int), args.package, ["version"], False)
|
||||
|
||||
|
||||
@ -94,11 +97,12 @@ def test_run_remove(args: argparse.Namespace, configuration: Configuration, repo
|
||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||
application_mock = mocker.patch("ahriman.application.handlers.Patch.patch_set_remove")
|
||||
|
||||
Patch.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Patch.run(args, repository_id, configuration, report=False)
|
||||
application_mock.assert_called_once_with(pytest.helpers.anyvar(int), args.package, ["version"])
|
||||
|
||||
|
||||
def test_patch_create_from_diff(package_ahriman: Package, mocker: MockerFixture) -> None:
|
||||
def test_patch_create_from_diff(package_ahriman: Package, configuration: Configuration, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must create patch from directory tree diff
|
||||
"""
|
||||
@ -108,8 +112,9 @@ def test_patch_create_from_diff(package_ahriman: Package, mocker: MockerFixture)
|
||||
package_mock = mocker.patch("ahriman.models.package.Package.from_build", return_value=package_ahriman)
|
||||
sources_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.patch_create", return_value=patch.value)
|
||||
|
||||
assert Patch.patch_create_from_diff(path, "x86_64", ["*.diff"]) == (package_ahriman.base, patch)
|
||||
package_mock.assert_called_once_with(path, "x86_64", None)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
assert Patch.patch_create_from_diff(path, repository_id.architecture, ["*.diff"]) == (package_ahriman.base, patch)
|
||||
package_mock.assert_called_once_with(path, repository_id.architecture, None)
|
||||
sources_mock.assert_called_once_with(path, "*.diff")
|
||||
|
||||
|
||||
|
@ -49,7 +49,8 @@ def test_run(args: argparse.Namespace, package_ahriman: Package, configuration:
|
||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty")
|
||||
on_start_mock = mocker.patch("ahriman.application.application.Application.on_start")
|
||||
|
||||
Rebuild.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Rebuild.run(args, repository_id, configuration, report=False)
|
||||
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], args.username, bump_pkgrel=args.increment)
|
||||
@ -70,7 +71,8 @@ def test_run_extract_packages(args: argparse.Namespace, configuration: Configura
|
||||
mocker.patch("ahriman.application.application.Application.print_updates")
|
||||
extract_mock = mocker.patch("ahriman.application.handlers.Rebuild.extract_packages", return_value=[])
|
||||
|
||||
Rebuild.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Rebuild.run(args, repository_id, configuration, report=False)
|
||||
extract_mock.assert_called_once_with(pytest.helpers.anyvar(int), args.status, from_database=args.from_database)
|
||||
|
||||
|
||||
@ -87,7 +89,8 @@ def test_run_dry_run(args: argparse.Namespace, configuration: Configuration, rep
|
||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty")
|
||||
print_mock = mocker.patch("ahriman.application.application.Application.print_updates")
|
||||
|
||||
Rebuild.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Rebuild.run(args, repository_id, configuration, report=False)
|
||||
application_mock.assert_not_called()
|
||||
check_mock.assert_called_once_with(False, False)
|
||||
print_mock.assert_called_once_with([package_ahriman], log_fn=pytest.helpers.anyvar(int))
|
||||
@ -105,7 +108,8 @@ def test_run_filter(args: argparse.Namespace, configuration: Configuration, repo
|
||||
mocker.patch("ahriman.application.handlers.Rebuild.extract_packages", return_value=[])
|
||||
application_packages_mock = mocker.patch("ahriman.core.repository.repository.Repository.packages_depend_on")
|
||||
|
||||
Rebuild.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Rebuild.run(args, repository_id, configuration, report=False)
|
||||
application_packages_mock.assert_called_once_with([], ["python-aur"])
|
||||
|
||||
|
||||
@ -120,7 +124,8 @@ def test_run_without_filter(args: argparse.Namespace, configuration: Configurati
|
||||
mocker.patch("ahriman.application.handlers.Rebuild.extract_packages", return_value=[])
|
||||
application_packages_mock = mocker.patch("ahriman.core.repository.repository.Repository.packages_depend_on")
|
||||
|
||||
Rebuild.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Rebuild.run(args, repository_id, configuration, report=False)
|
||||
application_packages_mock.assert_called_once_with([], None)
|
||||
|
||||
|
||||
@ -138,7 +143,8 @@ def test_run_update_empty_exception(args: argparse.Namespace, configuration: Con
|
||||
mocker.patch("ahriman.application.application.Application.print_updates")
|
||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty")
|
||||
|
||||
Rebuild.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Rebuild.run(args, repository_id, configuration, report=False)
|
||||
check_mock.assert_called_once_with(True, True)
|
||||
|
||||
|
||||
@ -155,7 +161,8 @@ def test_run_build_empty_exception(args: argparse.Namespace, configuration: Conf
|
||||
mocker.patch("ahriman.application.application.Application.update", return_value=Result())
|
||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty")
|
||||
|
||||
Rebuild.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Rebuild.run(args, repository_id, configuration, report=False)
|
||||
check_mock.assert_has_calls([MockCall(True, False), MockCall(True, True)])
|
||||
|
||||
|
||||
|
@ -31,6 +31,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
|
||||
application_mock = mocker.patch("ahriman.application.application.Application.remove")
|
||||
on_start_mock = mocker.patch("ahriman.application.application.Application.on_start")
|
||||
|
||||
Remove.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Remove.run(args, repository_id, configuration, report=False)
|
||||
application_mock.assert_called_once_with([])
|
||||
on_start_mock.assert_called_once_with()
|
||||
|
@ -34,7 +34,8 @@ def test_run(args: argparse.Namespace, package_ahriman: Package, configuration:
|
||||
remove_mock = mocker.patch("ahriman.application.application.Application.remove")
|
||||
on_start_mock = mocker.patch("ahriman.application.application.Application.on_start")
|
||||
|
||||
RemoveUnknown.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
RemoveUnknown.run(args, repository_id, configuration, report=False)
|
||||
application_mock.assert_called_once_with()
|
||||
remove_mock.assert_called_once_with([package_ahriman])
|
||||
on_start_mock.assert_called_once_with()
|
||||
@ -53,7 +54,8 @@ def test_run_dry_run(args: argparse.Namespace, configuration: Configuration, rep
|
||||
remove_mock = mocker.patch("ahriman.application.application.Application.remove")
|
||||
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
||||
|
||||
RemoveUnknown.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
RemoveUnknown.run(args, repository_id, configuration, report=False)
|
||||
application_mock.assert_called_once_with()
|
||||
remove_mock.assert_not_called()
|
||||
print_mock.assert_called_once_with(verbose=False)
|
||||
|
@ -32,7 +32,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
|
||||
extract_mock = tarfile.__enter__.return_value = MagicMock()
|
||||
mocker.patch("tarfile.TarFile.__new__", return_value=tarfile)
|
||||
|
||||
Restore.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Restore.run(args, repository_id, configuration, report=False)
|
||||
extract_mock.extractall.assert_called_once_with(path=args.output)
|
||||
|
||||
|
||||
|
@ -42,7 +42,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
|
||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty")
|
||||
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
||||
|
||||
Search.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Search.run(args, repository_id, configuration, report=False)
|
||||
aur_search_mock.assert_called_once_with("ahriman", pacman=pytest.helpers.anyvar(int))
|
||||
official_search_mock.assert_called_once_with("ahriman", pacman=pytest.helpers.anyvar(int))
|
||||
check_mock.assert_called_once_with(False, False)
|
||||
@ -62,7 +63,8 @@ def test_run_empty_exception(args: argparse.Namespace, configuration: Configurat
|
||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty")
|
||||
|
||||
Search.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Search.run(args, repository_id, configuration, report=False)
|
||||
check_mock.assert_called_once_with(True, True)
|
||||
|
||||
|
||||
@ -77,7 +79,8 @@ def test_run_sort(args: argparse.Namespace, configuration: Configuration, reposi
|
||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||
sort_mock = mocker.patch("ahriman.application.handlers.Search.sort")
|
||||
|
||||
Search.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Search.run(args, repository_id, configuration, report=False)
|
||||
sort_mock.assert_has_calls([
|
||||
MockCall([], "name"), MockCall().__iter__(),
|
||||
MockCall([aur_package_ahriman], "name"), MockCall().__iter__()
|
||||
@ -96,7 +99,8 @@ def test_run_sort_by(args: argparse.Namespace, configuration: Configuration, rep
|
||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||
sort_mock = mocker.patch("ahriman.application.handlers.Search.sort")
|
||||
|
||||
Search.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Search.run(args, repository_id, configuration, report=False)
|
||||
sort_mock.assert_has_calls([
|
||||
MockCall([], "field"), MockCall().__iter__(),
|
||||
MockCall([aur_package_ahriman], "field"), MockCall().__iter__()
|
||||
|
@ -35,7 +35,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
|
||||
application_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty")
|
||||
|
||||
ServiceUpdates.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
ServiceUpdates.run(args, repository_id, configuration, report=False)
|
||||
package_mock.assert_called_once_with(package_ahriman.base, repository.pacman, None)
|
||||
application_mock.assert_called_once_with(verbose=True, separator=" -> ")
|
||||
check_mock.assert_called_once_with(args.exit_code, True)
|
||||
@ -53,6 +54,7 @@ def test_run_skip(args: argparse.Namespace, configuration: Configuration, reposi
|
||||
application_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty")
|
||||
|
||||
ServiceUpdates.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
ServiceUpdates.run(args, repository_id, configuration, report=False)
|
||||
application_mock.assert_not_called()
|
||||
check_mock.assert_not_called()
|
||||
|
@ -9,6 +9,7 @@ from unittest.mock import call as MockCall
|
||||
from ahriman.application.handlers import Setup
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.repository import Repository
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
from ahriman.models.repository_paths import RepositoryPaths
|
||||
from ahriman.models.sign_settings import SignSettings
|
||||
|
||||
@ -24,14 +25,12 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace:
|
||||
argparse.Namespace: generated arguments for these test cases
|
||||
"""
|
||||
args.build_as_user = "ahriman"
|
||||
args.build_command = "ahriman"
|
||||
args.from_configuration = Path("/usr/share/devtools/pacman.conf.d/extra.conf")
|
||||
args.generate_salt = True
|
||||
args.makeflags_jobs = True
|
||||
args.mirror = "mirror"
|
||||
args.multilib = True
|
||||
args.packager = "John Doe <john@doe.com>"
|
||||
args.repository = "aur-clone"
|
||||
args.server = None
|
||||
args.sign_key = "key"
|
||||
args.sign_target = [SignSettings.Packages]
|
||||
@ -54,14 +53,14 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
|
||||
executable_mock = mocker.patch("ahriman.application.handlers.Setup.executable_create")
|
||||
init_mock = mocker.patch("ahriman.core.alpm.repo.Repo.init")
|
||||
|
||||
Setup.run(args, "x86_64", configuration, report=False)
|
||||
ahriman_configuration_mock.assert_called_once_with(args, "x86_64", args.repository, configuration)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Setup.run(args, repository_id, configuration, report=False)
|
||||
ahriman_configuration_mock.assert_called_once_with(args, repository_id, configuration)
|
||||
devtools_configuration_mock.assert_called_once_with(
|
||||
args.build_command, "x86_64", args.from_configuration, args.mirror, args.multilib, args.repository,
|
||||
f"file://{repository_paths.repository}")
|
||||
repository_id, args.from_configuration, args.mirror, args.multilib, f"file://{repository_paths.repository}")
|
||||
makepkg_configuration_mock.assert_called_once_with(args.packager, args.makeflags_jobs, repository_paths)
|
||||
sudo_configuration_mock.assert_called_once_with(repository_paths, args.build_command, "x86_64")
|
||||
executable_mock.assert_called_once_with(repository_paths, args.build_command, "x86_64")
|
||||
sudo_configuration_mock.assert_called_once_with(repository_paths, repository_id)
|
||||
executable_mock.assert_called_once_with(repository_paths, repository_id)
|
||||
init_mock.assert_called_once_with()
|
||||
|
||||
|
||||
@ -80,21 +79,20 @@ def test_run_with_server(args: argparse.Namespace, configuration: Configuration,
|
||||
mocker.patch("ahriman.core.alpm.repo.Repo.init")
|
||||
devtools_configuration_mock = mocker.patch("ahriman.application.handlers.Setup.configuration_create_devtools")
|
||||
|
||||
Setup.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Setup.run(args, repository_id, configuration, report=False)
|
||||
devtools_configuration_mock.assert_called_once_with(
|
||||
args.build_command, "x86_64", args.from_configuration, args.mirror, args.multilib, args.repository,
|
||||
"server")
|
||||
repository_id, args.from_configuration, args.mirror, args.multilib, "server")
|
||||
|
||||
|
||||
def test_build_command(args: argparse.Namespace) -> None:
|
||||
def test_build_command(repository_id: RepositoryId) -> None:
|
||||
"""
|
||||
must generate correct build command name
|
||||
"""
|
||||
args = _default_args(args)
|
||||
path = Path("local")
|
||||
|
||||
build_command = Setup.build_command(path, args.build_command, "x86_64")
|
||||
assert build_command.name == f"{args.build_command}-x86_64-build"
|
||||
build_command = Setup.build_command(path, repository_id)
|
||||
assert build_command.name == f"{repository_id.name}-{repository_id.architecture}-build"
|
||||
assert build_command.parent == path
|
||||
|
||||
|
||||
@ -107,19 +105,26 @@ def test_configuration_create_ahriman(args: argparse.Namespace, configuration: C
|
||||
mocker.patch("pathlib.Path.open")
|
||||
set_option_mock = mocker.patch("ahriman.core.configuration.Configuration.set_option")
|
||||
write_mock = mocker.patch("ahriman.core.configuration.Configuration.write")
|
||||
command = Setup.build_command(repository_paths.root, args.build_command, "x86_64")
|
||||
_, repository_id = configuration.check_loaded()
|
||||
command = Setup.build_command(repository_paths.root, repository_id)
|
||||
|
||||
Setup.configuration_create_ahriman(args, "x86_64", args.repository, configuration)
|
||||
Setup.configuration_create_ahriman(args, repository_id, configuration)
|
||||
set_option_mock.assert_has_calls([
|
||||
MockCall(Configuration.section_name("build", "x86_64"), "build_command", str(command)),
|
||||
MockCall("repository", "name", args.repository),
|
||||
MockCall(Configuration.section_name("build", "x86_64"), "makechrootpkg_flags", f"-U {args.build_as_user}"),
|
||||
MockCall(Configuration.section_name("alpm", "x86_64"), "mirror", args.mirror),
|
||||
MockCall(Configuration.section_name("sign", "x86_64"), "target",
|
||||
MockCall(Configuration.section_name("build", repository_id.name, repository_id.architecture), "build_command",
|
||||
str(command)),
|
||||
MockCall("repository", "name", repository_id.name),
|
||||
MockCall(Configuration.section_name("build", repository_id.name, repository_id.architecture),
|
||||
"makechrootpkg_flags", f"-U {args.build_as_user}"),
|
||||
MockCall(Configuration.section_name(
|
||||
"alpm", repository_id.name, repository_id.architecture), "mirror", args.mirror),
|
||||
MockCall(Configuration.section_name("sign", repository_id.name, repository_id.architecture), "target",
|
||||
" ".join([target.name.lower() for target in args.sign_target])),
|
||||
MockCall(Configuration.section_name("sign", "x86_64"), "key", args.sign_key),
|
||||
MockCall(Configuration.section_name("web", "x86_64"), "port", str(args.web_port)),
|
||||
MockCall(Configuration.section_name("web", "x86_64"), "unix_socket", str(args.web_unix_socket)),
|
||||
MockCall(Configuration.section_name("sign", repository_id.name, repository_id.architecture), "key",
|
||||
args.sign_key),
|
||||
MockCall(Configuration.section_name("web", repository_id.name, repository_id.architecture), "port",
|
||||
str(args.web_port)),
|
||||
MockCall(Configuration.section_name("web", repository_id.name, repository_id.architecture), "unix_socket",
|
||||
str(args.web_unix_socket)),
|
||||
MockCall("auth", "salt", pytest.helpers.anyvar(str, strict=True)),
|
||||
])
|
||||
write_mock.assert_called_once_with(pytest.helpers.anyvar(int))
|
||||
@ -136,13 +141,16 @@ def test_configuration_create_ahriman_no_multilib(args: argparse.Namespace, conf
|
||||
mocker.patch("ahriman.core.configuration.Configuration.write")
|
||||
set_option_mock = mocker.patch("ahriman.core.configuration.Configuration.set_option")
|
||||
|
||||
Setup.configuration_create_ahriman(args, "x86_64", args.repository, configuration)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Setup.configuration_create_ahriman(args, repository_id, configuration)
|
||||
set_option_mock.assert_has_calls([
|
||||
MockCall(Configuration.section_name("alpm", "x86_64"), "mirror", args.mirror),
|
||||
MockCall(Configuration.section_name("alpm", repository_id.name, repository_id.architecture), "mirror",
|
||||
args.mirror),
|
||||
]) # non-strict check called intentionally
|
||||
|
||||
|
||||
def test_configuration_create_devtools(args: argparse.Namespace, mocker: MockerFixture) -> None:
|
||||
def test_configuration_create_devtools(args: argparse.Namespace, configuration: Configuration,
|
||||
mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must create configuration for the devtools
|
||||
"""
|
||||
@ -152,13 +160,14 @@ def test_configuration_create_devtools(args: argparse.Namespace, mocker: MockerF
|
||||
add_section_mock = mocker.patch("ahriman.core.configuration.Configuration.add_section")
|
||||
write_mock = mocker.patch("ahriman.core.configuration.Configuration.write")
|
||||
|
||||
Setup.configuration_create_devtools(args.build_command, "x86_64", args.from_configuration,
|
||||
None, args.multilib, args.repository, "server")
|
||||
add_section_mock.assert_has_calls([MockCall("multilib"), MockCall(args.repository)])
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Setup.configuration_create_devtools(repository_id, args.from_configuration, None, args.multilib, "server")
|
||||
add_section_mock.assert_has_calls([MockCall("multilib"), MockCall(repository_id.name)])
|
||||
write_mock.assert_called_once_with(pytest.helpers.anyvar(int))
|
||||
|
||||
|
||||
def test_configuration_create_devtools_mirror(args: argparse.Namespace, mocker: MockerFixture) -> None:
|
||||
def test_configuration_create_devtools_mirror(args: argparse.Namespace, configuration: Configuration,
|
||||
mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must create configuration for the devtools with mirror set explicitly
|
||||
"""
|
||||
@ -176,14 +185,15 @@ def test_configuration_create_devtools_mirror(args: argparse.Namespace, mocker:
|
||||
remove_option_mock = mocker.patch("ahriman.core.configuration.Configuration.remove_option")
|
||||
set_option_mock = mocker.patch("ahriman.core.configuration.Configuration.set_option")
|
||||
|
||||
Setup.configuration_create_devtools(args.build_command, "x86_64", args.from_configuration,
|
||||
args.mirror, False, args.repository, "server")
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Setup.configuration_create_devtools(repository_id, args.from_configuration, args.mirror, args.multilib, "server")
|
||||
get_mock.assert_has_calls([MockCall("core", "Include", fallback=None), MockCall("extra", "Include", fallback=None)])
|
||||
remove_option_mock.assert_called_once_with("core", "Include")
|
||||
set_option_mock.assert_has_calls([MockCall("core", "Server", args.mirror)]) # non-strict check called intentionally
|
||||
|
||||
|
||||
def test_configuration_create_devtools_no_multilib(args: argparse.Namespace, mocker: MockerFixture) -> None:
|
||||
def test_configuration_create_devtools_no_multilib(args: argparse.Namespace, configuration: Configuration,
|
||||
mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must create configuration for the devtools without multilib
|
||||
"""
|
||||
@ -192,8 +202,8 @@ def test_configuration_create_devtools_no_multilib(args: argparse.Namespace, moc
|
||||
mocker.patch("ahriman.core.configuration.Configuration.set")
|
||||
write_mock = mocker.patch("ahriman.core.configuration.Configuration.write")
|
||||
|
||||
Setup.configuration_create_devtools(args.build_command, "x86_64", args.from_configuration,
|
||||
None, False, args.repository, "server")
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Setup.configuration_create_devtools(repository_id, args.from_configuration, args.mirror, False, "server")
|
||||
write_mock.assert_called_once_with(pytest.helpers.anyvar(int))
|
||||
|
||||
|
||||
@ -211,31 +221,32 @@ def test_configuration_create_makepkg(args: argparse.Namespace, repository_paths
|
||||
Path("home") / ".makepkg.conf", pytest.helpers.anyvar(str, True), encoding="utf8")
|
||||
|
||||
|
||||
def test_configuration_create_sudo(args: argparse.Namespace, repository_paths: RepositoryPaths,
|
||||
def test_configuration_create_sudo(configuration: Configuration, repository_paths: RepositoryPaths,
|
||||
mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must create sudo configuration
|
||||
"""
|
||||
args = _default_args(args)
|
||||
chmod_text_mock = mocker.patch("pathlib.Path.chmod")
|
||||
write_text_mock = mocker.patch("pathlib.Path.write_text")
|
||||
|
||||
Setup.configuration_create_sudo(repository_paths, args.build_command, "x86_64")
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Setup.configuration_create_sudo(repository_paths, repository_id)
|
||||
chmod_text_mock.assert_called_once_with(0o400)
|
||||
write_text_mock.assert_called_once_with(pytest.helpers.anyvar(str, True), encoding="utf8")
|
||||
|
||||
|
||||
def test_executable_create(args: argparse.Namespace, repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
|
||||
def test_executable_create(configuration: Configuration, repository_paths: RepositoryPaths,
|
||||
mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must create executable
|
||||
"""
|
||||
args = _default_args(args)
|
||||
chown_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.chown")
|
||||
symlink_mock = mocker.patch("pathlib.Path.symlink_to")
|
||||
unlink_mock = mocker.patch("pathlib.Path.unlink")
|
||||
|
||||
Setup.executable_create(repository_paths, args.build_command, "x86_64")
|
||||
chown_mock.assert_called_once_with(Setup.build_command(repository_paths.root, args.build_command, "x86_64"))
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Setup.executable_create(repository_paths, repository_id)
|
||||
chown_mock.assert_called_once_with(Setup.build_command(repository_paths.root, repository_id))
|
||||
symlink_mock.assert_called_once_with(Setup.ARCHBUILD_COMMAND_PATH)
|
||||
unlink_mock.assert_called_once_with(missing_ok=True)
|
||||
|
||||
|
@ -32,7 +32,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
|
||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||
application_mock = mocker.patch("code.interact")
|
||||
|
||||
Shell.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Shell.run(args, repository_id, configuration, report=False)
|
||||
application_mock.assert_called_once_with(local=pytest.helpers.anyvar(int))
|
||||
|
||||
|
||||
@ -46,7 +47,8 @@ def test_run_eval(args: argparse.Namespace, configuration: Configuration, reposi
|
||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||
application_mock = mocker.patch("code.InteractiveConsole.runcode")
|
||||
|
||||
Shell.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Shell.run(args, repository_id, configuration, report=False)
|
||||
application_mock.assert_called_once_with(args.code)
|
||||
|
||||
|
||||
@ -62,7 +64,8 @@ def test_run_verbose(args: argparse.Namespace, configuration: Configuration, rep
|
||||
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
||||
application_mock = mocker.patch("code.interact")
|
||||
|
||||
Shell.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Shell.run(args, repository_id, configuration, report=False)
|
||||
application_mock.assert_called_once_with(local=pytest.helpers.anyvar(int))
|
||||
read_mock.assert_called_once_with(encoding="utf8")
|
||||
print_mock.assert_called_once_with(verbose=False)
|
||||
|
@ -30,5 +30,6 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
|
||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||
application_mock = mocker.patch("ahriman.application.application.Application.sign")
|
||||
|
||||
Sign.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Sign.run(args, repository_id, configuration, report=False)
|
||||
application_mock.assert_called_once_with([])
|
||||
|
@ -43,7 +43,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
|
||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty")
|
||||
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
||||
|
||||
Status.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Status.run(args, repository_id, configuration, report=False)
|
||||
application_mock.assert_called_once_with()
|
||||
packages_mock.assert_called_once_with(None)
|
||||
check_mock.assert_called_once_with(False, False)
|
||||
@ -62,7 +63,8 @@ def test_run_empty_exception(args: argparse.Namespace, configuration: Configurat
|
||||
mocker.patch("ahriman.core.status.client.Client.package_get", return_value=[])
|
||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty")
|
||||
|
||||
Status.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Status.run(args, repository_id, configuration, report=False)
|
||||
check_mock.assert_called_once_with(True, True)
|
||||
|
||||
|
||||
@ -78,7 +80,8 @@ def test_run_verbose(args: argparse.Namespace, configuration: Configuration, rep
|
||||
return_value=[(package_ahriman, BuildStatus(BuildStatusEnum.Success))])
|
||||
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
||||
|
||||
Status.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Status.run(args, repository_id, configuration, report=False)
|
||||
print_mock.assert_has_calls([MockCall(verbose=True) for _ in range(2)])
|
||||
|
||||
|
||||
@ -93,7 +96,8 @@ def test_run_with_package_filter(args: argparse.Namespace, configuration: Config
|
||||
packages_mock = mocker.patch("ahriman.core.status.client.Client.package_get",
|
||||
return_value=[(package_ahriman, BuildStatus(BuildStatusEnum.Success))])
|
||||
|
||||
Status.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Status.run(args, repository_id, configuration, report=False)
|
||||
packages_mock.assert_called_once_with(package_ahriman.base)
|
||||
|
||||
|
||||
@ -110,7 +114,8 @@ def test_run_by_status(args: argparse.Namespace, configuration: Configuration, r
|
||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
||||
|
||||
Status.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Status.run(args, repository_id, configuration, report=False)
|
||||
print_mock.assert_has_calls([MockCall(verbose=False) for _ in range(2)])
|
||||
|
||||
|
||||
@ -123,8 +128,9 @@ def test_imply_with_report(args: argparse.Namespace, configuration: Configuratio
|
||||
mocker.patch("ahriman.core.database.SQLite.load", return_value=database)
|
||||
load_mock = mocker.patch("ahriman.core.repository.Repository.load")
|
||||
|
||||
Status.run(args, "x86_64", configuration, report=False)
|
||||
load_mock.assert_called_once_with("x86_64", configuration, database, report=True, refresh_pacman_database=0)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Status.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_auto_architecture_run() -> None:
|
||||
|
@ -36,7 +36,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
|
||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||
update_self_mock = mocker.patch("ahriman.core.status.client.Client.status_update")
|
||||
|
||||
StatusUpdate.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
StatusUpdate.run(args, repository_id, configuration, report=False)
|
||||
update_self_mock.assert_called_once_with(args.status)
|
||||
|
||||
|
||||
@ -50,7 +51,8 @@ def test_run_packages(args: argparse.Namespace, configuration: Configuration, re
|
||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||
update_mock = mocker.patch("ahriman.core.status.client.Client.package_update")
|
||||
|
||||
StatusUpdate.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
StatusUpdate.run(args, repository_id, configuration, report=False)
|
||||
update_mock.assert_called_once_with(package_ahriman.base, args.status)
|
||||
|
||||
|
||||
@ -65,7 +67,8 @@ def test_run_remove(args: argparse.Namespace, configuration: Configuration, repo
|
||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||
update_mock = mocker.patch("ahriman.core.status.client.Client.package_remove")
|
||||
|
||||
StatusUpdate.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
StatusUpdate.run(args, repository_id, configuration, report=False)
|
||||
update_mock.assert_called_once_with(package_ahriman.base)
|
||||
|
||||
|
||||
@ -78,8 +81,9 @@ def test_imply_with_report(args: argparse.Namespace, configuration: Configuratio
|
||||
mocker.patch("ahriman.core.database.SQLite.load", return_value=database)
|
||||
load_mock = mocker.patch("ahriman.core.repository.Repository.load")
|
||||
|
||||
StatusUpdate.run(args, "x86_64", configuration, report=False)
|
||||
load_mock.assert_called_once_with("x86_64", configuration, database, report=True, refresh_pacman_database=0)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
StatusUpdate.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_auto_architecture_run() -> None:
|
||||
|
@ -35,7 +35,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
|
||||
application_mock = mocker.patch("ahriman.core.tree.Tree.resolve", return_value=[[package_ahriman]])
|
||||
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
||||
|
||||
Structure.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Structure.run(args, repository_id, configuration, report=False)
|
||||
packages_mock.assert_called_once_with([package_ahriman], count=args.partitions)
|
||||
application_mock.assert_called_once_with([package_ahriman])
|
||||
print_mock.assert_has_calls([
|
||||
|
@ -33,7 +33,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
|
||||
application_mock = mocker.patch("ahriman.application.application.Application.on_result")
|
||||
on_start_mock = mocker.patch("ahriman.application.application.Application.on_start")
|
||||
|
||||
Triggers.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Triggers.run(args, repository_id, configuration, report=False)
|
||||
application_mock.assert_called_once_with(Result())
|
||||
on_start_mock.assert_called_once_with()
|
||||
|
||||
@ -50,6 +51,7 @@ def test_run_trigger(args: argparse.Namespace, configuration: Configuration, rep
|
||||
report_mock = mocker.patch("ahriman.core.report.ReportTrigger.on_result")
|
||||
upload_mock = mocker.patch("ahriman.core.upload.UploadTrigger.on_result")
|
||||
|
||||
Triggers.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Triggers.run(args, repository_id, configuration, report=False)
|
||||
report_mock.assert_called_once_with(Result(), [package_ahriman])
|
||||
upload_mock.assert_not_called()
|
||||
|
@ -32,7 +32,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
|
||||
return_value=["command"])
|
||||
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
||||
|
||||
UnsafeCommands.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
UnsafeCommands.run(args, repository_id, configuration, report=False)
|
||||
commands_mock.assert_called_once_with(pytest.helpers.anyvar(int))
|
||||
print_mock.assert_called_once_with(verbose=True)
|
||||
|
||||
@ -47,7 +48,8 @@ def test_run_check(args: argparse.Namespace, configuration: Configuration, mocke
|
||||
return_value=["command"])
|
||||
check_mock = mocker.patch("ahriman.application.handlers.UnsafeCommands.check_unsafe")
|
||||
|
||||
UnsafeCommands.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
UnsafeCommands.run(args, repository_id, configuration, report=False)
|
||||
commands_mock.assert_called_once_with(pytest.helpers.anyvar(int))
|
||||
check_mock.assert_called_once_with(["clean"], ["command"], pytest.helpers.anyvar(int))
|
||||
|
||||
|
@ -54,7 +54,8 @@ def test_run(args: argparse.Namespace, package_ahriman: Package, configuration:
|
||||
on_start_mock = mocker.patch("ahriman.application.application.Application.on_start")
|
||||
print_mock = mocker.patch("ahriman.application.application.Application.print_updates")
|
||||
|
||||
Update.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Update.run(args, repository_id, configuration, report=False)
|
||||
application_mock.assert_called_once_with([package_ahriman],
|
||||
Packagers(args.username, {package_ahriman.base: "packager"}),
|
||||
bump_pkgrel=args.increment)
|
||||
@ -77,7 +78,8 @@ def test_run_empty_exception(args: argparse.Namespace, configuration: Configurat
|
||||
mocker.patch("ahriman.application.application.Application.updates", return_value=[])
|
||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty")
|
||||
|
||||
Update.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Update.run(args, repository_id, configuration, report=False)
|
||||
check_mock.assert_called_once_with(True, True)
|
||||
|
||||
|
||||
@ -95,7 +97,8 @@ def test_run_update_empty_exception(args: argparse.Namespace, package_ahriman: P
|
||||
mocker.patch("ahriman.application.application.Application.print_updates")
|
||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty")
|
||||
|
||||
Update.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Update.run(args, repository_id, configuration, report=False)
|
||||
check_mock.assert_has_calls([MockCall(True, False), MockCall(True, True)])
|
||||
|
||||
|
||||
@ -111,7 +114,8 @@ def test_run_dry_run(args: argparse.Namespace, configuration: Configuration, rep
|
||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty")
|
||||
updates_mock = mocker.patch("ahriman.application.application.Application.updates")
|
||||
|
||||
Update.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Update.run(args, repository_id, configuration, report=False)
|
||||
updates_mock.assert_called_once_with(args.package, aur=args.aur, local=args.local, manual=args.manual, vcs=args.vcs)
|
||||
application_mock.assert_not_called()
|
||||
check_mock.assert_called_once_with(False, pytest.helpers.anyvar(int))
|
||||
|
@ -47,7 +47,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, database: S
|
||||
create_user_mock = mocker.patch("ahriman.application.handlers.Users.user_create", return_value=user)
|
||||
update_mock = mocker.patch("ahriman.core.database.SQLite.user_update")
|
||||
|
||||
Users.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Users.run(args, repository_id, configuration, report=False)
|
||||
create_user_mock.assert_called_once_with(args)
|
||||
update_mock.assert_called_once_with(user)
|
||||
|
||||
@ -64,7 +65,8 @@ def test_run_empty_salt(args: argparse.Namespace, configuration: Configuration,
|
||||
create_user_mock = mocker.patch("ahriman.application.handlers.Users.user_create", return_value=user)
|
||||
update_mock = mocker.patch("ahriman.core.database.SQLite.user_update")
|
||||
|
||||
Users.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Users.run(args, repository_id, configuration, report=False)
|
||||
create_user_mock.assert_called_once_with(args)
|
||||
update_mock.assert_called_once_with(user)
|
||||
|
||||
@ -83,7 +85,8 @@ def test_run_empty_salt_without_password(args: argparse.Namespace, configuration
|
||||
create_user_mock = mocker.patch("ahriman.application.handlers.Users.user_create", return_value=user)
|
||||
update_mock = mocker.patch("ahriman.core.database.SQLite.user_update")
|
||||
|
||||
Users.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Users.run(args, repository_id, configuration, report=False)
|
||||
create_user_mock.assert_called_once_with(args)
|
||||
update_mock.assert_called_once_with(user)
|
||||
|
||||
@ -99,7 +102,8 @@ def test_run_list(args: argparse.Namespace, configuration: Configuration, databa
|
||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty")
|
||||
list_mock = mocker.patch("ahriman.core.database.SQLite.user_list", return_value=[user])
|
||||
|
||||
Users.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Users.run(args, repository_id, configuration, report=False)
|
||||
list_mock.assert_called_once_with("user", args.role)
|
||||
check_mock.assert_called_once_with(False, False)
|
||||
|
||||
@ -116,7 +120,8 @@ def test_run_empty_exception(args: argparse.Namespace, configuration: Configurat
|
||||
mocker.patch("ahriman.core.database.SQLite.user_list", return_value=[])
|
||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty")
|
||||
|
||||
Users.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Users.run(args, repository_id, configuration, report=False)
|
||||
check_mock.assert_called_once_with(True, True)
|
||||
|
||||
|
||||
@ -130,7 +135,8 @@ def test_run_remove(args: argparse.Namespace, configuration: Configuration, data
|
||||
mocker.patch("ahriman.core.database.SQLite.load", return_value=database)
|
||||
remove_mock = mocker.patch("ahriman.core.database.SQLite.user_remove")
|
||||
|
||||
Users.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Users.run(args, repository_id, configuration, report=False)
|
||||
remove_mock.assert_called_once_with(args.username)
|
||||
|
||||
|
||||
|
@ -33,8 +33,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
|
||||
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
||||
application_mock = mocker.patch("ahriman.core.configuration.validator.Validator.validate", return_value=False)
|
||||
|
||||
Validate.run(args, "x86_64", configuration, report=False)
|
||||
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Validate.run(args, repository_id, configuration, report=False)
|
||||
application_mock.assert_called_once_with(configuration.dump())
|
||||
print_mock.assert_called_once_with(verbose=True)
|
||||
|
||||
@ -47,7 +47,8 @@ def test_run_skip(args: argparse.Namespace, configuration: Configuration, mocker
|
||||
mocker.patch("ahriman.core.configuration.validator.Validator.validate", return_value=True)
|
||||
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
||||
|
||||
Validate.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Validate.run(args, repository_id, configuration, report=False)
|
||||
print_mock.assert_not_called()
|
||||
|
||||
|
||||
@ -55,7 +56,8 @@ def test_schema(configuration: Configuration) -> None:
|
||||
"""
|
||||
must generate full schema correctly
|
||||
"""
|
||||
schema = Validate.schema("x86_64", configuration)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
schema = Validate.schema(repository_id, configuration)
|
||||
|
||||
# defaults
|
||||
assert schema.pop("console")
|
||||
@ -86,7 +88,9 @@ def test_schema_invalid_trigger(configuration: Configuration) -> None:
|
||||
"""
|
||||
configuration.set_option("build", "triggers", "some.invalid.trigger.path.Trigger")
|
||||
configuration.remove_option("build", "triggers_known")
|
||||
assert Validate.schema("x86_64", configuration) == CONFIGURATION_SCHEMA
|
||||
_, repository_id = configuration.check_loaded()
|
||||
|
||||
assert Validate.schema(repository_id, configuration) == CONFIGURATION_SCHEMA
|
||||
|
||||
|
||||
def test_schema_erase_required() -> None:
|
||||
|
@ -14,7 +14,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
|
||||
application_mock = mocker.patch("ahriman.application.handlers.Versions.package_dependencies")
|
||||
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
||||
|
||||
Versions.run(args, "x86_64", configuration, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Versions.run(args, repository_id, configuration, report=False)
|
||||
application_mock.assert_called_once_with("ahriman")
|
||||
print_mock.assert_has_calls([MockCall(verbose=False, separator=" "), MockCall(verbose=False, separator=" ")])
|
||||
|
||||
|
@ -41,8 +41,9 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
|
||||
stop_mock = mocker.patch("ahriman.core.spawn.Spawn.stop")
|
||||
join_mock = mocker.patch("ahriman.core.spawn.Spawn.join")
|
||||
|
||||
Web.run(args, "x86_64", configuration, report=False)
|
||||
setup_mock.assert_called_once_with("x86_64", configuration, pytest.helpers.anyvar(int))
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Web.run(args, repository_id, configuration, report=False)
|
||||
setup_mock.assert_called_once_with(repository_id, configuration, pytest.helpers.anyvar(int))
|
||||
run_mock.assert_called_once_with(pytest.helpers.anyvar(int))
|
||||
start_mock.assert_called_once_with()
|
||||
stop_mock.assert_called_once_with()
|
||||
@ -53,33 +54,35 @@ def test_extract_arguments(args: argparse.Namespace, configuration: Configuratio
|
||||
"""
|
||||
must extract correct args
|
||||
"""
|
||||
_, repository_id = configuration.check_loaded()
|
||||
expected = [
|
||||
"--architecture", "x86_64",
|
||||
"--architecture", repository_id.architecture,
|
||||
"--repository", repository_id.name,
|
||||
"--configuration", str(configuration.path),
|
||||
]
|
||||
|
||||
probe = _default_args(args)
|
||||
assert list(Web.extract_arguments(probe, "x86_64", configuration)) == expected
|
||||
assert list(Web.extract_arguments(probe, repository_id, configuration)) == expected
|
||||
|
||||
probe.force = True
|
||||
expected.extend(["--force"])
|
||||
assert list(Web.extract_arguments(probe, "x86_64", configuration)) == expected
|
||||
assert list(Web.extract_arguments(probe, repository_id, configuration)) == expected
|
||||
|
||||
probe.log_handler = LogHandler.Console
|
||||
expected.extend(["--log-handler", probe.log_handler.value])
|
||||
assert list(Web.extract_arguments(probe, "x86_64", configuration)) == expected
|
||||
assert list(Web.extract_arguments(probe, repository_id, configuration)) == expected
|
||||
|
||||
probe.quiet = True
|
||||
expected.extend(["--quiet"])
|
||||
assert list(Web.extract_arguments(probe, "x86_64", configuration)) == expected
|
||||
assert list(Web.extract_arguments(probe, repository_id, configuration)) == expected
|
||||
|
||||
probe.unsafe = True
|
||||
expected.extend(["--unsafe"])
|
||||
assert list(Web.extract_arguments(probe, "x86_64", configuration)) == expected
|
||||
assert list(Web.extract_arguments(probe, repository_id, configuration)) == expected
|
||||
|
||||
configuration.set_option("web", "wait_timeout", "60")
|
||||
expected.extend(["--wait-timeout", "60"])
|
||||
assert list(Web.extract_arguments(probe, "x86_64", configuration)) == expected
|
||||
assert list(Web.extract_arguments(probe, repository_id, configuration)) == expected
|
||||
|
||||
|
||||
def test_extract_arguments_full(parser: argparse.ArgumentParser, configuration: Configuration):
|
||||
@ -101,8 +104,10 @@ def test_extract_arguments_full(parser: argparse.ArgumentParser, configuration:
|
||||
value = action.type(value)
|
||||
setattr(args, action.dest, value)
|
||||
|
||||
assert list(Web.extract_arguments(args, "x86_64", configuration)) == [
|
||||
"--architecture", "x86_64",
|
||||
_, repository_id = configuration.check_loaded()
|
||||
assert list(Web.extract_arguments(args, repository_id, configuration)) == [
|
||||
"--architecture", repository_id.architecture,
|
||||
"--repository", repository_id.name,
|
||||
"--configuration", str(configuration.path),
|
||||
"--force",
|
||||
"--log-handler", "console",
|
||||
|
@ -5,6 +5,7 @@ from pytest_mock import MockerFixture
|
||||
|
||||
from ahriman.application import ahriman
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.models.action import Action
|
||||
from ahriman.models.build_status import BuildStatusEnum
|
||||
from ahriman.models.log_handler import LogHandler
|
||||
@ -65,6 +66,14 @@ def test_multiple_architectures(parser: argparse.ArgumentParser) -> None:
|
||||
assert args.architecture == ["x86_64", "i686"]
|
||||
|
||||
|
||||
def test_multiple_repositories(parser: argparse.ArgumentParser) -> None:
|
||||
"""
|
||||
must accept multiple architectures
|
||||
"""
|
||||
args = parser.parse_args(["-r", "repo1", "-r", "repo2", "service-config"])
|
||||
assert args.repository == ["repo1", "repo2"]
|
||||
|
||||
|
||||
def test_subparsers_aur_search(parser: argparse.ArgumentParser) -> None:
|
||||
"""
|
||||
aur-search command must imply architecture list, lock, report, quiet and unsafe
|
||||
@ -707,8 +716,7 @@ def test_subparsers_service_setup(parser: argparse.ArgumentParser) -> None:
|
||||
"""
|
||||
service-setup command must imply lock, report, quiet and unsafe
|
||||
"""
|
||||
args = parser.parse_args(["-a", "x86_64", "service-setup", "--packager", "John Doe <john@doe.com>",
|
||||
"--repository", "aur-clone"])
|
||||
args = parser.parse_args(["-a", "x86_64", "service-setup", "--packager", "John Doe <john@doe.com>"])
|
||||
assert args.architecture == ["x86_64"]
|
||||
assert args.lock is None
|
||||
assert not args.report
|
||||
@ -720,11 +728,10 @@ def test_subparsers_service_setup_option_from_configuration(parser: argparse.Arg
|
||||
"""
|
||||
service-setup command must convert from-configuration option to path instance
|
||||
"""
|
||||
args = parser.parse_args(["-a", "x86_64", "service-setup", "--packager", "John Doe <john@doe.com>",
|
||||
"--repository", "aur-clone"])
|
||||
args = parser.parse_args(["-a", "x86_64", "service-setup", "--packager", "John Doe <john@doe.com>"])
|
||||
assert isinstance(args.from_configuration, Path)
|
||||
args = parser.parse_args(["-a", "x86_64", "service-setup", "--packager", "John Doe <john@doe.com>",
|
||||
"--repository", "aur-clone", "--from-configuration", "path"])
|
||||
"--from-configuration", "path"])
|
||||
assert isinstance(args.from_configuration, Path)
|
||||
|
||||
|
||||
@ -733,7 +740,7 @@ def test_subparsers_service_setup_option_sign_target(parser: argparse.ArgumentPa
|
||||
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"])
|
||||
"--sign-target", "packages"])
|
||||
assert args.sign_target
|
||||
assert all(isinstance(target, SignSettings) for target in args.sign_target)
|
||||
|
||||
@ -836,13 +843,17 @@ def test_subparsers_web(parser: argparse.ArgumentParser) -> None:
|
||||
assert args.parser is not None and args.parser()
|
||||
|
||||
|
||||
def test_run(args: argparse.Namespace, mocker: MockerFixture) -> None:
|
||||
def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
application must be run
|
||||
"""
|
||||
args.architecture = "x86_64"
|
||||
path, repository_id = configuration.check_loaded()
|
||||
|
||||
args.architecture = repository_id.architecture
|
||||
args.repository = repository_id.name
|
||||
args.configuration = path
|
||||
args.handler = Handler
|
||||
|
||||
mocker.patch("argparse.ArgumentParser.parse_args", return_value=args)
|
||||
|
||||
assert ahriman.run() == 1
|
||||
assert ahriman.run() == 1 # not implemented
|
||||
|
@ -19,7 +19,9 @@ from ahriman.models.build_status import BuildStatus, BuildStatusEnum
|
||||
from ahriman.models.package import Package
|
||||
from ahriman.models.package_description import PackageDescription
|
||||
from ahriman.models.package_source import PackageSource
|
||||
from ahriman.models.pacman_synchronization import PacmanSynchronization
|
||||
from ahriman.models.remote_source import RemoteSource
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
from ahriman.models.repository_paths import RepositoryPaths
|
||||
from ahriman.models.result import Result
|
||||
from ahriman.models.user import User
|
||||
@ -243,18 +245,19 @@ def auth(configuration: Configuration) -> Auth:
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def configuration(resource_path_root: Path) -> Configuration:
|
||||
def configuration(repository_id: RepositoryId, resource_path_root: Path) -> Configuration:
|
||||
"""
|
||||
configuration fixture
|
||||
|
||||
Args:
|
||||
repository_id(RepositoryId): repository identifier fixture
|
||||
resource_path_root(Path): resource path root directory
|
||||
|
||||
Returns:
|
||||
Configuration: configuration test instance
|
||||
"""
|
||||
path = resource_path_root / "core" / "ahriman.ini"
|
||||
return Configuration.from_path(path=path, architecture="x86_64")
|
||||
return Configuration.from_path(path, repository_id)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@ -434,7 +437,8 @@ def pacman(configuration: Configuration) -> Pacman:
|
||||
Returns:
|
||||
Pacman: pacman wrapper test instance
|
||||
"""
|
||||
return Pacman("x86_64", configuration, refresh_database=0)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
return Pacman(repository_id, configuration, refresh_database=PacmanSynchronization.Disabled)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@ -481,7 +485,19 @@ def repository(configuration: Configuration, database: SQLite, mocker: MockerFix
|
||||
Repository: repository test instance
|
||||
"""
|
||||
mocker.patch("ahriman.core.repository.Repository._set_context")
|
||||
return Repository.load("x86_64", configuration, database, report=False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
return Repository.load(repository_id, configuration, database, report=False)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def repository_id() -> RepositoryId:
|
||||
"""
|
||||
fixture for repository identifier
|
||||
|
||||
Returns:
|
||||
RepositoryId: repository identifier test instance
|
||||
"""
|
||||
return RepositoryId("x86_64", "aur-clone")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@ -525,7 +541,12 @@ def spawner(configuration: Configuration) -> Spawn:
|
||||
Returns:
|
||||
Spawn: spawner fixture
|
||||
"""
|
||||
return Spawn(MagicMock(), "x86_64", ["--architecture", "x86_64", "--configuration", str(configuration.path)])
|
||||
_, repository_id = configuration.check_loaded()
|
||||
return Spawn(MagicMock(), repository_id, [
|
||||
"--architecture", "x86_64",
|
||||
"--repository", repository_id.name,
|
||||
"--configuration", str(configuration.path),
|
||||
])
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@ -554,4 +575,5 @@ def watcher(configuration: Configuration, database: SQLite, repository: Reposito
|
||||
Watcher: package status watcher test instance
|
||||
"""
|
||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||
return Watcher("x86_64", configuration, database)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
return Watcher(repository_id, configuration, database)
|
||||
|
@ -7,7 +7,7 @@ from pytest_mock import MockerFixture
|
||||
from systemd.journal import JournalHandler
|
||||
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.log import Log
|
||||
from ahriman.core.log.log_loader import LogLoader
|
||||
from ahriman.models.log_handler import LogHandler
|
||||
|
||||
|
||||
@ -15,14 +15,14 @@ def test_handler() -> None:
|
||||
"""
|
||||
must extract journald handler if available
|
||||
"""
|
||||
assert Log.handler(None) == LogHandler.Journald
|
||||
assert LogLoader.handler(None) == LogHandler.Journald
|
||||
|
||||
|
||||
def test_handler_selected() -> None:
|
||||
"""
|
||||
must return selected log handler
|
||||
"""
|
||||
assert Log.handler(LogHandler.Console) == LogHandler.Console
|
||||
assert LogLoader.handler(LogHandler.Console) == LogHandler.Console
|
||||
|
||||
|
||||
def test_handler_syslog(mocker: MockerFixture) -> None:
|
||||
@ -31,7 +31,7 @@ def test_handler_syslog(mocker: MockerFixture) -> None:
|
||||
"""
|
||||
mocker.patch("pathlib.Path.exists", return_value=True)
|
||||
mocker.patch.dict(sys.modules, {"systemd.journal": None})
|
||||
assert Log.handler(None) == LogHandler.Syslog
|
||||
assert LogLoader.handler(None) == LogHandler.Syslog
|
||||
|
||||
|
||||
def test_handler_console(mocker: MockerFixture) -> None:
|
||||
@ -40,17 +40,17 @@ def test_handler_console(mocker: MockerFixture) -> None:
|
||||
"""
|
||||
mocker.patch("pathlib.Path.exists", return_value=False)
|
||||
mocker.patch.dict(sys.modules, {"systemd.journal": None})
|
||||
assert Log.handler(None) == LogHandler.Console
|
||||
assert LogLoader.handler(None) == LogHandler.Console
|
||||
|
||||
|
||||
def test_load(configuration: Configuration, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must load logging
|
||||
"""
|
||||
logging_mock = mocker.patch("ahriman.core.log.log.fileConfig", side_effect=fileConfig)
|
||||
logging_mock = mocker.patch("ahriman.core.log.log_loader.fileConfig", side_effect=fileConfig)
|
||||
http_log_mock = mocker.patch("ahriman.core.log.http_log_handler.HttpLogHandler.load")
|
||||
|
||||
Log.load(configuration, LogHandler.Journald, quiet=False, report=False)
|
||||
LogLoader.load(configuration, LogHandler.Journald, quiet=False, report=False)
|
||||
logging_mock.assert_called_once_with(pytest.helpers.anyvar(int), disable_existing_loggers=True)
|
||||
http_log_mock.assert_called_once_with(configuration, report=False)
|
||||
assert all(isinstance(handler, JournalHandler) for handler in logging.getLogger().handlers)
|
||||
@ -60,8 +60,8 @@ def test_load_fallback(configuration: Configuration, mocker: MockerFixture) -> N
|
||||
"""
|
||||
must fall back to stderr without errors
|
||||
"""
|
||||
mocker.patch("ahriman.core.log.log.fileConfig", side_effect=PermissionError())
|
||||
Log.load(configuration, LogHandler.Journald, quiet=False, report=False)
|
||||
mocker.patch("ahriman.core.log.log_loader.fileConfig", side_effect=PermissionError())
|
||||
LogLoader.load(configuration, LogHandler.Journald, quiet=False, report=False)
|
||||
|
||||
|
||||
def test_load_quiet(configuration: Configuration, mocker: MockerFixture) -> None:
|
||||
@ -69,5 +69,5 @@ def test_load_quiet(configuration: Configuration, mocker: MockerFixture) -> None
|
||||
must disable logging in case if quiet flag set
|
||||
"""
|
||||
disable_mock = mocker.patch("logging.disable")
|
||||
Log.load(configuration, LogHandler.Journald, quiet=True, report=False)
|
||||
LogLoader.load(configuration, LogHandler.Journald, quiet=True, report=False)
|
||||
disable_mock.assert_called_once_with(logging.WARNING)
|
@ -17,4 +17,5 @@ def remote_call(configuration: Configuration) -> RemoteCall:
|
||||
"""
|
||||
configuration.set_option("web", "host", "localhost")
|
||||
configuration.set_option("web", "port", "8080")
|
||||
return RemoteCall("x86_64", configuration, "remote-call")
|
||||
_, repository_id = configuration.check_loaded()
|
||||
return RemoteCall(repository_id, configuration, "remote-call")
|
||||
|
@ -22,7 +22,8 @@ def cleaner(configuration: Configuration, database: SQLite) -> Cleaner:
|
||||
Returns:
|
||||
Cleaner: cleaner test instance
|
||||
"""
|
||||
return Cleaner("x86_64", configuration, database, report=False,
|
||||
_, repository_id = configuration.check_loaded()
|
||||
return Cleaner(repository_id, configuration, database, report=False,
|
||||
refresh_pacman_database=PacmanSynchronization.Disabled)
|
||||
|
||||
|
||||
@ -43,7 +44,8 @@ def executor(configuration: Configuration, database: SQLite, mocker: MockerFixtu
|
||||
mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_chroot")
|
||||
mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_packages")
|
||||
mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_queue")
|
||||
return Executor("x86_64", configuration, database, report=False,
|
||||
_, repository_id = configuration.check_loaded()
|
||||
return Executor(repository_id, configuration, database, report=False,
|
||||
refresh_pacman_database=PacmanSynchronization.Disabled)
|
||||
|
||||
|
||||
@ -64,5 +66,6 @@ def update_handler(configuration: Configuration, database: SQLite, mocker: Mocke
|
||||
mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_chroot")
|
||||
mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_packages")
|
||||
mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_queue")
|
||||
return UpdateHandler("x86_64", configuration, database, report=False,
|
||||
_, repository_id = configuration.check_loaded()
|
||||
return UpdateHandler(repository_id, configuration, database, report=False,
|
||||
refresh_pacman_database=PacmanSynchronization.Disabled)
|
||||
|
@ -15,7 +15,8 @@ def trigger(configuration: Configuration) -> Trigger:
|
||||
Returns:
|
||||
Trigger: trigger test instance
|
||||
"""
|
||||
return Trigger("x86_64", configuration)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
return Trigger(repository_id, configuration)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@ -28,4 +29,5 @@ def trigger_loader(configuration: Configuration) -> TriggerLoader:
|
||||
Returns:
|
||||
TriggerLoader: trigger loader test instance
|
||||
"""
|
||||
return TriggerLoader.load("x86_64", configuration)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
return TriggerLoader.load(repository_id, configuration)
|
||||
|
@ -4,33 +4,34 @@ from typing import Any
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.upload.github import Github
|
||||
from ahriman.core.upload.github import GitHub
|
||||
from ahriman.core.upload.remote_service import RemoteService
|
||||
from ahriman.core.upload.rsync import Rsync
|
||||
from ahriman.core.upload.s3 import S3
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def github(configuration: Configuration) -> Github:
|
||||
def github(configuration: Configuration) -> GitHub:
|
||||
"""
|
||||
fixture for github synchronization
|
||||
fixture for GitHub synchronization
|
||||
|
||||
Args:
|
||||
configuration(Configuration): configuration fixture
|
||||
|
||||
Returns:
|
||||
Github: github test instance
|
||||
GitHub: GitHub test instance
|
||||
"""
|
||||
return Github("x86_64", configuration, "github:x86_64")
|
||||
_, repository_id = configuration.check_loaded()
|
||||
return GitHub(repository_id, configuration, "github:x86_64")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def github_release() -> dict[str, Any]:
|
||||
"""
|
||||
fixture for the github release object
|
||||
fixture for the GitHub release object
|
||||
|
||||
Returns:
|
||||
dict[str, Any]: github test release object
|
||||
dict[str, Any]: GitHub test release object
|
||||
"""
|
||||
return {
|
||||
"url": "release_url",
|
||||
@ -59,7 +60,8 @@ def remote_service(configuration: Configuration) -> RemoteService:
|
||||
"""
|
||||
configuration.set_option("web", "host", "localhost")
|
||||
configuration.set_option("web", "port", "8080")
|
||||
return RemoteService("x86_64", configuration, "remote-service")
|
||||
_, repository_id = configuration.check_loaded()
|
||||
return RemoteService(repository_id, configuration, "remote-service")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@ -73,7 +75,8 @@ def rsync(configuration: Configuration) -> Rsync:
|
||||
Returns:
|
||||
Rsync: rsync test instance
|
||||
"""
|
||||
return Rsync("x86_64", configuration, "rsync")
|
||||
_, repository_id = configuration.check_loaded()
|
||||
return Rsync(repository_id, configuration, "rsync")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@ -87,7 +90,8 @@ def s3(configuration: Configuration) -> S3:
|
||||
Returns:
|
||||
S3: S3 test instance
|
||||
"""
|
||||
return S3("x86_64", configuration, "customs3")
|
||||
_, repository_id = configuration.check_loaded()
|
||||
return S3(repository_id, configuration, "customs3")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
@ -6,10 +6,10 @@ from pytest_mock import MockerFixture
|
||||
from typing import Any
|
||||
from unittest.mock import call as MockCall
|
||||
|
||||
from ahriman.core.upload.github import Github
|
||||
from ahriman.core.upload.github import GitHub
|
||||
|
||||
|
||||
def test_asset_remove(github: Github, github_release: dict[str, Any], mocker: MockerFixture) -> None:
|
||||
def test_asset_remove(github: GitHub, github_release: dict[str, Any], mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must remove asset from the release
|
||||
"""
|
||||
@ -18,7 +18,7 @@ def test_asset_remove(github: Github, github_release: dict[str, Any], mocker: Mo
|
||||
request_mock.assert_called_once_with("DELETE", "asset_url")
|
||||
|
||||
|
||||
def test_asset_remove_unknown(github: Github, github_release: dict[str, Any], mocker: MockerFixture) -> None:
|
||||
def test_asset_remove_unknown(github: GitHub, github_release: dict[str, Any], mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must not fail if no asset found
|
||||
"""
|
||||
@ -27,7 +27,7 @@ def test_asset_remove_unknown(github: Github, github_release: dict[str, Any], mo
|
||||
request_mock.assert_not_called()
|
||||
|
||||
|
||||
def test_asset_upload(github: Github, github_release: dict[str, Any], mocker: MockerFixture) -> None:
|
||||
def test_asset_upload(github: GitHub, github_release: dict[str, Any], mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must upload asset to the repository
|
||||
"""
|
||||
@ -42,7 +42,7 @@ def test_asset_upload(github: Github, github_release: dict[str, Any], mocker: Mo
|
||||
remove_mock.assert_not_called()
|
||||
|
||||
|
||||
def test_asset_upload_with_removal(github: Github, github_release: dict[str, Any], mocker: MockerFixture) -> None:
|
||||
def test_asset_upload_with_removal(github: GitHub, github_release: dict[str, Any], mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must remove existing file before upload
|
||||
"""
|
||||
@ -58,7 +58,7 @@ def test_asset_upload_with_removal(github: Github, github_release: dict[str, Any
|
||||
])
|
||||
|
||||
|
||||
def test_asset_upload_empty_mimetype(github: Github, github_release: dict[str, Any], mocker: MockerFixture) -> None:
|
||||
def test_asset_upload_empty_mimetype(github: GitHub, github_release: dict[str, Any], mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must upload asset to the repository with empty mime type if the library cannot guess it
|
||||
"""
|
||||
@ -73,7 +73,7 @@ def test_asset_upload_empty_mimetype(github: Github, github_release: dict[str, A
|
||||
headers={"Content-Type": "application/octet-stream"})
|
||||
|
||||
|
||||
def test_get_local_files(github: Github, resource_path_root: Path, mocker: MockerFixture) -> None:
|
||||
def test_get_local_files(github: GitHub, resource_path_root: Path, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must get all local files recursively
|
||||
"""
|
||||
@ -82,7 +82,7 @@ def test_get_local_files(github: Github, resource_path_root: Path, mocker: Mocke
|
||||
walk_mock.assert_called()
|
||||
|
||||
|
||||
def test_files_remove(github: Github, github_release: dict[str, Any], mocker: MockerFixture) -> None:
|
||||
def test_files_remove(github: GitHub, github_release: dict[str, Any], mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must remove files from the remote
|
||||
"""
|
||||
@ -91,7 +91,7 @@ def test_files_remove(github: Github, github_release: dict[str, Any], mocker: Mo
|
||||
remove_mock.assert_called_once_with(github_release, "b")
|
||||
|
||||
|
||||
def test_files_remove_empty(github: Github, github_release: dict[str, Any], mocker: MockerFixture) -> None:
|
||||
def test_files_remove_empty(github: GitHub, github_release: dict[str, Any], mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must remove nothing if nothing changed
|
||||
"""
|
||||
@ -100,7 +100,7 @@ def test_files_remove_empty(github: Github, github_release: dict[str, Any], mock
|
||||
remove_mock.assert_not_called()
|
||||
|
||||
|
||||
def test_files_upload(github: Github, github_release: dict[str, Any], mocker: MockerFixture) -> None:
|
||||
def test_files_upload(github: GitHub, github_release: dict[str, Any], mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must upload files to the remote
|
||||
"""
|
||||
@ -112,7 +112,7 @@ def test_files_upload(github: Github, github_release: dict[str, Any], mocker: Mo
|
||||
])
|
||||
|
||||
|
||||
def test_files_upload_empty(github: Github, github_release: dict[str, Any], mocker: MockerFixture) -> None:
|
||||
def test_files_upload_empty(github: GitHub, github_release: dict[str, Any], mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must upload nothing if nothing changed
|
||||
"""
|
||||
@ -121,7 +121,7 @@ def test_files_upload_empty(github: Github, github_release: dict[str, Any], mock
|
||||
upload_mock.assert_not_called()
|
||||
|
||||
|
||||
def test_release_create(github: Github, mocker: MockerFixture) -> None:
|
||||
def test_release_create(github: GitHub, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must create release
|
||||
"""
|
||||
@ -131,7 +131,7 @@ def test_release_create(github: Github, mocker: MockerFixture) -> None:
|
||||
json={"tag_name": github.architecture, "name": github.architecture})
|
||||
|
||||
|
||||
def test_release_get(github: Github, mocker: MockerFixture) -> None:
|
||||
def test_release_get(github: GitHub, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must get release
|
||||
"""
|
||||
@ -140,7 +140,7 @@ def test_release_get(github: Github, mocker: MockerFixture) -> None:
|
||||
request_mock.assert_called_once_with("GET", pytest.helpers.anyvar(str, True))
|
||||
|
||||
|
||||
def test_release_get_empty(github: Github, mocker: MockerFixture) -> None:
|
||||
def test_release_get_empty(github: GitHub, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must return nothing in case of 404 status code
|
||||
"""
|
||||
@ -151,7 +151,7 @@ def test_release_get_empty(github: Github, mocker: MockerFixture) -> None:
|
||||
assert github.release_get() is None
|
||||
|
||||
|
||||
def test_release_get_exception(github: Github, mocker: MockerFixture) -> None:
|
||||
def test_release_get_exception(github: GitHub, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must re-raise non HTTPError exception
|
||||
"""
|
||||
@ -160,7 +160,7 @@ def test_release_get_exception(github: Github, mocker: MockerFixture) -> None:
|
||||
github.release_get()
|
||||
|
||||
|
||||
def test_release_get_exception_http_error(github: Github, mocker: MockerFixture) -> None:
|
||||
def test_release_get_exception_http_error(github: GitHub, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must re-raise HTTPError exception with code differs from 404
|
||||
"""
|
||||
@ -170,7 +170,7 @@ def test_release_get_exception_http_error(github: Github, mocker: MockerFixture)
|
||||
github.release_get()
|
||||
|
||||
|
||||
def test_release_update(github: Github, github_release: dict[str, Any], mocker: MockerFixture) -> None:
|
||||
def test_release_update(github: GitHub, github_release: dict[str, Any], mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must update release
|
||||
"""
|
||||
@ -179,7 +179,7 @@ def test_release_update(github: Github, github_release: dict[str, Any], mocker:
|
||||
request_mock.assert_called_once_with("POST", "release_url", json={"body": "body"})
|
||||
|
||||
|
||||
def test_release_sync(github: Github, mocker: MockerFixture) -> None:
|
||||
def test_release_sync(github: GitHub, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must run sync command
|
||||
"""
|
||||
@ -199,7 +199,7 @@ def test_release_sync(github: Github, mocker: MockerFixture) -> None:
|
||||
release_update_mock.assert_called_once_with({}, pytest.helpers.anyvar(int))
|
||||
|
||||
|
||||
def test_release_sync_create_release(github: Github, mocker: MockerFixture) -> None:
|
||||
def test_release_sync_create_release(github: GitHub, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must create release in case if it does not exist
|
||||
"""
|
||||
|
@ -112,7 +112,9 @@ def application(configuration: Configuration, spawner: Spawn, database: SQLite,
|
||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||
mocker.patch("aiohttp_apispec.setup_aiohttp_apispec")
|
||||
mocker.patch.object(ahriman.core.auth.helpers, "_has_aiohttp_security", False)
|
||||
return setup_service("x86_64", configuration, spawner)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
|
||||
return setup_service(repository_id, configuration, spawner)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@ -138,7 +140,8 @@ def application_with_auth(configuration: Configuration, user: User, spawner: Spa
|
||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||
mocker.patch("aiohttp_apispec.setup_aiohttp_apispec")
|
||||
mocker.patch.object(ahriman.core.auth.helpers, "_has_aiohttp_security", True)
|
||||
application = setup_service("x86_64", configuration, spawner)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
application = setup_service(repository_id, configuration, spawner)
|
||||
|
||||
generated = user.hash_password(application["validator"].salt)
|
||||
mocker.patch("ahriman.core.database.SQLite.user_get", return_value=generated)
|
||||
@ -169,7 +172,9 @@ def application_with_debug(configuration: Configuration, user: User, spawner: Sp
|
||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||
mocker.patch("aiohttp_apispec.setup_aiohttp_apispec")
|
||||
mocker.patch.object(ahriman.core.auth.helpers, "_has_aiohttp_security", False)
|
||||
return setup_service("x86_64", configuration, spawner)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
|
||||
return setup_service(repository_id, configuration, spawner)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
Loading…
Reference in New Issue
Block a user