mirror of
https://github.com/arcan1s/ahriman.git
synced 2025-04-24 23:37:18 +00:00
Merge 7885df0dae
into 6fe77eb465
This commit is contained in:
commit
bb0c35f576
11
.github/workflows/setup.sh
vendored
11
.github/workflows/setup.sh
vendored
@ -26,11 +26,16 @@ cp "docker/systemd-nspawn.sh" "/usr/local/bin/systemd-nspawn"
|
|||||||
# create fresh tarball
|
# create fresh tarball
|
||||||
tox -e archive
|
tox -e archive
|
||||||
# run makepkg
|
# run makepkg
|
||||||
mv dist/ahriman-*.tar.gz package/archlinux
|
PKGVER=$(python -c "from src.ahriman import __version__; print(__version__)")
|
||||||
|
mv "dist/ahriman-$PKGVER.tar.gz" package/archlinux
|
||||||
chmod +777 package/archlinux # because fuck you that's why
|
chmod +777 package/archlinux # because fuck you that's why
|
||||||
cd package/archlinux
|
cd package/archlinux
|
||||||
sudo -u nobody -- makepkg -cf --skipchecksums --noconfirm
|
sudo -u nobody -- makepkg -cf --skipchecksums --noconfirm
|
||||||
sudo -u nobody -- makepkg --packagelist | grep -v -- -debug- | pacman -U --noconfirm -
|
sudo -u nobody -- makepkg --packagelist | grep "ahriman-core-$PKGVER" | pacman -U --noconfirm --nodeps -
|
||||||
|
if [[ -z $MINIMAL_INSTALL ]]; then
|
||||||
|
sudo -u nobody -- makepkg --packagelist | grep "ahriman-triggers-$PKGVER" | pacman -U --noconfirm --nodeps -
|
||||||
|
sudo -u nobody -- makepkg --packagelist | grep "ahriman-web-$PKGVER" | pacman -U --noconfirm --nodeps -
|
||||||
|
fi
|
||||||
# create machine-id which is required by build tools
|
# create machine-id which is required by build tools
|
||||||
systemd-machine-id-setup
|
systemd-machine-id-setup
|
||||||
|
|
||||||
@ -41,12 +46,12 @@ pacman -Qdtq | pacman -Rscn --noconfirm -
|
|||||||
[[ -z $MINIMAL_INSTALL ]] && WEB_ARGS=("--web-port" "8080")
|
[[ -z $MINIMAL_INSTALL ]] && WEB_ARGS=("--web-port" "8080")
|
||||||
ahriman -a x86_64 -r "github" service-setup --packager "ahriman bot <ahriman@example.com>" "${WEB_ARGS[@]}"
|
ahriman -a x86_64 -r "github" service-setup --packager "ahriman bot <ahriman@example.com>" "${WEB_ARGS[@]}"
|
||||||
# enable services
|
# enable services
|
||||||
systemctl enable ahriman-web
|
|
||||||
systemctl enable ahriman@x86_64-github.timer
|
systemctl enable ahriman@x86_64-github.timer
|
||||||
if [[ -z $MINIMAL_INSTALL ]]; then
|
if [[ -z $MINIMAL_INSTALL ]]; then
|
||||||
# validate configuration
|
# validate configuration
|
||||||
ahriman service-config-validate --exit-code
|
ahriman service-config-validate --exit-code
|
||||||
# run web service (detached)
|
# run web service (detached)
|
||||||
|
systemctl enable ahriman-web
|
||||||
sudo -u ahriman -- ahriman web &
|
sudo -u ahriman -- ahriman web &
|
||||||
WEB_PID=$!
|
WEB_PID=$!
|
||||||
fi
|
fi
|
||||||
|
@ -79,7 +79,8 @@ RUN cd "/home/build/ahriman" && \
|
|||||||
tox -e archive && \
|
tox -e archive && \
|
||||||
cp ./dist/*.tar.gz "package/archlinux" && \
|
cp ./dist/*.tar.gz "package/archlinux" && \
|
||||||
cd "package/archlinux" && \
|
cd "package/archlinux" && \
|
||||||
runuser -u build -- makepkg --noconfirm --install --skipchecksums && \
|
runuser -u build -- makepkg --noconfirm --skipchecksums && \
|
||||||
|
runuser -u build -- makepkg --packagelist | grep -v -- -debug- | pacman -U --noconfirm --nodeps - && \
|
||||||
cd / && rm -r "/home/build/ahriman"
|
cd / && rm -r "/home/build/ahriman"
|
||||||
|
|
||||||
# cleanup unused
|
# cleanup unused
|
||||||
|
51
docs/advanced-usage/handlers.rst
Normal file
51
docs/advanced-usage/handlers.rst
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
Writing own handler
|
||||||
|
===================
|
||||||
|
|
||||||
|
It is possible to extend the application by adding own custom commands. To do so it is required to implement class, which derives from ``ahriman.application.handlers.handler.Handler`` and put it to the ``ahriman.application.handlers`` package. The class later will be loaded automatically and included to each command run.
|
||||||
|
|
||||||
|
Let's imagine, that the new class implements ``help-web``, which prints server information to the stdout. To do so, we need to implement base ``ahriman.application.handlers.handler.Handler.run`` method which is entry point for all subcommands:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from ahriman.application.application import Application
|
||||||
|
from ahriman.application.handlers.handler import Handler
|
||||||
|
|
||||||
|
|
||||||
|
class HelpWeb(Handler):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def run(cls, args: argparse.Namespace, repository_id: RepositoryId, configuration: Configuration, *,
|
||||||
|
report: bool) -> None:
|
||||||
|
# load application instance
|
||||||
|
# report is set to True to make sure that web client is loaded
|
||||||
|
application = Application(repository_id, configuration, report=True)
|
||||||
|
# extract web client
|
||||||
|
client = application.repository.reporter
|
||||||
|
|
||||||
|
# send request to the server
|
||||||
|
response = client.make_request("GET", f"{client.address}/api/v1/info")
|
||||||
|
result = response.json()
|
||||||
|
print(result)
|
||||||
|
|
||||||
|
The main functionality of the class is already described, but command is still not available yet. To do so, it is required to set ``arguments`` property, which is list of functions, which takes argument parser object, creates new subcommand and returns the modified parser, e.g.:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
from ahriman.application.handlers.handler import SubParserAction
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def set_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
parser = root.add_parser("help-web", help="get web server status",
|
||||||
|
description="request server info and print it to stdout")
|
||||||
|
|
||||||
|
arguments = set_parser
|
||||||
|
|
||||||
|
In addition, ``ahriman.application.handlers.handler.Handler.ALLOW_MULTI_ARCHITECTURE_RUN`` can be set to ``False`` in order to disable multiprocess run (e.g. in case if there are conflicting operations, like writting to stdout).
|
||||||
|
|
||||||
|
Save the file above as ``/usr/lib/python3.12/site-packages/ahriman/application/handlers/help_web.py`` (replace ``python3.12`` with actual python version) and you are set.
|
||||||
|
|
||||||
|
For more examples and details, please check builtin handlers and classes documentations.
|
@ -1,6 +1,12 @@
|
|||||||
Advanced usage
|
Advanced usage
|
||||||
==============
|
==============
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
handlers
|
||||||
|
views
|
||||||
|
|
||||||
Depending on the goal the package can be used in different ways. Nevertheless, in the most cases you will need some basic classes
|
Depending on the goal the package can be used in different ways. Nevertheless, in the most cases you will need some basic classes
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
41
docs/advanced-usage/views.rst
Normal file
41
docs/advanced-usage/views.rst
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
Writing own API endpoint
|
||||||
|
========================
|
||||||
|
|
||||||
|
The web service loads views dynamically, thus it is possible to add custom API endpoint or even web page. The views must be derived from ``ahriman.web.views.base.BaseView`` and implements HTTP methods. The API specification will be also loaded (if available), but optional. The implementation must be saved into the ``ahriman.web.views`` package
|
||||||
|
|
||||||
|
Let's consider example for API endpoint which always returns 204 with no response:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from aiohttp.web import Response, HTTPNoContent
|
||||||
|
|
||||||
|
from ahriman.web.views.base import BaseView
|
||||||
|
|
||||||
|
class PingView(BaseView):
|
||||||
|
|
||||||
|
async def get(self) -> Response:
|
||||||
|
# do nothing, just raise 204 response
|
||||||
|
# check public methods of the BaseView class for all available controls
|
||||||
|
raise HTTPNoContent
|
||||||
|
|
||||||
|
The ``get()`` method can be decorated by ``aiohttp_apispec`` methods, but we will leave it for self-study. Consider checking examples of usages in the main package.
|
||||||
|
|
||||||
|
In order to view to be set correctly to routes list, few more options are required to be set. First of all, it is required to specify ``ROUTES`` (list of strings), which contains list of all available routes, e.g.:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
ROUTES = ["/api/v1/ping"]
|
||||||
|
|
||||||
|
In addition, it is also recommended to specify permission level for using this endpoint. Since this endpoint neither does anything nor returns sensitive information, it can be set to ``UserAccess.Unauthorized``:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
GET_PERMISSION = UserAccess.Unauthorized
|
||||||
|
|
||||||
|
That's all. Just save the file as ``/usr/lib/python3.12/site-packages/ahriman/web/views/ping.py`` (replace ``python3.12`` with actual python version) and restart web server.
|
||||||
|
|
||||||
|
For more examples and details, please check builtin handlers and classes documentations.
|
@ -228,6 +228,14 @@ ahriman.application.handlers.triggers module
|
|||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
|
ahriman.application.handlers.triggers\_support module
|
||||||
|
-----------------------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.application.handlers.triggers_support
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
ahriman.application.handlers.unsafe\_commands module
|
ahriman.application.handlers.unsafe\_commands module
|
||||||
----------------------------------------------------
|
----------------------------------------------------
|
||||||
|
|
||||||
|
@ -36,6 +36,14 @@ ahriman.core.exceptions module
|
|||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
|
ahriman.core.module\_loader module
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.core.module_loader
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
ahriman.core.spawn module
|
ahriman.core.spawn module
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ Full dependency diagram:
|
|||||||
``ahriman.application`` package
|
``ahriman.application`` package
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
This package contains application (aka executable) related classes and everything for it. It also contains package called ``ahriman.application.handlers`` in which all available subcommands are described as separated classes derived from the base ``ahriman.application.handlers.Handler`` class.
|
This package contains application (aka executable) related classes and everything for it. It also contains package called ``ahriman.application.handlers`` in which all available subcommands are described as separated classes derived from the base ``ahriman.application.handlers.handler.Handler`` class.
|
||||||
|
|
||||||
``ahriman.application.application.Application`` (god class) is used for any interaction from parsers with repository. It is divided into multiple traits by functions (package related and repository related) in the same package.
|
``ahriman.application.application.Application`` (god class) is used for any interaction from parsers with repository. It is divided into multiple traits by functions (package related and repository related) in the same package.
|
||||||
|
|
||||||
@ -52,8 +52,10 @@ This package contains everything required for the most of application actions an
|
|||||||
This package also provides some generic functions and classes which may be used by other packages:
|
This package also provides some generic functions and classes which may be used by other packages:
|
||||||
|
|
||||||
* ``ahriman.core.exceptions`` provides custom exceptions.
|
* ``ahriman.core.exceptions`` provides custom exceptions.
|
||||||
|
* ``ahriman.core.module_loader`` provides ``implementations`` method which can be used for dynamic classes load. In particular, this method is used for web views and application handlers loading.
|
||||||
* ``ahriman.core.spawn.Spawn`` is a tool which can spawn another ``ahriman`` process. This feature is used by web application.
|
* ``ahriman.core.spawn.Spawn`` is a tool which can spawn another ``ahriman`` process. This feature is used by web application.
|
||||||
* ``ahriman.core.tree`` is a dependency tree implementation.
|
* ``ahriman.core.tree`` is a dependency tree implementation.
|
||||||
|
* ``ahriman.core.types`` are an additional global types for mypy checks.
|
||||||
|
|
||||||
``ahriman.models`` package
|
``ahriman.models`` package
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -436,6 +438,9 @@ REST API supports only JSON data.
|
|||||||
Different APIs are separated into different packages:
|
Different APIs are separated into different packages:
|
||||||
|
|
||||||
* ``ahriman.web.views.api`` not a real API, but some views which provide OpenAPI support.
|
* ``ahriman.web.views.api`` not a real API, but some views which provide OpenAPI support.
|
||||||
|
* ``ahriman.web.views.*.auditlog`` provides event log API.
|
||||||
|
* ``ahriman.web.views.*.distributed`` is an API for builders interaction for multi-node setup.
|
||||||
|
* ``ahriman.web.views.*.pacakges`` contains views which provide information about existing packages.
|
||||||
* ``ahriman.web.views.*.service`` provides views for application controls.
|
* ``ahriman.web.views.*.service`` provides views for application controls.
|
||||||
* ``ahriman.web.views.*.status`` package provides REST API for application reporting.
|
* ``ahriman.web.views.*.status`` package provides REST API for application reporting.
|
||||||
* ``ahriman.web.views.*.user`` package provides login and logout methods which can be called without authorization.
|
* ``ahriman.web.views.*.user`` package provides login and logout methods which can be called without authorization.
|
||||||
|
@ -311,6 +311,12 @@ Automatic worker nodes discovery
|
|||||||
|
|
||||||
Instead of setting ``${build:workers}`` option explicitly it is also possible to configure services to load worker list dynamically. To do so, the ``ahriman.core.distributed.WorkerLoaderTrigger`` and ``ahriman.core.distributed.WorkerTrigger`` must be used for **master** and **worker** nodes respectively. See recipes for more details.
|
Instead of setting ``${build:workers}`` option explicitly it is also possible to configure services to load worker list dynamically. To do so, the ``ahriman.core.distributed.WorkerLoaderTrigger`` and ``ahriman.core.distributed.WorkerTrigger`` must be used for **master** and **worker** nodes respectively. See recipes for more details.
|
||||||
|
|
||||||
|
Those triggers have to be installed as a separate package:
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
yay -S ahriman-triggers
|
||||||
|
|
||||||
Known limitations
|
Known limitations
|
||||||
"""""""""""""""""
|
"""""""""""""""""
|
||||||
|
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
Maintenance packages
|
Maintenance packages
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
|
Those features require extensions package to be installed before, e.g.:
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
yay -S ahriman-triggers
|
||||||
|
|
||||||
Generate keyring package
|
Generate keyring package
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
@ -5,11 +5,11 @@ How to setup web service
|
|||||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
#.
|
#.
|
||||||
Install dependencies:
|
Install web service:
|
||||||
|
|
||||||
.. code-block:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
yay -S --asdeps python-aiohttp python-aiohttp-jinja2 python-aiohttp-apispec>=3.0.0 python-aiohttp-cors
|
yay -S -ahriman-web
|
||||||
|
|
||||||
#.
|
#.
|
||||||
Configure service:
|
Configure service:
|
||||||
|
@ -36,6 +36,6 @@ Contents
|
|||||||
faq/index
|
faq/index
|
||||||
migrations/index
|
migrations/index
|
||||||
architecture
|
architecture
|
||||||
advanced-usage
|
advanced-usage/index
|
||||||
triggers
|
triggers
|
||||||
modules
|
modules
|
||||||
|
@ -1,51 +1,87 @@
|
|||||||
# Maintainer: Evgeniy Alekseev
|
# Maintainer: Evgeniy Alekseev
|
||||||
|
|
||||||
pkgname='ahriman'
|
pkgbase='ahriman'
|
||||||
|
pkgname=('ahriman' 'ahriman-core' 'ahriman-triggers' 'ahriman-web')
|
||||||
pkgver=2.15.2
|
pkgver=2.15.2
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc="ArcH linux ReposItory MANager"
|
pkgdesc="ArcH linux ReposItory MANager"
|
||||||
arch=('any')
|
arch=('any')
|
||||||
url="https://github.com/arcan1s/ahriman"
|
url="https://ahriman.readthedocs.io/"
|
||||||
license=('GPL3')
|
license=('GPL-3.0-or-later')
|
||||||
depends=('devtools>=1:1.0.0' 'git' 'pyalpm' 'python-bcrypt' 'python-inflection' 'python-pyelftools' 'python-requests')
|
depends=('devtools>=1:1.0.0' 'git' 'pyalpm' 'python-bcrypt' 'python-inflection' 'python-pyelftools' 'python-requests')
|
||||||
makedepends=('python-build' 'python-flit' 'python-installer' 'python-wheel')
|
makedepends=('python-build' 'python-flit' 'python-installer' 'python-wheel')
|
||||||
optdepends=('python-aioauth-client: web server with OAuth2 authorization'
|
source=("https://github.com/arcan1s/ahriman/releases/download/$pkgver/$pkgbase-$pkgver.tar.gz"
|
||||||
'python-aiohttp: web server'
|
"$pkgbase.sysusers"
|
||||||
'python-aiohttp-apispec>=3.0.0: web server'
|
"$pkgbase.tmpfiles")
|
||||||
'python-aiohttp-cors: web server'
|
|
||||||
'python-aiohttp-jinja2: web server'
|
|
||||||
'python-aiohttp-security: web server with authorization'
|
|
||||||
'python-aiohttp-session: web server with authorization'
|
|
||||||
'python-boto3: sync to s3'
|
|
||||||
'python-cerberus: configuration validator'
|
|
||||||
'python-cryptography: web server with authorization'
|
|
||||||
'python-matplotlib: usage statistics chart'
|
|
||||||
'python-requests-unixsocket2: client report to web server by unix socket'
|
|
||||||
'python-jinja: html report generation'
|
|
||||||
'python-systemd: journal support'
|
|
||||||
'rsync: sync by using rsync')
|
|
||||||
source=("https://github.com/arcan1s/ahriman/releases/download/$pkgver/$pkgname-$pkgver.tar.gz"
|
|
||||||
'ahriman.sysusers'
|
|
||||||
'ahriman.tmpfiles')
|
|
||||||
install="$pkgname.install"
|
|
||||||
backup=('etc/ahriman.ini'
|
|
||||||
'etc/ahriman.ini.d/logging.ini')
|
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
cd "$pkgname-$pkgver"
|
cd "$pkgbase-$pkgver"
|
||||||
|
|
||||||
python -m build --wheel --no-isolation
|
python -m build --wheel --no-isolation
|
||||||
}
|
}
|
||||||
|
|
||||||
package() {
|
package_ahriman() {
|
||||||
cd "$pkgname-$pkgver"
|
pkgname='ahriman'
|
||||||
|
pkgdesc="ArcH linux ReposItory MANager (meta package)"
|
||||||
python -m installer --destdir="$pkgdir" "dist/$pkgname-$pkgver-py3-none-any.whl"
|
depends=("$pkgbase-core=$pkgver" "$pkgbase-triggers=$pkgver" "$pkgbase-web=$pkgver")
|
||||||
|
}
|
||||||
# keep usr/share configs as reference and copy them to /etc
|
|
||||||
install -Dm644 "$pkgdir/usr/share/$pkgname/settings/ahriman.ini" "$pkgdir/etc/ahriman.ini"
|
package_ahriman-core() {
|
||||||
install -Dm644 "$pkgdir/usr/share/$pkgname/settings/ahriman.ini.d/logging.ini" "$pkgdir/etc/ahriman.ini.d/logging.ini"
|
pkgname='ahriman-core'
|
||||||
|
optdepends=('ahriman-triggers: additional extensions for the application'
|
||||||
install -Dm644 "$srcdir/$pkgname.sysusers" "$pkgdir/usr/lib/sysusers.d/$pkgname.conf"
|
'ahriman-web: web server'
|
||||||
install -Dm644 "$srcdir/$pkgname.tmpfiles" "$pkgdir/usr/lib/tmpfiles.d/$pkgname.conf"
|
'python-boto3: sync to s3'
|
||||||
|
'python-cerberus: configuration validator'
|
||||||
|
'python-matplotlib: usage statistics chart'
|
||||||
|
'python-requests-unixsocket2: client report to web server by unix socket'
|
||||||
|
'python-jinja: html report generation'
|
||||||
|
'python-systemd: journal support'
|
||||||
|
'rsync: sync by using rsync')
|
||||||
|
install="$pkgbase.install"
|
||||||
|
backup=('etc/ahriman.ini'
|
||||||
|
'etc/ahriman.ini.d/logging.ini')
|
||||||
|
|
||||||
|
cd "$pkgbase-$pkgver"
|
||||||
|
|
||||||
|
python -m installer --destdir="$pkgdir" "dist/$pkgbase-$pkgver-py3-none-any.whl"
|
||||||
|
python subpackages.py "$pkgdir" "$pkgname"
|
||||||
|
|
||||||
|
# keep usr/share configs as reference and copy them to /etc
|
||||||
|
install -Dm644 "$pkgdir/usr/share/$pkgbase/settings/ahriman.ini" "$pkgdir/etc/ahriman.ini"
|
||||||
|
install -Dm644 "$pkgdir/usr/share/$pkgbase/settings/ahriman.ini.d/logging.ini" "$pkgdir/etc/ahriman.ini.d/logging.ini"
|
||||||
|
|
||||||
|
install -Dm644 "$srcdir/$pkgbase.sysusers" "$pkgdir/usr/lib/sysusers.d/$pkgbase.conf"
|
||||||
|
install -Dm644 "$srcdir/$pkgbase.tmpfiles" "$pkgdir/usr/lib/tmpfiles.d/$pkgbase.conf"
|
||||||
|
}
|
||||||
|
|
||||||
|
package_ahriman-triggers() {
|
||||||
|
pkgname='ahriman-triggers'
|
||||||
|
pkgdesc="ArcH linux ReposItory MANager, additional extensions"
|
||||||
|
depends=("$pkgbase-core=$pkgver")
|
||||||
|
backup=('etc/ahriman.ini.d/00-triggers.ini')
|
||||||
|
|
||||||
|
cd "$pkgbase-$pkgver"
|
||||||
|
|
||||||
|
python -m installer --destdir="$pkgdir" "dist/$pkgbase-$pkgver-py3-none-any.whl"
|
||||||
|
python subpackages.py "$pkgdir" "$pkgname"
|
||||||
|
|
||||||
|
install -Dm644 "$pkgdir/usr/share/$pkgbase/settings/ahriman.ini.d/00-triggers.ini" "$pkgdir/etc/ahriman.ini.d/00-triggers.ini"
|
||||||
|
}
|
||||||
|
|
||||||
|
package_ahriman-web() {
|
||||||
|
pkgname='ahriman-web'
|
||||||
|
pkgdesc="ArcH linux ReposItory MANager, web server"
|
||||||
|
depends=("$pkgbase-core=$pkgver" 'python-aiohttp-apispec>=3.0.0' 'python-aiohttp-cors' 'python-aiohttp-jinja2')
|
||||||
|
optdepends=('python-aioauth-client: OAuth2 authorization support'
|
||||||
|
'python-aiohttp-security: authorization support'
|
||||||
|
'python-aiohttp-session: authorization support'
|
||||||
|
'python-cryptography: authorization support')
|
||||||
|
backup=('etc/ahriman.ini.d/00-web.ini')
|
||||||
|
|
||||||
|
cd "$pkgbase-$pkgver"
|
||||||
|
|
||||||
|
python -m installer --destdir="$pkgdir" "dist/$pkgbase-$pkgver-py3-none-any.whl"
|
||||||
|
python subpackages.py "$pkgdir" "$pkgname"
|
||||||
|
|
||||||
|
install -Dm644 "$pkgdir/usr/share/$pkgbase/settings/ahriman.ini.d/00-web.ini" "$pkgdir/etc/ahriman.ini.d/00-web.ini"
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ post_upgrade() {
|
|||||||
local breakpoints=(
|
local breakpoints=(
|
||||||
2.9.0-1
|
2.9.0-1
|
||||||
2.12.0-1
|
2.12.0-1
|
||||||
|
2.16.0-1
|
||||||
)
|
)
|
||||||
|
|
||||||
for v in "${breakpoints[@]}"; do
|
for v in "${breakpoints[@]}"; do
|
||||||
|
@ -23,32 +23,6 @@ sync_files_database = yes
|
|||||||
; as additional option for some subcommands). If set to no, databases must be synchronized manually.
|
; as additional option for some subcommands). If set to no, databases must be synchronized manually.
|
||||||
use_ahriman_cache = yes
|
use_ahriman_cache = yes
|
||||||
|
|
||||||
[auth]
|
|
||||||
; Authentication provider, must be one of disabled, configuration, pam, oauth.
|
|
||||||
target = disabled
|
|
||||||
; Allow read-only endpoint to be called without authentication.
|
|
||||||
allow_read_only = yes
|
|
||||||
; OAuth2 application client ID and secret. Required if oauth is used.
|
|
||||||
;client_id =
|
|
||||||
;client_secret =
|
|
||||||
; Cookie secret key to be used for cookies encryption. Must be valid 32 bytes URL-safe base64-encoded string.
|
|
||||||
; If not set, it will be generated automatically.
|
|
||||||
;cookie_secret_key =
|
|
||||||
; Name of the secondary group to be used as admin group in the service. Required if pam is used.
|
|
||||||
;full_access_group = wheel
|
|
||||||
; Authentication cookie expiration in seconds.
|
|
||||||
;max_age = 604800
|
|
||||||
; OAuth2 provider icon for the web interface.
|
|
||||||
;oauth_icon = google
|
|
||||||
; OAuth2 provider class name, one of provided by aioauth-client. Required if oauth is used.
|
|
||||||
;oauth_provider = GoogleClient
|
|
||||||
; Scopes list for OAuth2 provider. Required if oauth is used.
|
|
||||||
;oauth_scopes = https://www.googleapis.com/auth/userinfo.email
|
|
||||||
; Allow login as root user (only applicable if PAM is used).
|
|
||||||
;permit_root_login = no
|
|
||||||
; Optional password salt.
|
|
||||||
;salt =
|
|
||||||
|
|
||||||
[build]
|
[build]
|
||||||
; List of additional flags passed to archbuild command.
|
; List of additional flags passed to archbuild command.
|
||||||
;archbuild_flags =
|
;archbuild_flags =
|
||||||
@ -70,20 +44,12 @@ triggers[] = ahriman.core.report.ReportTrigger
|
|||||||
triggers[] = ahriman.core.upload.UploadTrigger
|
triggers[] = ahriman.core.upload.UploadTrigger
|
||||||
triggers[] = ahriman.core.gitremote.RemotePushTrigger
|
triggers[] = ahriman.core.gitremote.RemotePushTrigger
|
||||||
; List of well-known triggers. Used only for configuration purposes.
|
; List of well-known triggers. Used only for configuration purposes.
|
||||||
triggers_known[] = ahriman.core.distributed.WorkerLoaderTrigger
|
|
||||||
triggers_known[] = ahriman.core.distributed.WorkerTrigger
|
|
||||||
triggers_known[] = ahriman.core.gitremote.RemotePullTrigger
|
triggers_known[] = ahriman.core.gitremote.RemotePullTrigger
|
||||||
triggers_known[] = ahriman.core.gitremote.RemotePushTrigger
|
triggers_known[] = ahriman.core.gitremote.RemotePushTrigger
|
||||||
triggers_known[] = ahriman.core.report.ReportTrigger
|
triggers_known[] = ahriman.core.report.ReportTrigger
|
||||||
triggers_known[] = ahriman.core.support.KeyringTrigger
|
|
||||||
triggers_known[] = ahriman.core.support.MirrorlistTrigger
|
|
||||||
triggers_known[] = ahriman.core.upload.UploadTrigger
|
triggers_known[] = ahriman.core.upload.UploadTrigger
|
||||||
; Maximal age in seconds of the VCS packages before their version will be updated with its remote source.
|
; Maximal age in seconds of the VCS packages before their version will be updated with its remote source.
|
||||||
;vcs_allowed_age = 604800
|
;vcs_allowed_age = 604800
|
||||||
; List of worker nodes addresses used for build process, e.g.:
|
|
||||||
; workers = http://10.0.0.1:8080 http://10.0.0.3:8080
|
|
||||||
; Empty list means run on the local instance.
|
|
||||||
;workers =
|
|
||||||
|
|
||||||
[repository]
|
[repository]
|
||||||
; Application root.
|
; Application root.
|
||||||
@ -112,79 +78,6 @@ suppress_http_log_errors = yes
|
|||||||
; Optional username for authentication (if enabled).
|
; Optional username for authentication (if enabled).
|
||||||
;username =
|
;username =
|
||||||
|
|
||||||
[web]
|
|
||||||
; External address of the web service. Will be used for some features like OAuth. If none set will be generated as
|
|
||||||
; address = http://${web:host}:${web:port}
|
|
||||||
;address = http://${web:host}:${web:port}
|
|
||||||
; Enable file upload endpoint used by some triggers.
|
|
||||||
;enable_archive_upload = no
|
|
||||||
; Address to bind the server.
|
|
||||||
host = 127.0.0.1
|
|
||||||
; Full URL to the repository index page used by templates.
|
|
||||||
;index_url =
|
|
||||||
; Max file size in bytes which can be uploaded to the server. Requires ${web:enable_archive_upload} to be enabled.
|
|
||||||
;max_body_size =
|
|
||||||
; Port to listen. Must be set, if the web service is enabled.
|
|
||||||
;port =
|
|
||||||
; Disable status (e.g. package status, logs, etc) endpoints. Useful for build only modes.
|
|
||||||
;service_only = no
|
|
||||||
; Path to directory with static files.
|
|
||||||
static_path = ${templates}/static
|
|
||||||
; List of directories with templates.
|
|
||||||
templates[] = ${prefix}/share/ahriman/templates
|
|
||||||
; Path to unix socket. If none set, unix socket will be disabled.
|
|
||||||
;unix_socket =
|
|
||||||
; Allow unix socket to be world readable.
|
|
||||||
;unix_socket_unsafe = yes
|
|
||||||
; Maximum amount of time in seconds to be waited before lock will be free, used by spawned processes (0 is infinite).
|
|
||||||
;wait_timeout =
|
|
||||||
|
|
||||||
[keyring]
|
|
||||||
; List of configuration section names for keyring generator plugin, e.g.:
|
|
||||||
; target = keyring-trigger
|
|
||||||
target =
|
|
||||||
|
|
||||||
; Keyring generator trigger sample.
|
|
||||||
;[keyring-trigger]
|
|
||||||
; Generator type name.
|
|
||||||
;type = keyring-generator
|
|
||||||
; Optional keyring package description.
|
|
||||||
;description=
|
|
||||||
; Optional URL to the repository homepage.
|
|
||||||
;homepage=
|
|
||||||
; Keyring package licenses list.
|
|
||||||
;license = Unlicense
|
|
||||||
; Optional keyring package name.
|
|
||||||
;package =
|
|
||||||
; Optional packager PGP keys list. If none set, it will read from database.
|
|
||||||
;packagers =
|
|
||||||
; List of revoked PGP keys.
|
|
||||||
;revoked =
|
|
||||||
; List of master PGP keys. If none set, the sign.key value will be used.
|
|
||||||
;trusted =
|
|
||||||
|
|
||||||
[mirrorlist]
|
|
||||||
; List of configuration section names for mirrorlist generator plugin, e.g.:
|
|
||||||
; target = mirrorlist-trigger
|
|
||||||
target =
|
|
||||||
|
|
||||||
; Mirror list generator trigger sample.
|
|
||||||
;[mirrorlist-trigger]
|
|
||||||
; Generator type name.
|
|
||||||
;type = mirrorlist-generator
|
|
||||||
; Optional mirrorlist package description.
|
|
||||||
;description=
|
|
||||||
; Optional URL to the repository homepage.
|
|
||||||
;homepage=
|
|
||||||
; Mirrorlist package licenses list.
|
|
||||||
;license = Unlicense
|
|
||||||
; Optional mirrorlist package name.
|
|
||||||
;package =
|
|
||||||
; Absolute path to generated mirrorlist file, usually path inside /etc/pacman.d directory.
|
|
||||||
;path =
|
|
||||||
; List of repository mirrors.
|
|
||||||
;servers =
|
|
||||||
|
|
||||||
[remote-pull]
|
[remote-pull]
|
||||||
; List of configuration section names for git remote pull plugin, e.g.:
|
; List of configuration section names for git remote pull plugin, e.g.:
|
||||||
; target = remote-pull-trigger
|
; target = remote-pull-trigger
|
||||||
|
56
package/share/ahriman/settings/ahriman.ini.d/00-triggers.ini
Normal file
56
package/share/ahriman/settings/ahriman.ini.d/00-triggers.ini
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
[build]
|
||||||
|
; List of well-known triggers. Used only for configuration purposes.
|
||||||
|
triggers_known[] = ahriman.core.distributed.WorkerLoaderTrigger
|
||||||
|
triggers_known[] = ahriman.core.distributed.WorkerTrigger
|
||||||
|
triggers_known[] = ahriman.core.support.KeyringTrigger
|
||||||
|
triggers_known[] = ahriman.core.support.MirrorlistTrigger
|
||||||
|
; List of worker nodes addresses used for build process, e.g.:
|
||||||
|
; workers = http://10.0.0.1:8080 http://10.0.0.3:8080
|
||||||
|
; Empty list means run on the local instance.
|
||||||
|
;workers =
|
||||||
|
|
||||||
|
[keyring]
|
||||||
|
; List of configuration section names for keyring generator plugin, e.g.:
|
||||||
|
; target = keyring-trigger
|
||||||
|
target =
|
||||||
|
|
||||||
|
; Keyring generator trigger sample.
|
||||||
|
;[keyring-trigger]
|
||||||
|
; Generator type name.
|
||||||
|
;type = keyring-generator
|
||||||
|
; Optional keyring package description.
|
||||||
|
;description=
|
||||||
|
; Optional URL to the repository homepage.
|
||||||
|
;homepage=
|
||||||
|
; Keyring package licenses list.
|
||||||
|
;license = Unlicense
|
||||||
|
; Optional keyring package name.
|
||||||
|
;package =
|
||||||
|
; Optional packager PGP keys list. If none set, it will read from database.
|
||||||
|
;packagers =
|
||||||
|
; List of revoked PGP keys.
|
||||||
|
;revoked =
|
||||||
|
; List of master PGP keys. If none set, the sign.key value will be used.
|
||||||
|
;trusted =
|
||||||
|
|
||||||
|
[mirrorlist]
|
||||||
|
; List of configuration section names for mirrorlist generator plugin, e.g.:
|
||||||
|
; target = mirrorlist-trigger
|
||||||
|
target =
|
||||||
|
|
||||||
|
; Mirror list generator trigger sample.
|
||||||
|
;[mirrorlist-trigger]
|
||||||
|
; Generator type name.
|
||||||
|
;type = mirrorlist-generator
|
||||||
|
; Optional mirrorlist package description.
|
||||||
|
;description=
|
||||||
|
; Optional URL to the repository homepage.
|
||||||
|
;homepage=
|
||||||
|
; Mirrorlist package licenses list.
|
||||||
|
;license = Unlicense
|
||||||
|
; Optional mirrorlist package name.
|
||||||
|
;package =
|
||||||
|
; Absolute path to generated mirrorlist file, usually path inside /etc/pacman.d directory.
|
||||||
|
;path =
|
||||||
|
; List of repository mirrors.
|
||||||
|
;servers =
|
52
package/share/ahriman/settings/ahriman.ini.d/00-web.ini
Normal file
52
package/share/ahriman/settings/ahriman.ini.d/00-web.ini
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
[auth]
|
||||||
|
; Authentication provider, must be one of disabled, configuration, pam, oauth.
|
||||||
|
target = disabled
|
||||||
|
; Allow read-only endpoint to be called without authentication.
|
||||||
|
allow_read_only = yes
|
||||||
|
; OAuth2 application client ID and secret. Required if oauth is used.
|
||||||
|
;client_id =
|
||||||
|
;client_secret =
|
||||||
|
; Cookie secret key to be used for cookies encryption. Must be valid 32 bytes URL-safe base64-encoded string.
|
||||||
|
; If not set, it will be generated automatically.
|
||||||
|
;cookie_secret_key =
|
||||||
|
; Name of the secondary group to be used as admin group in the service. Required if pam is used.
|
||||||
|
;full_access_group = wheel
|
||||||
|
; Authentication cookie expiration in seconds.
|
||||||
|
;max_age = 604800
|
||||||
|
; OAuth2 provider icon for the web interface.
|
||||||
|
;oauth_icon = google
|
||||||
|
; OAuth2 provider class name, one of provided by aioauth-client. Required if oauth is used.
|
||||||
|
;oauth_provider = GoogleClient
|
||||||
|
; Scopes list for OAuth2 provider. Required if oauth is used.
|
||||||
|
;oauth_scopes = https://www.googleapis.com/auth/userinfo.email
|
||||||
|
; Allow login as root user (only applicable if PAM is used).
|
||||||
|
;permit_root_login = no
|
||||||
|
; Optional password salt.
|
||||||
|
;salt =
|
||||||
|
|
||||||
|
[web]
|
||||||
|
; External address of the web service. Will be used for some features like OAuth. If none set will be generated as
|
||||||
|
; address = http://${web:host}:${web:port}
|
||||||
|
;address = http://${web:host}:${web:port}
|
||||||
|
; Enable file upload endpoint used by some triggers.
|
||||||
|
;enable_archive_upload = no
|
||||||
|
; Address to bind the server.
|
||||||
|
host = 127.0.0.1
|
||||||
|
; Full URL to the repository index page used by templates.
|
||||||
|
;index_url =
|
||||||
|
; Max file size in bytes which can be uploaded to the server. Requires ${web:enable_archive_upload} to be enabled.
|
||||||
|
;max_body_size =
|
||||||
|
; Port to listen. Must be set, if the web service is enabled.
|
||||||
|
;port =
|
||||||
|
; Disable status (e.g. package status, logs, etc) endpoints. Useful for build only modes.
|
||||||
|
;service_only = no
|
||||||
|
; Path to directory with static files.
|
||||||
|
static_path = ${templates}/static
|
||||||
|
; List of directories with templates.
|
||||||
|
templates[] = ${prefix}/share/ahriman/templates
|
||||||
|
; Path to unix socket. If none set, unix socket will be disabled.
|
||||||
|
;unix_socket =
|
||||||
|
; Allow unix socket to be world readable.
|
||||||
|
;unix_socket_unsafe = yes
|
||||||
|
; Maximum amount of time in seconds to be waited before lock will be free, used by spawned processes (0 is infinite).
|
||||||
|
;wait_timeout =
|
@ -30,12 +30,14 @@ class ImportType(StrEnum):
|
|||||||
import type enumeration
|
import type enumeration
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
|
Future(MethodTypeOrder): (class attribute) from __future__ import
|
||||||
Package(MethodTypeOrder): (class attribute) package import
|
Package(MethodTypeOrder): (class attribute) package import
|
||||||
PackageFrom(MethodTypeOrder): (class attribute) package import, from clause
|
PackageFrom(MethodTypeOrder): (class attribute) package import, from clause
|
||||||
System(ImportType): (class attribute) system installed packages
|
System(ImportType): (class attribute) system installed packages
|
||||||
SystemFrom(MethodTypeOrder): (class attribute) system installed packages, from clause
|
SystemFrom(MethodTypeOrder): (class attribute) system installed packages, from clause
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
Future = "future"
|
||||||
Package = "package"
|
Package = "package"
|
||||||
PackageFrom = "package-from"
|
PackageFrom = "package-from"
|
||||||
System = "system"
|
System = "system"
|
||||||
@ -70,6 +72,7 @@ class ImportOrder(BaseRawFileChecker):
|
|||||||
"import-type-order",
|
"import-type-order",
|
||||||
{
|
{
|
||||||
"default": [
|
"default": [
|
||||||
|
"future",
|
||||||
"system",
|
"system",
|
||||||
"system-from",
|
"system-from",
|
||||||
"package",
|
"package",
|
||||||
@ -91,7 +94,7 @@ class ImportOrder(BaseRawFileChecker):
|
|||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def imports(source: Iterable[Any], start_lineno: int = 0) -> list[nodes.Import | nodes.ImportFrom]:
|
def imports(source: Iterable[Any], start_lineno: int = 0) -> Iterable[nodes.Import | nodes.ImportFrom]:
|
||||||
"""
|
"""
|
||||||
extract import nodes from list of raw nodes
|
extract import nodes from list of raw nodes
|
||||||
|
|
||||||
@ -100,7 +103,7 @@ class ImportOrder(BaseRawFileChecker):
|
|||||||
start_lineno(int, optional): minimal allowed line number (Default value = 0)
|
start_lineno(int, optional): minimal allowed line number (Default value = 0)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list[nodes.Import | nodes.ImportFrom]: list of import nodes
|
Iterable[nodes.Import | nodes.ImportFrom]: list of import nodes
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def is_defined_import(imports: Any) -> bool:
|
def is_defined_import(imports: Any) -> bool:
|
||||||
@ -108,7 +111,7 @@ class ImportOrder(BaseRawFileChecker):
|
|||||||
and imports.lineno is not None \
|
and imports.lineno is not None \
|
||||||
and imports.lineno >= start_lineno
|
and imports.lineno >= start_lineno
|
||||||
|
|
||||||
return list(filter(is_defined_import, source))
|
return sorted(filter(is_defined_import, source), key=lambda imports: imports.lineno)
|
||||||
|
|
||||||
def check_from_imports(self, imports: nodes.ImportFrom) -> None:
|
def check_from_imports(self, imports: nodes.ImportFrom) -> None:
|
||||||
"""
|
"""
|
||||||
@ -124,30 +127,36 @@ class ImportOrder(BaseRawFileChecker):
|
|||||||
self.add_message("from-imports-out-of-order", line=imports.lineno, args=(real, expected))
|
self.add_message("from-imports-out-of-order", line=imports.lineno, args=(real, expected))
|
||||||
break
|
break
|
||||||
|
|
||||||
def check_imports(self, imports: list[nodes.Import | nodes.ImportFrom], root_package: str) -> None:
|
def check_imports(self, imports: Iterable[nodes.Import | nodes.ImportFrom], root_package: str) -> None:
|
||||||
"""
|
"""
|
||||||
check imports
|
check imports
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
imports(list[nodes.Import | nodes.ImportFrom]): list of imports in their defined order
|
imports(Iterable[nodes.Import | nodes.ImportFrom]): list of imports in their defined order
|
||||||
root_package(str): root package name
|
root_package(str): root package name
|
||||||
"""
|
"""
|
||||||
last_statement: tuple[int, str] | None = None
|
last_statement: tuple[int, str] | None = None
|
||||||
|
|
||||||
for statement in imports:
|
for statement in imports:
|
||||||
# define types and perform specific checks
|
# define types and perform specific checks
|
||||||
if isinstance(statement, nodes.ImportFrom):
|
match statement:
|
||||||
import_name = statement.modname
|
case nodes.ImportFrom() if statement.modname == "__future__":
|
||||||
root, *_ = import_name.split(".", maxsplit=1)
|
import_name = statement.modname
|
||||||
import_type = ImportType.PackageFrom if root_package == root else ImportType.SystemFrom
|
import_type = ImportType.Future
|
||||||
# check from import itself
|
case nodes.ImportFrom():
|
||||||
self.check_from_imports(statement)
|
import_name = statement.modname
|
||||||
else:
|
root, *_ = import_name.split(".", maxsplit=1)
|
||||||
import_name = next(name for name, _ in statement.names)
|
import_type = ImportType.PackageFrom if root_package == root else ImportType.SystemFrom
|
||||||
root, *_ = import_name.split(".", maxsplit=1)[0]
|
# check from import itself
|
||||||
import_type = ImportType.Package if root_package == root else ImportType.System
|
self.check_from_imports(statement)
|
||||||
# check import itself
|
case nodes.Import():
|
||||||
self.check_package_imports(statement)
|
import_name = next(name for name, _ in statement.names)
|
||||||
|
root, *_ = import_name.split(".", maxsplit=1)
|
||||||
|
import_type = ImportType.Package if root_package == root else ImportType.System
|
||||||
|
# check import itself
|
||||||
|
self.check_package_imports(statement)
|
||||||
|
case _:
|
||||||
|
continue
|
||||||
|
|
||||||
# extract index
|
# extract index
|
||||||
try:
|
try:
|
||||||
|
@ -95,6 +95,7 @@ include = [
|
|||||||
"CONTRIBUTING.md",
|
"CONTRIBUTING.md",
|
||||||
"SECURITY.md",
|
"SECURITY.md",
|
||||||
"package",
|
"package",
|
||||||
|
"subpackages.py",
|
||||||
"web.png",
|
"web.png",
|
||||||
]
|
]
|
||||||
exclude = [
|
exclude = [
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -17,37 +17,3 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
from ahriman.application.handlers.add import Add
|
|
||||||
from ahriman.application.handlers.backup import Backup
|
|
||||||
from ahriman.application.handlers.change import Change
|
|
||||||
from ahriman.application.handlers.clean import Clean
|
|
||||||
from ahriman.application.handlers.copy import Copy
|
|
||||||
from ahriman.application.handlers.daemon import Daemon
|
|
||||||
from ahriman.application.handlers.dump import Dump
|
|
||||||
from ahriman.application.handlers.handler import Handler
|
|
||||||
from ahriman.application.handlers.help import Help
|
|
||||||
from ahriman.application.handlers.key_import import KeyImport
|
|
||||||
from ahriman.application.handlers.patch import Patch
|
|
||||||
from ahriman.application.handlers.rebuild import Rebuild
|
|
||||||
from ahriman.application.handlers.remove import Remove
|
|
||||||
from ahriman.application.handlers.remove_unknown import RemoveUnknown
|
|
||||||
from ahriman.application.handlers.repositories import Repositories
|
|
||||||
from ahriman.application.handlers.restore import Restore
|
|
||||||
from ahriman.application.handlers.run import Run
|
|
||||||
from ahriman.application.handlers.search import Search
|
|
||||||
from ahriman.application.handlers.service_updates import ServiceUpdates
|
|
||||||
from ahriman.application.handlers.setup import Setup
|
|
||||||
from ahriman.application.handlers.shell import Shell
|
|
||||||
from ahriman.application.handlers.sign import Sign
|
|
||||||
from ahriman.application.handlers.statistics import Statistics
|
|
||||||
from ahriman.application.handlers.status import Status
|
|
||||||
from ahriman.application.handlers.status_update import StatusUpdate
|
|
||||||
from ahriman.application.handlers.structure import Structure
|
|
||||||
from ahriman.application.handlers.tree_migrate import TreeMigrate
|
|
||||||
from ahriman.application.handlers.triggers import Triggers
|
|
||||||
from ahriman.application.handlers.unsafe_commands import UnsafeCommands
|
|
||||||
from ahriman.application.handlers.update import Update
|
|
||||||
from ahriman.application.handlers.users import Users
|
|
||||||
from ahriman.application.handlers.validate import Validate
|
|
||||||
from ahriman.application.handlers.versions import Versions
|
|
||||||
from ahriman.application.handlers.web import Web
|
|
||||||
|
@ -20,8 +20,10 @@
|
|||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
from ahriman.application.application import Application
|
from ahriman.application.application import Application
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
|
from ahriman.core.utils import enum_values, extract_user
|
||||||
|
from ahriman.models.package_source import PackageSource
|
||||||
from ahriman.models.packagers import Packagers
|
from ahriman.models.packagers import Packagers
|
||||||
from ahriman.models.pkgbuild_patch import PkgbuildPatch
|
from ahriman.models.pkgbuild_patch import PkgbuildPatch
|
||||||
from ahriman.models.repository_id import RepositoryId
|
from ahriman.models.repository_id import RepositoryId
|
||||||
@ -66,3 +68,49 @@ class Add(Handler):
|
|||||||
application.print_updates(packages, log_fn=application.logger.info)
|
application.print_updates(packages, log_fn=application.logger.info)
|
||||||
result = application.update(packages, packagers, bump_pkgrel=args.increment)
|
result = application.update(packages, packagers, bump_pkgrel=args.increment)
|
||||||
Add.check_status(args.exit_code, not result.is_empty)
|
Add.check_status(args.exit_code, not result.is_empty)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_package_add_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for package addition subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("package-add", aliases=["add", "package-update"], help="add package",
|
||||||
|
description="add existing or new package to the build queue",
|
||||||
|
epilog="This subcommand should be used for new package addition. "
|
||||||
|
"It also supports flag --now in case if you would like to build "
|
||||||
|
"the package immediately. You can add new package from one of "
|
||||||
|
"supported sources:\n\n"
|
||||||
|
"1. If it is already built package you can specify the path to the archive.\n"
|
||||||
|
"2. You can also add built packages from the directory (e.g. during the "
|
||||||
|
"migration from another repository source).\n"
|
||||||
|
"3. It is also possible to add package from local PKGBUILD, but in this case "
|
||||||
|
"it will be ignored during the next automatic updates.\n"
|
||||||
|
"4. Ahriman supports downloading archives from remote (e.g. HTTP) sources.\n"
|
||||||
|
"5. Finally you can add package from AUR.")
|
||||||
|
parser.add_argument("package", help="package source (base name, path to local files, remote URL)", nargs="+")
|
||||||
|
parser.add_argument("--changes", help="calculate changes from the latest known commit if available",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("--dependencies", help="process missing package dependencies",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty",
|
||||||
|
action="store_true")
|
||||||
|
parser.add_argument("--increment", help="increment package release (pkgrel) version on duplicate",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("-n", "--now", help="run update function after", action="store_true")
|
||||||
|
parser.add_argument("-y", "--refresh", help="download fresh package databases from the mirror before actions, "
|
||||||
|
"-yy to force refresh even if up to date",
|
||||||
|
action="count", default=False)
|
||||||
|
parser.add_argument("-s", "--source", help="explicitly specify the package source for this command",
|
||||||
|
type=PackageSource, choices=enum_values(PackageSource), default=PackageSource.Auto)
|
||||||
|
parser.add_argument("-u", "--username", help="build as user", default=extract_user())
|
||||||
|
parser.add_argument("-v", "--variable", help="apply specified makepkg variables to the next build",
|
||||||
|
action="append")
|
||||||
|
return parser
|
||||||
|
|
||||||
|
arguments = [_set_package_add_parser]
|
||||||
|
@ -23,7 +23,7 @@ import tarfile
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from pwd import getpwuid
|
from pwd import getpwuid
|
||||||
|
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.database import SQLite
|
from ahriman.core.database import SQLite
|
||||||
from ahriman.models.repository_id import RepositoryId
|
from ahriman.models.repository_id import RepositoryId
|
||||||
@ -53,6 +53,23 @@ class Backup(Handler):
|
|||||||
for backup_path in backup_paths:
|
for backup_path in backup_paths:
|
||||||
archive.add(backup_path)
|
archive.add(backup_path)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_repo_backup_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for repository backup subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("repo-backup", help="backup repository data",
|
||||||
|
description="backup repository settings and database")
|
||||||
|
parser.add_argument("path", help="path of the output archive", type=Path)
|
||||||
|
parser.set_defaults(architecture="", lock=None, report=False, repository="", unsafe=True)
|
||||||
|
return parser
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_paths(configuration: Configuration) -> set[Path]:
|
def get_paths(configuration: Configuration) -> set[Path]:
|
||||||
"""
|
"""
|
||||||
@ -83,3 +100,5 @@ class Backup(Handler):
|
|||||||
paths.add(gnupg_home)
|
paths.add(gnupg_home)
|
||||||
|
|
||||||
return paths
|
return paths
|
||||||
|
|
||||||
|
arguments = [_set_repo_backup_parser]
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
from ahriman.application.application import Application
|
from ahriman.application.application import Application
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.formatters import ChangesPrinter
|
from ahriman.core.formatters import ChangesPrinter
|
||||||
from ahriman.models.action import Action
|
from ahriman.models.action import Action
|
||||||
@ -57,3 +57,43 @@ class Change(Handler):
|
|||||||
Change.check_status(args.exit_code, not changes.is_empty)
|
Change.check_status(args.exit_code, not changes.is_empty)
|
||||||
case Action.Remove:
|
case Action.Remove:
|
||||||
client.package_changes_update(args.package, Changes())
|
client.package_changes_update(args.package, Changes())
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_package_changes_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for package changes subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("package-changes", help="get package changes",
|
||||||
|
description="retrieve package changes stored in database",
|
||||||
|
epilog="This command requests package status from the web interface "
|
||||||
|
"if it is available.")
|
||||||
|
parser.add_argument("package", help="package base")
|
||||||
|
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty",
|
||||||
|
action="store_true")
|
||||||
|
parser.set_defaults(action=Action.List, lock=None, quiet=True, report=False, unsafe=True)
|
||||||
|
return parser
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_package_changes_remove_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for package change remove subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("package-changes-remove", help="remove package changes",
|
||||||
|
description="remove the package changes stored remotely")
|
||||||
|
parser.add_argument("package", help="package base")
|
||||||
|
parser.set_defaults(action=Action.Remove, exit_code=False, lock=None, quiet=True, report=False, unsafe=True)
|
||||||
|
return parser
|
||||||
|
|
||||||
|
arguments = [_set_package_changes_parser, _set_package_changes_remove_parser]
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
from ahriman.application.application import Application
|
from ahriman.application.application import Application
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.models.repository_id import RepositoryId
|
from ahriman.models.repository_id import RepositoryId
|
||||||
|
|
||||||
@ -46,3 +46,33 @@ class Clean(Handler):
|
|||||||
application.on_start()
|
application.on_start()
|
||||||
application.clean(cache=args.cache, chroot=args.chroot, manual=args.manual, packages=args.packages,
|
application.clean(cache=args.cache, chroot=args.chroot, manual=args.manual, packages=args.packages,
|
||||||
pacman=args.pacman)
|
pacman=args.pacman)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_service_clean_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for repository clean subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("service-clean", aliases=["clean", "repo-clean"], help="clean local caches",
|
||||||
|
description="remove local caches",
|
||||||
|
epilog="The subcommand clears every temporary directories (builds, caches etc). "
|
||||||
|
"Normally you should not run this command manually. Also in case if "
|
||||||
|
"you are going to clear the chroot directories you will need root privileges.")
|
||||||
|
parser.add_argument("--cache", help="clear directory with package caches",
|
||||||
|
action=argparse.BooleanOptionalAction, default=False)
|
||||||
|
parser.add_argument("--chroot", help="clear build chroot", action=argparse.BooleanOptionalAction, default=False)
|
||||||
|
parser.add_argument("--manual", help="clear manually added packages queue",
|
||||||
|
action=argparse.BooleanOptionalAction, default=False)
|
||||||
|
parser.add_argument("--packages", help="clear directory with built packages",
|
||||||
|
action=argparse.BooleanOptionalAction, default=False)
|
||||||
|
parser.add_argument("--pacman", help="clear directory with pacman local database cache",
|
||||||
|
action=argparse.BooleanOptionalAction, default=False)
|
||||||
|
parser.set_defaults(lock=None, quiet=True, unsafe=True)
|
||||||
|
return parser
|
||||||
|
|
||||||
|
arguments = [_set_service_clean_parser]
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
from ahriman.application.application import Application
|
from ahriman.application.application import Application
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.models.build_status import BuildStatusEnum
|
from ahriman.models.build_status import BuildStatusEnum
|
||||||
from ahriman.models.package import Package
|
from ahriman.models.package import Package
|
||||||
@ -67,6 +67,26 @@ class Copy(Handler):
|
|||||||
if args.remove:
|
if args.remove:
|
||||||
source_application.remove(args.package)
|
source_application.remove(args.package)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_package_copy_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for package copy subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("package-copy", aliases=["copy"], help="copy package from another repository",
|
||||||
|
description="copy package and its metadata from another repository")
|
||||||
|
parser.add_argument("source", help="source repository name")
|
||||||
|
parser.add_argument("package", help="package base", nargs="+")
|
||||||
|
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty",
|
||||||
|
action="store_true")
|
||||||
|
parser.add_argument("--remove", help="remove package from the source repository after", action="store_true")
|
||||||
|
return parser
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def copy_package(package: Package, application: Application, source_application: Application) -> None:
|
def copy_package(package: Package, application: Application, source_application: Application) -> None:
|
||||||
"""
|
"""
|
||||||
@ -93,3 +113,5 @@ class Copy(Handler):
|
|||||||
package.base, source_application.reporter.package_dependencies_get(package.base)
|
package.base, source_application.reporter.package_dependencies_get(package.base)
|
||||||
)
|
)
|
||||||
application.reporter.package_update(package, BuildStatusEnum.Pending)
|
application.reporter.package_update(package, BuildStatusEnum.Pending)
|
||||||
|
|
||||||
|
arguments = [_set_package_copy_parser]
|
||||||
|
@ -19,11 +19,14 @@
|
|||||||
#
|
#
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
from ahriman.application.application import Application
|
from ahriman.application.application import Application
|
||||||
from ahriman.application.application.updates_iterator import FixedUpdatesIterator, UpdatesIterator
|
from ahriman.application.application.updates_iterator import FixedUpdatesIterator, UpdatesIterator
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.application.handlers.update import Update
|
from ahriman.application.handlers.update import Update
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
|
from ahriman.core.utils import extract_user
|
||||||
from ahriman.models.repository_id import RepositoryId
|
from ahriman.models.repository_id import RepositoryId
|
||||||
|
|
||||||
|
|
||||||
@ -56,3 +59,48 @@ class Daemon(Handler):
|
|||||||
|
|
||||||
args.package = packages
|
args.package = packages
|
||||||
Update.run(args, repository_id, configuration, report=report)
|
Update.run(args, repository_id, configuration, report=report)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_repo_daemon_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for daemon subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("repo-daemon", aliases=["daemon"], help="run application as daemon",
|
||||||
|
description="start process which periodically will run update process")
|
||||||
|
parser.add_argument("-i", "--interval", help="interval between runs in seconds", type=int, default=60 * 60 * 12)
|
||||||
|
parser.add_argument("--aur", help="enable or disable checking for AUR updates",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("--changes", help="calculate changes from the latest known commit if available. "
|
||||||
|
"Only applicable in dry run mode",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("--check-files", help="enable or disable checking of broken dependencies "
|
||||||
|
"(e.g. dynamically linked libraries or modules directories)",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("--dependencies", help="process missing package dependencies",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("--dry-run", help="just perform check for updates, same as check command",
|
||||||
|
action="store_true")
|
||||||
|
parser.add_argument("--increment", help="increment package release (pkgrel) on duplicate",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("--local", help="enable or disable checking of local packages for updates",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("--manual", help="include or exclude manual updates",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("--partitions", help="instead of updating whole repository, split updates into chunks",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("-u", "--username", help="build as user", default=extract_user())
|
||||||
|
parser.add_argument("--vcs", help="fetch actual version of VCS packages",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("-y", "--refresh", help="download fresh package databases from the mirror before actions, "
|
||||||
|
"-yy to force refresh even if up to date",
|
||||||
|
action="count", default=False)
|
||||||
|
parser.set_defaults(exit_code=False, lock=Path("ahriman-daemon.pid"), package=[])
|
||||||
|
return parser
|
||||||
|
|
||||||
|
arguments = [_set_repo_daemon_parser]
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
#
|
#
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.formatters import ConfigurationPathsPrinter, ConfigurationPrinter, StringPrinter
|
from ahriman.core.formatters import ConfigurationPathsPrinter, ConfigurationPrinter, StringPrinter
|
||||||
from ahriman.models.repository_id import RepositoryId
|
from ahriman.models.repository_id import RepositoryId
|
||||||
@ -59,3 +59,27 @@ class Dump(Handler):
|
|||||||
case section, key: # key only
|
case section, key: # key only
|
||||||
value = configuration.get(section, key, fallback="")
|
value = configuration.get(section, key, fallback="")
|
||||||
StringPrinter(value)(verbose=False)
|
StringPrinter(value)(verbose=False)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_service_config_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for config subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("service-config", aliases=["config", "repo-config"], help="dump configuration",
|
||||||
|
description="dump configuration for the specified architecture")
|
||||||
|
parser.add_argument("section", help="filter settings by section", nargs="?")
|
||||||
|
parser.add_argument("key", help="filter settings by key", nargs="?")
|
||||||
|
parser.add_argument("--info", help="show additional information, e.g. configuration files",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("--secure", help="hide passwords and secrets from output",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.set_defaults(lock=None, quiet=True, report=False, unsafe=True)
|
||||||
|
return parser
|
||||||
|
|
||||||
|
arguments = [_set_service_config_parser]
|
||||||
|
@ -22,6 +22,7 @@ import logging
|
|||||||
|
|
||||||
from collections.abc import Callable, Iterable
|
from collections.abc import Callable, Iterable
|
||||||
from multiprocessing import Pool
|
from multiprocessing import Pool
|
||||||
|
from typing import TypeVar
|
||||||
|
|
||||||
from ahriman.application.lock import Lock
|
from ahriman.application.lock import Lock
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
@ -32,12 +33,21 @@ from ahriman.models.repository_id import RepositoryId
|
|||||||
from ahriman.models.repository_paths import RepositoryPaths
|
from ahriman.models.repository_paths import RepositoryPaths
|
||||||
|
|
||||||
|
|
||||||
|
# this workaround is for several things
|
||||||
|
# firstly python devs don't think that is it error and asking you for workarounds https://bugs.python.org/issue41592
|
||||||
|
# secondly linters don't like when you are importing private members
|
||||||
|
# thirdly new mypy doesn't like _SubParsersAction and thinks it is a template
|
||||||
|
SubParserAction = TypeVar("SubParserAction", bound="argparse._SubParsersAction[argparse.ArgumentParser]")
|
||||||
|
|
||||||
|
|
||||||
class Handler:
|
class Handler:
|
||||||
"""
|
"""
|
||||||
base handler class for command callbacks
|
base handler class for command callbacks
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
ALLOW_MULTI_ARCHITECTURE_RUN(bool): (class attribute) allow running with multiple architectures
|
ALLOW_MULTI_ARCHITECTURE_RUN(bool): (class attribute) allow running with multiple architectures
|
||||||
|
arguments(list[Callable[[SubParserAction], argparse.ArgumentParser]]): (class attribute) argument parser
|
||||||
|
methods, which will be called to create command line parsers
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
Wrapper for all command line actions, though each derived class implements :func:`run()` method, it usually
|
Wrapper for all command line actions, though each derived class implements :func:`run()` method, it usually
|
||||||
@ -49,6 +59,7 @@ class Handler:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
ALLOW_MULTI_ARCHITECTURE_RUN = True
|
ALLOW_MULTI_ARCHITECTURE_RUN = True
|
||||||
|
arguments: list[Callable[[SubParserAction], argparse.ArgumentParser]]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def call(cls, args: argparse.Namespace, repository_id: RepositoryId) -> bool:
|
def call(cls, args: argparse.Namespace, repository_id: RepositoryId) -> bool:
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
#
|
#
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.models.repository_id import RepositoryId
|
from ahriman.models.repository_id import RepositoryId
|
||||||
|
|
||||||
@ -48,3 +48,22 @@ class Help(Handler):
|
|||||||
parser.parse_args(["--help"])
|
parser.parse_args(["--help"])
|
||||||
else:
|
else:
|
||||||
parser.parse_args([args.subcommand, "--help"])
|
parser.parse_args([args.subcommand, "--help"])
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_help_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for listing help subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("help", help="show help message",
|
||||||
|
description="show help message for application or command and exit")
|
||||||
|
parser.add_argument("subcommand", help="show help message for specific command", nargs="?")
|
||||||
|
parser.set_defaults(architecture="", lock=None, quiet=True, report=False, repository="", unsafe=True)
|
||||||
|
return parser
|
||||||
|
|
||||||
|
arguments = [_set_help_parser]
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
from ahriman.application.application import Application
|
from ahriman.application.application import Application
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.models.repository_id import RepositoryId
|
from ahriman.models.repository_id import RepositoryId
|
||||||
|
|
||||||
@ -46,3 +46,27 @@ class KeyImport(Handler):
|
|||||||
"""
|
"""
|
||||||
application = Application(repository_id, configuration, report=report)
|
application = Application(repository_id, configuration, report=report)
|
||||||
application.repository.sign.key_import(args.key_server, args.key)
|
application.repository.sign.key_import(args.key_server, args.key)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_service_key_import_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for key import subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("service-key-import", aliases=["key-import"], help="import PGP key",
|
||||||
|
description="import PGP key from public sources to the repository user",
|
||||||
|
epilog="By default ahriman runs build process with package sources validation "
|
||||||
|
"(in case if signature and keys are available in PKGBUILD). This process will "
|
||||||
|
"fail in case if key is not known for build user. This subcommand can be used "
|
||||||
|
"in order to import the PGP key to user keychain.")
|
||||||
|
parser.add_argument("--key-server", help="key server for key import", default="keyserver.ubuntu.com")
|
||||||
|
parser.add_argument("key", help="PGP key to import from public server")
|
||||||
|
parser.set_defaults(architecture="", lock=None, report=False, repository="")
|
||||||
|
return parser
|
||||||
|
|
||||||
|
arguments = [_set_service_key_import_parser]
|
||||||
|
@ -23,7 +23,7 @@ import sys
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from ahriman.application.application import Application
|
from ahriman.application.application import Application
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.core.build_tools.sources import Sources
|
from ahriman.core.build_tools.sources import Sources
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.formatters import PatchPrinter
|
from ahriman.core.formatters import PatchPrinter
|
||||||
@ -67,6 +67,100 @@ class Patch(Handler):
|
|||||||
case Action.Remove:
|
case Action.Remove:
|
||||||
Patch.patch_set_remove(application, args.package, args.variable)
|
Patch.patch_set_remove(application, args.package, args.variable)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_patch_add_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for new single-function patch subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("patch-add", help="add patch for PKGBUILD function",
|
||||||
|
description="create or update patched PKGBUILD function or variable",
|
||||||
|
epilog="Unlike ``patch-set-add``, this function allows to patch only one PKGBUILD "
|
||||||
|
"function, e.g. typing ``ahriman patch-add ahriman pkgver`` it will change the "
|
||||||
|
"``pkgver`` inside PKGBUILD, typing ``ahriman patch-add ahriman build()`` "
|
||||||
|
"it will change ``build()`` function inside PKGBUILD.")
|
||||||
|
parser.add_argument("package", help="package base")
|
||||||
|
parser.add_argument("variable", help="PKGBUILD variable or function name. If variable is a function, "
|
||||||
|
"it must end with ()")
|
||||||
|
parser.add_argument("patch", help="path to file which contains function or variable value. If not set, "
|
||||||
|
"the value will be read from stdin", type=Path, nargs="?")
|
||||||
|
parser.set_defaults(action=Action.Update, architecture="", exit_code=False, lock=None, report=False,
|
||||||
|
repository="")
|
||||||
|
return parser
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_patch_list_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for list patches subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("patch-list", help="list patch sets",
|
||||||
|
description="list available patches for the package")
|
||||||
|
parser.add_argument("package", help="package base")
|
||||||
|
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty",
|
||||||
|
action="store_true")
|
||||||
|
parser.add_argument("-v", "--variable", help="if set, show only patches for specified PKGBUILD variables",
|
||||||
|
action="append")
|
||||||
|
parser.set_defaults(action=Action.List, architecture="", lock=None, report=False, repository="", unsafe=True)
|
||||||
|
return parser
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_patch_remove_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for remove patches subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("patch-remove", help="remove patch set", description="remove patches for the package")
|
||||||
|
parser.add_argument("package", help="package base")
|
||||||
|
parser.add_argument("-v", "--variable",
|
||||||
|
help="should be used for single-function patches in case if you wold like "
|
||||||
|
"to remove only specified PKGBUILD variables. In case if not set, "
|
||||||
|
"it will remove all patches related to the package",
|
||||||
|
action="append")
|
||||||
|
parser.set_defaults(action=Action.Remove, architecture="", exit_code=False, lock=None, report=False,
|
||||||
|
repository="")
|
||||||
|
return parser
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_patch_set_add_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for new full-diff patch subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("patch-set-add", help="add patch set", description="create or update source patches",
|
||||||
|
epilog="In order to add a patch set for the package you will need to:\n\n"
|
||||||
|
"1. Clone the AUR package manually.\n"
|
||||||
|
"2. Add required changes (e.g. external patches, edit PKGBUILD).\n"
|
||||||
|
"3. Run command, e.g. ``ahriman patch-set-add path/to/directory``.\n\n"
|
||||||
|
"By default it tracks ``*.patch`` and ``*.diff`` files, but this behavior "
|
||||||
|
"can be changed by using ``--track`` option.")
|
||||||
|
parser.add_argument("package", help="path to directory with changed files for patch addition/update", type=Path)
|
||||||
|
parser.add_argument("-t", "--track", help="files which has to be tracked", action="append",
|
||||||
|
default=["*.diff", "*.patch"])
|
||||||
|
parser.set_defaults(action=Action.Update, architecture="", exit_code=False, lock=None, report=False,
|
||||||
|
repository="", variable=None)
|
||||||
|
return parser
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def patch_create_from_diff(sources_dir: Path, architecture: str, track: list[str]) -> tuple[str, PkgbuildPatch]:
|
def patch_create_from_diff(sources_dir: Path, architecture: str, track: list[str]) -> tuple[str, PkgbuildPatch]:
|
||||||
"""
|
"""
|
||||||
@ -155,3 +249,10 @@ class Patch(Handler):
|
|||||||
application.reporter.package_patches_remove(package_base, variable)
|
application.reporter.package_patches_remove(package_base, variable)
|
||||||
else:
|
else:
|
||||||
application.reporter.package_patches_remove(package_base, None) # just pass as is
|
application.reporter.package_patches_remove(package_base, None) # just pass as is
|
||||||
|
|
||||||
|
arguments = [
|
||||||
|
_set_patch_add_parser,
|
||||||
|
_set_patch_list_parser,
|
||||||
|
_set_patch_remove_parser,
|
||||||
|
_set_patch_set_add_parser,
|
||||||
|
]
|
||||||
|
@ -20,8 +20,9 @@
|
|||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
from ahriman.application.application import Application
|
from ahriman.application.application import Application
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
|
from ahriman.core.utils import enum_values, extract_user
|
||||||
from ahriman.models.build_status import BuildStatusEnum
|
from ahriman.models.build_status import BuildStatusEnum
|
||||||
from ahriman.models.package import Package
|
from ahriman.models.package import Package
|
||||||
from ahriman.models.packagers import Packagers
|
from ahriman.models.packagers import Packagers
|
||||||
@ -59,6 +60,38 @@ class Rebuild(Handler):
|
|||||||
result = application.update(packages, Packagers(args.username), bump_pkgrel=args.increment)
|
result = application.update(packages, Packagers(args.username), bump_pkgrel=args.increment)
|
||||||
Rebuild.check_status(args.exit_code, not result.is_empty)
|
Rebuild.check_status(args.exit_code, not result.is_empty)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_repo_rebuild_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for repository rebuild subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("repo-rebuild", aliases=["rebuild"], help="rebuild repository",
|
||||||
|
description="force rebuild whole repository")
|
||||||
|
parser.add_argument("--depends-on", help="only rebuild packages that depend on specified packages",
|
||||||
|
action="append")
|
||||||
|
parser.add_argument("--dry-run", help="just perform check for packages without rebuild process itself",
|
||||||
|
action="store_true")
|
||||||
|
parser.add_argument("--from-database",
|
||||||
|
help="read packages from database instead of filesystem. This feature in particular is "
|
||||||
|
"required in case if you would like to restore repository from another repository "
|
||||||
|
"instance. Note, however, that in order to restore packages you need to have original "
|
||||||
|
"ahriman instance run with web service and have run repo-update at least once.",
|
||||||
|
action="store_true")
|
||||||
|
parser.add_argument("--increment", help="increment package release (pkgrel) on duplicate",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty",
|
||||||
|
action="store_true")
|
||||||
|
parser.add_argument("-s", "--status", help="filter packages by status. Requires --from-database to be set",
|
||||||
|
type=BuildStatusEnum, choices=enum_values(BuildStatusEnum))
|
||||||
|
parser.add_argument("-u", "--username", help="build as user", default=extract_user())
|
||||||
|
return parser
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def extract_packages(application: Application, status: BuildStatusEnum | None, *,
|
def extract_packages(application: Application, status: BuildStatusEnum | None, *,
|
||||||
from_database: bool) -> list[Package]:
|
from_database: bool) -> list[Package]:
|
||||||
@ -81,3 +114,5 @@ class Rebuild(Handler):
|
|||||||
]
|
]
|
||||||
|
|
||||||
return application.repository.packages()
|
return application.repository.packages()
|
||||||
|
|
||||||
|
arguments = [_set_repo_rebuild_parser]
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
from ahriman.application.application import Application
|
from ahriman.application.application import Application
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.models.repository_id import RepositoryId
|
from ahriman.models.repository_id import RepositoryId
|
||||||
|
|
||||||
@ -45,3 +45,21 @@ class Remove(Handler):
|
|||||||
application = Application(repository_id, configuration, report=report)
|
application = Application(repository_id, configuration, report=report)
|
||||||
application.on_start()
|
application.on_start()
|
||||||
application.remove(args.package)
|
application.remove(args.package)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_package_remove_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for package removal subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("package-remove", aliases=["remove"], help="remove package",
|
||||||
|
description="remove package from the repository")
|
||||||
|
parser.add_argument("package", help="package name or base", nargs="+")
|
||||||
|
return parser
|
||||||
|
|
||||||
|
arguments = [_set_package_remove_parser]
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
from ahriman.application.application import Application
|
from ahriman.application.application import Application
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.formatters import StringPrinter
|
from ahriman.core.formatters import StringPrinter
|
||||||
from ahriman.models.repository_id import RepositoryId
|
from ahriman.models.repository_id import RepositoryId
|
||||||
@ -53,3 +53,21 @@ class RemoveUnknown(Handler):
|
|||||||
return
|
return
|
||||||
|
|
||||||
application.remove(unknown_packages)
|
application.remove(unknown_packages)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_repo_remove_unknown_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for remove unknown packages subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("repo-remove-unknown", aliases=["remove-unknown"], help="remove unknown packages",
|
||||||
|
description="remove packages which are missing in AUR and do not have local PKGBUILDs")
|
||||||
|
parser.add_argument("--dry-run", help="just perform check for packages without removal", action="store_true")
|
||||||
|
return parser
|
||||||
|
|
||||||
|
arguments = [_set_repo_remove_unknown_parser]
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
#
|
#
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.formatters import RepositoryPrinter
|
from ahriman.core.formatters import RepositoryPrinter
|
||||||
from ahriman.models.repository_id import RepositoryId
|
from ahriman.models.repository_id import RepositoryId
|
||||||
@ -52,3 +52,23 @@ class Repositories(Handler):
|
|||||||
)
|
)
|
||||||
for repository in cls.repositories_extract(dummy_args):
|
for repository in cls.repositories_extract(dummy_args):
|
||||||
RepositoryPrinter(repository)(verbose=not args.id_only)
|
RepositoryPrinter(repository)(verbose=not args.id_only)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_service_repositories(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for repositories listing
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("service-repositories", help="show repositories",
|
||||||
|
description="list all available repositories")
|
||||||
|
parser.add_argument("--id-only", help="show machine readable identifier instead",
|
||||||
|
action=argparse.BooleanOptionalAction, default=False)
|
||||||
|
parser.set_defaults(architecture="", lock=None, report=False, repository="", unsafe=True)
|
||||||
|
return parser
|
||||||
|
|
||||||
|
arguments = [_set_service_repositories]
|
||||||
|
@ -20,7 +20,9 @@
|
|||||||
import argparse
|
import argparse
|
||||||
import tarfile
|
import tarfile
|
||||||
|
|
||||||
from ahriman.application.handlers.handler import Handler
|
from pathlib import Path
|
||||||
|
|
||||||
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.models.repository_id import RepositoryId
|
from ahriman.models.repository_id import RepositoryId
|
||||||
|
|
||||||
@ -46,3 +48,23 @@ class Restore(Handler):
|
|||||||
"""
|
"""
|
||||||
with tarfile.open(args.path) as archive:
|
with tarfile.open(args.path) as archive:
|
||||||
archive.extractall(path=args.output) # nosec
|
archive.extractall(path=args.output) # nosec
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_repo_restore_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for repository restore subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("repo-restore", help="restore repository data",
|
||||||
|
description="restore settings and database")
|
||||||
|
parser.add_argument("path", help="path of the input archive", type=Path)
|
||||||
|
parser.add_argument("-o", "--output", help="root path of the extracted files", type=Path, default=Path("/"))
|
||||||
|
parser.set_defaults(architecture="", lock=None, report=False, repository="", unsafe=True)
|
||||||
|
return parser
|
||||||
|
|
||||||
|
arguments = [_set_repo_restore_parser]
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
import argparse
|
import argparse
|
||||||
import shlex
|
import shlex
|
||||||
|
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.models.repository_id import RepositoryId
|
from ahriman.models.repository_id import RepositoryId
|
||||||
|
|
||||||
@ -49,6 +49,25 @@ class Run(Handler):
|
|||||||
status = Run.run_command(shlex.split(command), parser)
|
status = Run.run_command(shlex.split(command), parser)
|
||||||
Run.check_status(True, status)
|
Run.check_status(True, status)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_service_run(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for multicommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("service-run", aliases=["run"], help="run multiple commands",
|
||||||
|
description="run multiple commands on success run of the previous command",
|
||||||
|
epilog="Commands must be quoted by using usual bash rules. Processes will be spawned "
|
||||||
|
"under the same user as this command.")
|
||||||
|
parser.add_argument("command", help="command to be run (quoted) without ``ahriman``", nargs="+")
|
||||||
|
parser.set_defaults(architecture="", lock=None, report=False, repository="", unsafe=True)
|
||||||
|
return parser
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def run_command(command: list[str], parser: argparse.ArgumentParser) -> bool:
|
def run_command(command: list[str], parser: argparse.ArgumentParser) -> bool:
|
||||||
"""
|
"""
|
||||||
@ -64,3 +83,5 @@ class Run(Handler):
|
|||||||
args = parser.parse_args(command)
|
args = parser.parse_args(command)
|
||||||
handler: Handler = args.handler
|
handler: Handler = args.handler
|
||||||
return handler.execute(args) == 0
|
return handler.execute(args) == 0
|
||||||
|
|
||||||
|
arguments = [_set_service_run]
|
||||||
|
@ -22,7 +22,7 @@ import argparse
|
|||||||
from collections.abc import Callable, Iterable
|
from collections.abc import Callable, Iterable
|
||||||
from dataclasses import fields
|
from dataclasses import fields
|
||||||
|
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.core.alpm.remote import AUR, Official
|
from ahriman.core.alpm.remote import AUR, Official
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.exceptions import OptionError
|
from ahriman.core.exceptions import OptionError
|
||||||
@ -68,6 +68,33 @@ class Search(Handler):
|
|||||||
for package in Search.sort(packages_list, args.sort_by):
|
for package in Search.sort(packages_list, args.sort_by):
|
||||||
AurPrinter(package)(verbose=args.info)
|
AurPrinter(package)(verbose=args.info)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_aur_search_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for AUR search subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("aur-search", aliases=["search"], help="search for package",
|
||||||
|
description="search for package in AUR using API")
|
||||||
|
parser.add_argument("search",
|
||||||
|
help="search terms, can be specified multiple times, the result will match all terms",
|
||||||
|
nargs="+")
|
||||||
|
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty",
|
||||||
|
action="store_true")
|
||||||
|
parser.add_argument("--info", help="show additional package information",
|
||||||
|
action=argparse.BooleanOptionalAction, default=False)
|
||||||
|
parser.add_argument("--sort-by",
|
||||||
|
help="sort field by this field. In case if two packages have the same value of "
|
||||||
|
"the specified field, they will be always sorted by name",
|
||||||
|
default="name", choices=sorted(Search.SORT_FIELDS))
|
||||||
|
parser.set_defaults(architecture="", lock=None, quiet=True, report=False, repository="", unsafe=True)
|
||||||
|
return parser
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def sort(packages: Iterable[AURPackage], sort_by: str) -> list[AURPackage]:
|
def sort(packages: Iterable[AURPackage], sort_by: str) -> list[AURPackage]:
|
||||||
"""
|
"""
|
||||||
@ -90,3 +117,5 @@ class Search(Handler):
|
|||||||
comparator: Callable[[AURPackage], tuple[str, str]] =\
|
comparator: Callable[[AURPackage], tuple[str, str]] =\
|
||||||
lambda package: (getattr(package, sort_by), package.name)
|
lambda package: (getattr(package, sort_by), package.name)
|
||||||
return sorted(packages, key=comparator)
|
return sorted(packages, key=comparator)
|
||||||
|
|
||||||
|
arguments = [_set_aur_search_parser]
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
from ahriman import __version__
|
from ahriman import __version__
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.formatters import UpdatePrinter
|
from ahriman.core.formatters import UpdatePrinter
|
||||||
from ahriman.models.package import Package
|
from ahriman.models.package import Package
|
||||||
@ -58,3 +58,23 @@ class ServiceUpdates(Handler):
|
|||||||
|
|
||||||
UpdatePrinter(remote, local_version)(verbose=True, separator=" -> ")
|
UpdatePrinter(remote, local_version)(verbose=True, separator=" -> ")
|
||||||
ServiceUpdates.check_status(args.exit_code, same_version)
|
ServiceUpdates.check_status(args.exit_code, same_version)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_help_updates_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for service update check subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("help-updates", help="check for service updates",
|
||||||
|
description="request AUR for current version and compare with current service version")
|
||||||
|
parser.add_argument("-e", "--exit-code", help="return non-zero exit code if updates available",
|
||||||
|
action="store_true")
|
||||||
|
parser.set_defaults(architecture="", lock=None, quiet=True, report=False, repository="", unsafe=True)
|
||||||
|
return parser
|
||||||
|
|
||||||
|
arguments = [_set_help_updates_parser]
|
||||||
|
@ -24,11 +24,13 @@ from pwd import getpwuid
|
|||||||
from urllib.parse import quote_plus as urlencode
|
from urllib.parse import quote_plus as urlencode
|
||||||
|
|
||||||
from ahriman.application.application import Application
|
from ahriman.application.application import Application
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.exceptions import MissingArchitectureError
|
from ahriman.core.exceptions import MissingArchitectureError
|
||||||
|
from ahriman.core.utils import enum_values
|
||||||
from ahriman.models.repository_id import RepositoryId
|
from ahriman.models.repository_id import RepositoryId
|
||||||
from ahriman.models.repository_paths import RepositoryPaths
|
from ahriman.models.repository_paths import RepositoryPaths
|
||||||
|
from ahriman.models.sign_settings import SignSettings
|
||||||
from ahriman.models.user import User
|
from ahriman.models.user import User
|
||||||
|
|
||||||
|
|
||||||
@ -80,6 +82,44 @@ class Setup(Handler):
|
|||||||
# lazy database sync
|
# lazy database sync
|
||||||
application.repository.pacman.handle # pylint: disable=pointless-statement
|
application.repository.pacman.handle # pylint: disable=pointless-statement
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_service_setup_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for setup subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("service-setup", aliases=["init", "repo-init", "repo-setup", "setup"],
|
||||||
|
help="initial service configuration",
|
||||||
|
description="create initial service configuration, requires root",
|
||||||
|
epilog="Create minimal configuration for the service according to provided options.")
|
||||||
|
parser.add_argument("--build-as-user", help="force makepkg user to the specific one")
|
||||||
|
parser.add_argument("--from-configuration", help="path to default devtools pacman configuration",
|
||||||
|
type=Path,
|
||||||
|
default=Path("/") / "usr" / "share" / "devtools" / "pacman.conf.d" / "extra.conf")
|
||||||
|
parser.add_argument("--generate-salt", help="generate salt for user passwords",
|
||||||
|
action=argparse.BooleanOptionalAction, default=False)
|
||||||
|
parser.add_argument("--makeflags-jobs",
|
||||||
|
help="append MAKEFLAGS variable with parallelism set to number of cores",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("--mirror", help="use the specified explicitly mirror instead of including mirrorlist")
|
||||||
|
parser.add_argument("--multilib", help="add or do not multilib repository",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("--packager", help="packager name and email", required=True)
|
||||||
|
parser.add_argument("--server", help="server to be used for devtools. If none set, local files will be used")
|
||||||
|
parser.add_argument("--sign-key", help="sign key id")
|
||||||
|
parser.add_argument("--sign-target", help="sign options", action="append",
|
||||||
|
type=SignSettings.from_option, choices=enum_values(SignSettings))
|
||||||
|
parser.add_argument("--web-port", help="port of the web service", type=int)
|
||||||
|
parser.add_argument("--web-unix-socket", help="path to unix socket used for interprocess communications",
|
||||||
|
type=Path)
|
||||||
|
parser.set_defaults(lock=None, quiet=True, report=False, unsafe=True)
|
||||||
|
return parser
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def build_command(root: Path, repository_id: RepositoryId) -> Path:
|
def build_command(root: Path, repository_id: RepositoryId) -> Path:
|
||||||
"""
|
"""
|
||||||
@ -240,3 +280,5 @@ class Setup(Handler):
|
|||||||
command.unlink(missing_ok=True)
|
command.unlink(missing_ok=True)
|
||||||
command.symlink_to(Setup.ARCHBUILD_COMMAND_PATH)
|
command.symlink_to(Setup.ARCHBUILD_COMMAND_PATH)
|
||||||
paths.chown(command) # we would like to keep owner inside ahriman's home
|
paths.chown(command) # we would like to keep owner inside ahriman's home
|
||||||
|
|
||||||
|
arguments = [_set_service_setup_parser]
|
||||||
|
@ -23,7 +23,7 @@ import sys
|
|||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.formatters import StringPrinter
|
from ahriman.core.formatters import StringPrinter
|
||||||
from ahriman.models.repository_id import RepositoryId
|
from ahriman.models.repository_id import RepositoryId
|
||||||
@ -63,3 +63,23 @@ class Shell(Handler):
|
|||||||
code.interact(local=local_variables)
|
code.interact(local=local_variables)
|
||||||
else:
|
else:
|
||||||
code.InteractiveConsole(locals=local_variables).runcode(args.code)
|
code.InteractiveConsole(locals=local_variables).runcode(args.code)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_service_shell_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for shell subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("service-shell", aliases=["shell"], help="invoke python shell",
|
||||||
|
description="drop into python shell")
|
||||||
|
parser.add_argument("code", help="instead of dropping into shell, just execute the specified code", nargs="?")
|
||||||
|
parser.add_argument("-v", "--verbose", help=argparse.SUPPRESS, action="store_true")
|
||||||
|
parser.set_defaults(lock=None, report=False)
|
||||||
|
return parser
|
||||||
|
|
||||||
|
arguments = [_set_service_shell_parser]
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
from ahriman.application.application import Application
|
from ahriman.application.application import Application
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.models.repository_id import RepositoryId
|
from ahriman.models.repository_id import RepositoryId
|
||||||
|
|
||||||
@ -43,3 +43,22 @@ class Sign(Handler):
|
|||||||
report(bool): force enable or disable reporting
|
report(bool): force enable or disable reporting
|
||||||
"""
|
"""
|
||||||
Application(repository_id, configuration, report=report).sign(args.package)
|
Application(repository_id, configuration, report=report).sign(args.package)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_repo_sign_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for sign subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("repo-sign", aliases=["sign"], help="sign packages",
|
||||||
|
description="(re-)sign packages and repository database according to current settings",
|
||||||
|
epilog="Sign repository and/or packages as configured.")
|
||||||
|
parser.add_argument("package", help="sign only specified packages", nargs="*")
|
||||||
|
return parser
|
||||||
|
|
||||||
|
arguments = [_set_repo_sign_parser]
|
||||||
|
@ -25,11 +25,11 @@ from collections.abc import Callable
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from ahriman.application.application import Application
|
from ahriman.application.application import Application
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.formatters import EventStatsPrinter, PackageStatsPrinter
|
from ahriman.core.formatters import EventStatsPrinter, PackageStatsPrinter
|
||||||
from ahriman.core.utils import pretty_datetime
|
from ahriman.core.utils import enum_values, pretty_datetime
|
||||||
from ahriman.models.event import Event
|
from ahriman.models.event import Event, EventType
|
||||||
from ahriman.models.repository_id import RepositoryId
|
from ahriman.models.repository_id import RepositoryId
|
||||||
|
|
||||||
|
|
||||||
@ -68,6 +68,30 @@ class Statistics(Handler):
|
|||||||
case _:
|
case _:
|
||||||
Statistics.stats_for_package(args.event, events, args.chart)
|
Statistics.stats_for_package(args.event, events, args.chart)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_repo_statistics_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for repository statistics subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("repo-statistics", help="repository statistics",
|
||||||
|
description="fetch repository statistics")
|
||||||
|
parser.add_argument("package", help="fetch only events for the specified package", nargs="?")
|
||||||
|
parser.add_argument("--chart", help="create updates chart and save it to the specified path", type=Path)
|
||||||
|
parser.add_argument("-e", "--event", help="event type filter",
|
||||||
|
type=EventType, choices=enum_values(EventType), default=EventType.PackageUpdated)
|
||||||
|
parser.add_argument("--from-date", help="only fetch events which are newer than the date")
|
||||||
|
parser.add_argument("--limit", help="limit response by specified amount of events", type=int, default=-1)
|
||||||
|
parser.add_argument("--offset", help="skip specified amount of events", type=int, default=0)
|
||||||
|
parser.add_argument("--to-date", help="only fetch events which are older than the date")
|
||||||
|
parser.set_defaults(lock=None, quiet=True, report=False, unsafe=True)
|
||||||
|
return parser
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def event_stats(event_type: str, events: list[Event]) -> None:
|
def event_stats(event_type: str, events: list[Event]) -> None:
|
||||||
"""
|
"""
|
||||||
@ -168,3 +192,5 @@ class Statistics(Handler):
|
|||||||
# chart if enabled
|
# chart if enabled
|
||||||
if chart_path is not None:
|
if chart_path is not None:
|
||||||
Statistics.plot_packages(event_type, by_object_id, chart_path)
|
Statistics.plot_packages(event_type, by_object_id, chart_path)
|
||||||
|
|
||||||
|
arguments = [_set_repo_statistics_parser]
|
||||||
|
@ -22,10 +22,11 @@ import argparse
|
|||||||
from collections.abc import Callable
|
from collections.abc import Callable
|
||||||
|
|
||||||
from ahriman.application.application import Application
|
from ahriman.application.application import Application
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.formatters import PackagePrinter, StatusPrinter
|
from ahriman.core.formatters import PackagePrinter, StatusPrinter
|
||||||
from ahriman.models.build_status import BuildStatus
|
from ahriman.core.utils import enum_values
|
||||||
|
from ahriman.models.build_status import BuildStatus, BuildStatusEnum
|
||||||
from ahriman.models.package import Package
|
from ahriman.models.package import Package
|
||||||
from ahriman.models.repository_id import RepositoryId
|
from ahriman.models.repository_id import RepositoryId
|
||||||
|
|
||||||
@ -68,3 +69,31 @@ class Status(Handler):
|
|||||||
lambda item: args.status is None or item[1].status == args.status
|
lambda item: args.status is None or item[1].status == args.status
|
||||||
for package, package_status in sorted(filter(filter_fn, packages), key=comparator):
|
for package, package_status in sorted(filter(filter_fn, packages), key=comparator):
|
||||||
PackagePrinter(package, package_status)(verbose=args.info)
|
PackagePrinter(package, package_status)(verbose=args.info)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_package_status_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for package status subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("package-status", aliases=["status"], help="get package status",
|
||||||
|
description="request status of the package",
|
||||||
|
epilog="This command requests package status from the web interface "
|
||||||
|
"if it is available.")
|
||||||
|
parser.add_argument("package", help="filter status by package base", nargs="*")
|
||||||
|
parser.add_argument("--ahriman", help="get service status itself", action="store_true")
|
||||||
|
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty",
|
||||||
|
action="store_true")
|
||||||
|
parser.add_argument("--info", help="show additional package information",
|
||||||
|
action=argparse.BooleanOptionalAction, default=False)
|
||||||
|
parser.add_argument("-s", "--status", help="filter packages by status",
|
||||||
|
type=BuildStatusEnum, choices=enum_values(BuildStatusEnum))
|
||||||
|
parser.set_defaults(lock=None, quiet=True, report=False, unsafe=True)
|
||||||
|
return parser
|
||||||
|
|
||||||
|
arguments = [_set_package_status_parser]
|
||||||
|
@ -20,9 +20,11 @@
|
|||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
from ahriman.application.application import Application
|
from ahriman.application.application import Application
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
|
from ahriman.core.utils import enum_values
|
||||||
from ahriman.models.action import Action
|
from ahriman.models.action import Action
|
||||||
|
from ahriman.models.build_status import BuildStatusEnum
|
||||||
from ahriman.models.repository_id import RepositoryId
|
from ahriman.models.repository_id import RepositoryId
|
||||||
|
|
||||||
|
|
||||||
@ -59,3 +61,67 @@ class StatusUpdate(Handler):
|
|||||||
case Action.Remove:
|
case Action.Remove:
|
||||||
for package in args.package:
|
for package in args.package:
|
||||||
client.package_remove(package)
|
client.package_remove(package)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_package_status_remove_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for package status remove subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("package-status-remove", help="remove package status",
|
||||||
|
description="remove the package from the status page",
|
||||||
|
epilog="Please note that this subcommand does not remove the package itself, it just "
|
||||||
|
"clears the status page.")
|
||||||
|
parser.add_argument("package", help="remove specified packages from status page", nargs="+")
|
||||||
|
parser.set_defaults(action=Action.Remove, lock=None, quiet=True, report=False, unsafe=True)
|
||||||
|
return parser
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_package_status_update_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for package status update subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("package-status-update", aliases=["status-update"], help="update package status",
|
||||||
|
description="update package status on the status page")
|
||||||
|
parser.add_argument("package", help="set status for specified packages. "
|
||||||
|
"If no packages supplied, service status will be updated",
|
||||||
|
nargs="*")
|
||||||
|
parser.add_argument("-s", "--status", help="new package build status",
|
||||||
|
type=BuildStatusEnum, choices=enum_values(BuildStatusEnum), default=BuildStatusEnum.Success)
|
||||||
|
parser.set_defaults(action=Action.Update, lock=None, quiet=True, report=False, unsafe=True)
|
||||||
|
return parser
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_repo_status_update_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for repository status update subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("repo-status-update", help="update repository status",
|
||||||
|
description="update repository status on the status page")
|
||||||
|
parser.add_argument("-s", "--status", help="new status",
|
||||||
|
type=BuildStatusEnum, choices=enum_values(BuildStatusEnum), default=BuildStatusEnum.Success)
|
||||||
|
parser.set_defaults(action=Action.Update, lock=None, package=[], quiet=True, report=False, unsafe=True)
|
||||||
|
return parser
|
||||||
|
|
||||||
|
arguments = [
|
||||||
|
_set_package_status_remove_parser,
|
||||||
|
_set_package_status_update_parser,
|
||||||
|
_set_repo_status_update_parser,
|
||||||
|
]
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
from ahriman.application.application import Application
|
from ahriman.application.application import Application
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.formatters import StringPrinter, TreePrinter
|
from ahriman.core.formatters import StringPrinter, TreePrinter
|
||||||
from ahriman.core.tree import Tree
|
from ahriman.core.tree import Tree
|
||||||
@ -58,3 +58,23 @@ class Structure(Handler):
|
|||||||
|
|
||||||
# empty line
|
# empty line
|
||||||
StringPrinter("")(verbose=False)
|
StringPrinter("")(verbose=False)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_repo_tree_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for repository tree subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("repo-tree", help="dump repository tree",
|
||||||
|
description="dump repository tree based on packages dependencies")
|
||||||
|
parser.add_argument("-p", "--partitions", help="also divide packages by independent partitions",
|
||||||
|
type=int, default=1)
|
||||||
|
parser.set_defaults(lock=None, quiet=True, report=False, unsafe=True)
|
||||||
|
return parser
|
||||||
|
|
||||||
|
arguments = [_set_repo_tree_parser]
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
#
|
#
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.models.repository_id import RepositoryId
|
from ahriman.models.repository_id import RepositoryId
|
||||||
from ahriman.models.repository_paths import RepositoryPaths
|
from ahriman.models.repository_paths import RepositoryPaths
|
||||||
@ -50,6 +50,22 @@ class TreeMigrate(Handler):
|
|||||||
# perform migration
|
# perform migration
|
||||||
TreeMigrate.tree_move(current_tree, target_tree)
|
TreeMigrate.tree_move(current_tree, target_tree)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_service_tree_migrate_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for tree migration subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("service-tree-migrate", help="migrate repository tree",
|
||||||
|
description="migrate repository tree between versions")
|
||||||
|
parser.set_defaults(lock=None, quiet=True, report=False)
|
||||||
|
return parser
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def tree_move(from_tree: RepositoryPaths, to_tree: RepositoryPaths) -> None:
|
def tree_move(from_tree: RepositoryPaths, to_tree: RepositoryPaths) -> None:
|
||||||
"""
|
"""
|
||||||
@ -66,3 +82,5 @@ class TreeMigrate(Handler):
|
|||||||
RepositoryPaths.repository,
|
RepositoryPaths.repository,
|
||||||
):
|
):
|
||||||
attribute.fget(from_tree).rename(attribute.fget(to_tree)) # type: ignore[attr-defined]
|
attribute.fget(from_tree).rename(attribute.fget(to_tree)) # type: ignore[attr-defined]
|
||||||
|
|
||||||
|
arguments = [_set_service_tree_migrate_parser]
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
from ahriman.application.application import Application
|
from ahriman.application.application import Application
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.models.repository_id import RepositoryId
|
from ahriman.models.repository_id import RepositoryId
|
||||||
from ahriman.models.result import Result
|
from ahriman.models.result import Result
|
||||||
@ -49,3 +49,60 @@ class Triggers(Handler):
|
|||||||
loader.triggers = [loader.load_trigger(trigger, repository_id, configuration) for trigger in args.trigger]
|
loader.triggers = [loader.load_trigger(trigger, repository_id, configuration) for trigger in args.trigger]
|
||||||
application.on_start()
|
application.on_start()
|
||||||
application.on_result(Result())
|
application.on_result(Result())
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_repo_report_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for report subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("repo-report", aliases=["report"], help="generate report",
|
||||||
|
description="generate repository report according to current settings",
|
||||||
|
epilog="Create and/or update repository report as configured.")
|
||||||
|
parser.set_defaults(trigger=["ahriman.core.report.ReportTrigger"])
|
||||||
|
return parser
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_repo_sync_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for repository sync subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("repo-sync", aliases=["sync"], help="sync repository",
|
||||||
|
description="sync repository files to remote server according to current settings",
|
||||||
|
epilog="Synchronize the repository to remote services as configured.")
|
||||||
|
parser.set_defaults(trigger=["ahriman.core.upload.UploadTrigger"])
|
||||||
|
return parser
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_repo_triggers_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for repository triggers subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("repo-triggers", help="run triggers",
|
||||||
|
description="run triggers on empty build result as configured by settings")
|
||||||
|
parser.add_argument("trigger", help="instead of running all triggers as set by configuration, just process "
|
||||||
|
"specified ones in order of mention", nargs="*")
|
||||||
|
return parser
|
||||||
|
|
||||||
|
arguments = [
|
||||||
|
_set_repo_report_parser,
|
||||||
|
_set_repo_sync_parser,
|
||||||
|
_set_repo_triggers_parser,
|
||||||
|
]
|
||||||
|
70
src/ahriman/application/handlers/triggers_support.py
Normal file
70
src/ahriman/application/handlers/triggers_support.py
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#
|
||||||
|
# Copyright (c) 2021-2024 ahriman team.
|
||||||
|
#
|
||||||
|
# This file is part of ahriman
|
||||||
|
# (see https://github.com/arcan1s/ahriman).
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
from ahriman.application.handlers.handler import SubParserAction
|
||||||
|
from ahriman.application.handlers.triggers import Triggers
|
||||||
|
|
||||||
|
|
||||||
|
class TriggersSupport(Triggers):
|
||||||
|
"""
|
||||||
|
additional triggers handlers for support commands
|
||||||
|
"""
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_repo_create_keyring_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for create-keyring subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("repo-create-keyring", help="create keyring package",
|
||||||
|
description="create package which contains list of trusted keys as set by "
|
||||||
|
"configuration. Note, that this action will only create package, "
|
||||||
|
"the package itself has to be built manually")
|
||||||
|
parser.set_defaults(trigger=["ahriman.core.support.KeyringTrigger"])
|
||||||
|
return parser
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_repo_create_mirrorlist_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for create-mirrorlist subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("repo-create-mirrorlist", help="create mirrorlist package",
|
||||||
|
description="create package which contains list of available mirrors as set by "
|
||||||
|
"configuration. Note, that this action will only create package, "
|
||||||
|
"the package itself has to be built manually")
|
||||||
|
parser.set_defaults(trigger=["ahriman.core.support.MirrorlistTrigger"])
|
||||||
|
return parser
|
||||||
|
|
||||||
|
arguments = [
|
||||||
|
_set_repo_create_keyring_parser,
|
||||||
|
_set_repo_create_mirrorlist_parser,
|
||||||
|
]
|
@ -19,7 +19,7 @@
|
|||||||
#
|
#
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.formatters import StringPrinter
|
from ahriman.core.formatters import StringPrinter
|
||||||
from ahriman.models.repository_id import RepositoryId
|
from ahriman.models.repository_id import RepositoryId
|
||||||
@ -52,6 +52,25 @@ class UnsafeCommands(Handler):
|
|||||||
for command in unsafe_commands:
|
for command in unsafe_commands:
|
||||||
StringPrinter(command)(verbose=True)
|
StringPrinter(command)(verbose=True)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_help_commands_unsafe_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for listing unsafe commands
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("help-commands-unsafe", help="list unsafe commands",
|
||||||
|
description="list unsafe commands as defined in default args")
|
||||||
|
parser.add_argument("subcommand",
|
||||||
|
help="instead of showing commands, just test command line for unsafe subcommand "
|
||||||
|
"and return 0 in case if command is safe and 1 otherwise", nargs="*")
|
||||||
|
parser.set_defaults(architecture="", lock=None, quiet=True, report=False, repository="", unsafe=True)
|
||||||
|
return parser
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def check_unsafe(command: list[str], unsafe_commands: list[str], parser: argparse.ArgumentParser) -> None:
|
def check_unsafe(command: list[str], unsafe_commands: list[str], parser: argparse.ArgumentParser) -> None:
|
||||||
"""
|
"""
|
||||||
@ -81,3 +100,5 @@ class UnsafeCommands(Handler):
|
|||||||
subparser = next((action for action in parser._actions if isinstance(action, argparse._SubParsersAction)), None)
|
subparser = next((action for action in parser._actions if isinstance(action, argparse._SubParsersAction)), None)
|
||||||
actions = subparser.choices if subparser is not None else {}
|
actions = subparser.choices if subparser is not None else {}
|
||||||
return sorted(action_name for action_name, action in actions.items() if action.get_default("unsafe"))
|
return sorted(action_name for action_name, action in actions.items() if action.get_default("unsafe"))
|
||||||
|
|
||||||
|
arguments = [_set_help_commands_unsafe_parser]
|
||||||
|
@ -22,8 +22,9 @@ import argparse
|
|||||||
from collections.abc import Callable
|
from collections.abc import Callable
|
||||||
|
|
||||||
from ahriman.application.application import Application
|
from ahriman.application.application import Application
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
|
from ahriman.core.utils import extract_user
|
||||||
from ahriman.models.packagers import Packagers
|
from ahriman.models.packagers import Packagers
|
||||||
from ahriman.models.repository_id import RepositoryId
|
from ahriman.models.repository_id import RepositoryId
|
||||||
|
|
||||||
@ -64,6 +65,78 @@ class Update(Handler):
|
|||||||
result = application.update(packages, packagers, bump_pkgrel=args.increment)
|
result = application.update(packages, packagers, bump_pkgrel=args.increment)
|
||||||
Update.check_status(args.exit_code, not result.is_empty)
|
Update.check_status(args.exit_code, not result.is_empty)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_repo_check_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for repository check subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("repo-check", aliases=["check"], help="check for updates",
|
||||||
|
description="check for packages updates. Same as repo-update --dry-run --no-manual")
|
||||||
|
parser.add_argument("package", help="filter check by package base", nargs="*")
|
||||||
|
parser.add_argument("--changes", help="calculate changes from the latest known commit if available",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("--check-files", help="enable or disable checking of broken dependencies "
|
||||||
|
"(e.g. dynamically linked libraries or modules directories)",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty",
|
||||||
|
action="store_true")
|
||||||
|
parser.add_argument("--vcs", help="fetch actual version of VCS packages",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("-y", "--refresh", help="download fresh package databases from the mirror before actions, "
|
||||||
|
"-yy to force refresh even if up to date",
|
||||||
|
action="count", default=False)
|
||||||
|
parser.set_defaults(aur=True, dependencies=False, dry_run=True, increment=False, local=True, manual=False,
|
||||||
|
username=None)
|
||||||
|
return parser
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_repo_update_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for repository update subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("repo-update", aliases=["update"], help="update packages",
|
||||||
|
description="check for packages updates and run build process if requested")
|
||||||
|
parser.add_argument("package", help="filter check by package base", nargs="*")
|
||||||
|
parser.add_argument("--aur", help="enable or disable checking for AUR updates",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("--changes", help="calculate changes from the latest known commit if available. "
|
||||||
|
"Only applicable in dry run mode",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("--check-files", help="enable or disable checking of broken dependencies "
|
||||||
|
"(e.g. dynamically linked libraries or modules directories)",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("--dependencies", help="process missing package dependencies",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("--dry-run", help="just perform check for updates, same as check command",
|
||||||
|
action="store_true")
|
||||||
|
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty",
|
||||||
|
action="store_true")
|
||||||
|
parser.add_argument("--increment", help="increment package release (pkgrel) on duplicate",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("--local", help="enable or disable checking of local packages for updates",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("--manual", help="include or exclude manual updates",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("-u", "--username", help="build as user", default=extract_user())
|
||||||
|
parser.add_argument("--vcs", help="fetch actual version of VCS packages",
|
||||||
|
action=argparse.BooleanOptionalAction, default=True)
|
||||||
|
parser.add_argument("-y", "--refresh", help="download fresh package databases from the mirror before actions, "
|
||||||
|
"-yy to force refresh even if up to date",
|
||||||
|
action="count", default=False)
|
||||||
|
return parser
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def log_fn(application: Application, dry_run: bool) -> Callable[[str], None]:
|
def log_fn(application: Application, dry_run: bool) -> Callable[[str], None]:
|
||||||
"""
|
"""
|
||||||
@ -79,3 +152,8 @@ class Update(Handler):
|
|||||||
def inner(line: str) -> None:
|
def inner(line: str) -> None:
|
||||||
return print(line) if dry_run else application.logger.info(line) # pylint: disable=bad-builtin
|
return print(line) if dry_run else application.logger.info(line) # pylint: disable=bad-builtin
|
||||||
return inner
|
return inner
|
||||||
|
|
||||||
|
arguments = [
|
||||||
|
_set_repo_check_parser,
|
||||||
|
_set_repo_update_parser,
|
||||||
|
]
|
||||||
|
@ -20,14 +20,16 @@
|
|||||||
import argparse
|
import argparse
|
||||||
import getpass
|
import getpass
|
||||||
|
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.database import SQLite
|
from ahriman.core.database import SQLite
|
||||||
from ahriman.core.exceptions import PasswordError
|
from ahriman.core.exceptions import PasswordError
|
||||||
from ahriman.core.formatters import UserPrinter
|
from ahriman.core.formatters import UserPrinter
|
||||||
|
from ahriman.core.utils import enum_values
|
||||||
from ahriman.models.action import Action
|
from ahriman.models.action import Action
|
||||||
from ahriman.models.repository_id import RepositoryId
|
from ahriman.models.repository_id import RepositoryId
|
||||||
from ahriman.models.user import User
|
from ahriman.models.user import User
|
||||||
|
from ahriman.models.user_access import UserAccess
|
||||||
|
|
||||||
|
|
||||||
class Users(Handler):
|
class Users(Handler):
|
||||||
@ -65,6 +67,73 @@ class Users(Handler):
|
|||||||
case Action.Remove:
|
case Action.Remove:
|
||||||
database.user_remove(args.username)
|
database.user_remove(args.username)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_user_add_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for create user subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("user-add", help="create or update user",
|
||||||
|
description="update user for web services with the given password and role. "
|
||||||
|
"In case if password was not entered it will be asked interactively")
|
||||||
|
parser.add_argument("username", help="username for web service")
|
||||||
|
parser.add_argument("--key", help="optional PGP key used by this user. The private key must be imported")
|
||||||
|
parser.add_argument("--packager", help="optional packager id used for build process in form of "
|
||||||
|
"`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",
|
||||||
|
type=UserAccess, choices=enum_values(UserAccess), default=UserAccess.Read)
|
||||||
|
parser.set_defaults(action=Action.Update, architecture="", exit_code=False, lock=None, quiet=True,
|
||||||
|
report=False, repository="")
|
||||||
|
return parser
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_user_list_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for user list subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("user-list", help="user known users and their access",
|
||||||
|
description="list users from the user mapping and their roles")
|
||||||
|
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.set_defaults(action=Action.List, architecture="", lock=None, quiet=True, report=False, repository="",
|
||||||
|
unsafe=True)
|
||||||
|
return parser
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_user_remove_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for user removal subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("user-remove", help="remove user",
|
||||||
|
description="remove user from the user mapping and update the configuration")
|
||||||
|
parser.add_argument("username", help="username for web service")
|
||||||
|
parser.set_defaults(action=Action.Remove, architecture="", exit_code=False, lock=None, quiet=True,
|
||||||
|
report=False, repository="")
|
||||||
|
return parser
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def user_create(args: argparse.Namespace) -> User:
|
def user_create(args: argparse.Namespace) -> User:
|
||||||
"""
|
"""
|
||||||
@ -92,3 +161,9 @@ class Users(Handler):
|
|||||||
|
|
||||||
return User(username=args.username, password=password, access=args.role,
|
return User(username=args.username, password=password, access=args.role,
|
||||||
packager_id=args.packager, key=args.key)
|
packager_id=args.packager, key=args.key)
|
||||||
|
|
||||||
|
arguments = [
|
||||||
|
_set_user_add_parser,
|
||||||
|
_set_user_list_parser,
|
||||||
|
_set_user_remove_parser,
|
||||||
|
]
|
||||||
|
@ -22,7 +22,7 @@ import copy
|
|||||||
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.configuration.schema import CONFIGURATION_SCHEMA, ConfigurationSchema
|
from ahriman.core.configuration.schema import CONFIGURATION_SCHEMA, ConfigurationSchema
|
||||||
from ahriman.core.exceptions import ExtensionError
|
from ahriman.core.exceptions import ExtensionError
|
||||||
@ -63,6 +63,25 @@ class Validate(Handler):
|
|||||||
# as we reach this part it means that we always have errors
|
# as we reach this part it means that we always have errors
|
||||||
Validate.check_status(args.exit_code, False)
|
Validate.check_status(args.exit_code, False)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_service_config_validate_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for config validation subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("service-config-validate", aliases=["config-validate", "repo-config-validate"],
|
||||||
|
help="validate system configuration",
|
||||||
|
description="validate configuration and print found errors")
|
||||||
|
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if configuration is invalid",
|
||||||
|
action="store_true")
|
||||||
|
parser.set_defaults(lock=None, quiet=True, report=False, unsafe=True)
|
||||||
|
return parser
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def schema(repository_id: RepositoryId, configuration: Configuration) -> ConfigurationSchema:
|
def schema(repository_id: RepositoryId, configuration: Configuration) -> ConfigurationSchema:
|
||||||
"""
|
"""
|
||||||
@ -136,3 +155,5 @@ class Validate(Handler):
|
|||||||
Validate.schema_merge(value, schema[key])
|
Validate.schema_merge(value, schema[key])
|
||||||
|
|
||||||
return schema
|
return schema
|
||||||
|
|
||||||
|
arguments = [_set_service_config_validate_parser]
|
||||||
|
@ -25,7 +25,7 @@ from collections.abc import Generator
|
|||||||
from importlib import metadata
|
from importlib import metadata
|
||||||
|
|
||||||
from ahriman import __version__
|
from ahriman import __version__
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.formatters import VersionPrinter
|
from ahriman.core.formatters import VersionPrinter
|
||||||
from ahriman.models.repository_id import RepositoryId
|
from ahriman.models.repository_id import RepositoryId
|
||||||
@ -59,6 +59,22 @@ class Versions(Handler):
|
|||||||
packages = Versions.package_dependencies("ahriman")
|
packages = Versions.package_dependencies("ahriman")
|
||||||
VersionPrinter("Installed packages", dict(packages))(verbose=False, separator=" ")
|
VersionPrinter("Installed packages", dict(packages))(verbose=False, separator=" ")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_help_version_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for version subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("help-version", aliases=["version"], help="application version",
|
||||||
|
description="print application and its dependencies versions")
|
||||||
|
parser.set_defaults(architecture="", lock=None, quiet=True, report=False, repository="", unsafe=True)
|
||||||
|
return parser
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def package_dependencies(root: str) -> Generator[tuple[str, str], None, None]:
|
def package_dependencies(root: str) -> Generator[tuple[str, str], None, None]:
|
||||||
"""
|
"""
|
||||||
@ -96,3 +112,5 @@ class Versions(Handler):
|
|||||||
yield distribution.name, distribution.version
|
yield distribution.name, distribution.version
|
||||||
except metadata.PackageNotFoundError:
|
except metadata.PackageNotFoundError:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
arguments = [_set_help_version_parser]
|
||||||
|
@ -20,8 +20,9 @@
|
|||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
from collections.abc import Generator
|
from collections.abc import Generator
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.spawn import Spawn
|
from ahriman.core.spawn import Spawn
|
||||||
from ahriman.core.triggers import TriggerLoader
|
from ahriman.core.triggers import TriggerLoader
|
||||||
@ -71,6 +72,21 @@ class Web(Handler):
|
|||||||
spawner.stop()
|
spawner.stop()
|
||||||
spawner.join()
|
spawner.join()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_web_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for web subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("web", help="web server", description="start web server")
|
||||||
|
parser.set_defaults(architecture="", lock=Path("ahriman-web.pid"), report=False, repository="")
|
||||||
|
return parser
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def extract_arguments(args: argparse.Namespace, configuration: Configuration) -> Generator[str, None, None]:
|
def extract_arguments(args: argparse.Namespace, configuration: Configuration) -> Generator[str, None, None]:
|
||||||
"""
|
"""
|
||||||
@ -100,3 +116,5 @@ class Web(Handler):
|
|||||||
# arguments from configuration
|
# arguments from configuration
|
||||||
if (wait_timeout := configuration.getint("web", "wait_timeout", fallback=None)) is not None:
|
if (wait_timeout := configuration.getint("web", "wait_timeout", fallback=None)) is not None:
|
||||||
yield from ["--wait-timeout", str(wait_timeout)]
|
yield from ["--wait-timeout", str(wait_timeout)]
|
||||||
|
|
||||||
|
arguments = [_set_web_parser]
|
||||||
|
@ -17,14 +17,14 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
from typing import Any
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import aiohttp_security
|
import aiohttp_security
|
||||||
_has_aiohttp_security = True
|
_has_aiohttp_security = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
_has_aiohttp_security = False
|
_has_aiohttp_security = False
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
|
||||||
__all__ = ["authorized_userid", "check_authorized", "forget", "remember"]
|
__all__ = ["authorized_userid", "check_authorized", "forget", "remember"]
|
||||||
|
|
||||||
|
@ -17,7 +17,8 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
from logging import NullHandler # pylint: disable=imports-out-of-order
|
# pylint: disable=imports-out-of-order
|
||||||
|
from logging import NullHandler
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
|
||||||
|
78
src/ahriman/core/module_loader.py
Normal file
78
src/ahriman/core/module_loader.py
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
#
|
||||||
|
# Copyright (c) 2021-2024 ahriman team.
|
||||||
|
#
|
||||||
|
# This file is part of ahriman
|
||||||
|
# (see https://github.com/arcan1s/ahriman).
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
import inspect
|
||||||
|
|
||||||
|
from collections.abc import Generator
|
||||||
|
from importlib import import_module
|
||||||
|
from pathlib import Path
|
||||||
|
from pkgutil import ModuleInfo, walk_packages
|
||||||
|
from types import ModuleType
|
||||||
|
from typing import Any, TypeGuard, TypeVar
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = ["implementations"]
|
||||||
|
|
||||||
|
|
||||||
|
T = TypeVar("T")
|
||||||
|
|
||||||
|
|
||||||
|
def _modules(module_root: Path, prefix: str) -> Generator[ModuleInfo, None, None]:
|
||||||
|
"""
|
||||||
|
extract available modules from package
|
||||||
|
|
||||||
|
Args:
|
||||||
|
module_root(Path): module root path
|
||||||
|
prefix(str): modules package prefix
|
||||||
|
|
||||||
|
Yields:
|
||||||
|
ModuleInfo: module information each available module
|
||||||
|
"""
|
||||||
|
prefix = f"{prefix}." if prefix else ""
|
||||||
|
for module_info in walk_packages([str(module_root)], prefix):
|
||||||
|
if module_info.ispkg:
|
||||||
|
yield from _modules(module_root / module_info.name, prefix)
|
||||||
|
else:
|
||||||
|
yield module_info
|
||||||
|
|
||||||
|
|
||||||
|
def implementations(root_module: ModuleType, base_class: type[T]) -> Generator[type[T], None, None]:
|
||||||
|
"""
|
||||||
|
extract implementations of the ``base_class`` from the module
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root_module(ModuleType): root module
|
||||||
|
base_class(type[T]): base class type
|
||||||
|
|
||||||
|
Yields:
|
||||||
|
type[T]: found implementations
|
||||||
|
"""
|
||||||
|
def is_base_class(clazz: Any) -> TypeGuard[type[T]]:
|
||||||
|
return inspect.isclass(clazz) \
|
||||||
|
and issubclass(clazz, base_class) and clazz != base_class \
|
||||||
|
and clazz.__module__ == module.__name__
|
||||||
|
|
||||||
|
prefix = root_module.__name__
|
||||||
|
|
||||||
|
for module_root in root_module.__path__:
|
||||||
|
for module_info in _modules(Path(module_root), prefix):
|
||||||
|
module = import_module(module_info.name)
|
||||||
|
|
||||||
|
for _, attribute in inspect.getmembers(module, is_base_class):
|
||||||
|
yield attribute
|
@ -461,7 +461,7 @@ def trim_package(package_name: str) -> str:
|
|||||||
str: package name without description or version bound
|
str: package name without description or version bound
|
||||||
"""
|
"""
|
||||||
for symbol in ("<", "=", ">", ":"):
|
for symbol in ("<", "=", ">", ":"):
|
||||||
package_name = package_name.partition(symbol)[0]
|
package_name, *_ = package_name.split(symbol, maxsplit=1)
|
||||||
return package_name
|
return package_name
|
||||||
|
|
||||||
|
|
||||||
@ -478,7 +478,6 @@ def utcnow() -> datetime.datetime:
|
|||||||
def walk(directory_path: Path) -> Generator[Path, None, None]:
|
def walk(directory_path: Path) -> Generator[Path, None, None]:
|
||||||
"""
|
"""
|
||||||
list all file paths in given directory
|
list all file paths in given directory
|
||||||
Credits to https://stackoverflow.com/a/64915960
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
directory_path(Path): root directory path
|
directory_path(Path): root directory path
|
||||||
@ -487,18 +486,13 @@ def walk(directory_path: Path) -> Generator[Path, None, None]:
|
|||||||
Path: all found files in given directory with full path
|
Path: all found files in given directory with full path
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
Since the :mod:`pathlib` module does not provide an alternative to :func:`os.walk()`, this wrapper
|
Wrapper around :func:`pathlib.Path.walk`, which yields only files instead::
|
||||||
can be used instead::
|
|
||||||
|
|
||||||
>>> from pathlib import Path
|
>>> from pathlib import Path
|
||||||
>>>
|
>>>
|
||||||
>>> for file_path in walk(Path.cwd()):
|
>>> for file_path in walk(Path.cwd()):
|
||||||
>>> print(file_path)
|
>>> print(file_path)
|
||||||
|
|
||||||
Note, however, that unlike the original method, it does not yield directories.
|
|
||||||
"""
|
"""
|
||||||
for element in directory_path.iterdir():
|
for root, _, files in directory_path.walk(follow_symlinks=True):
|
||||||
if element.is_dir():
|
for file in files:
|
||||||
yield from walk(element)
|
yield root / file
|
||||||
continue
|
|
||||||
yield element
|
|
||||||
|
@ -18,93 +18,35 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
from aiohttp.web import Application, View
|
from aiohttp.web import Application, View
|
||||||
from collections.abc import Generator
|
|
||||||
from importlib.machinery import SourceFileLoader
|
import ahriman.web.views
|
||||||
from pathlib import Path
|
|
||||||
from pkgutil import ModuleInfo, iter_modules
|
|
||||||
from types import ModuleType
|
|
||||||
from typing import Any, Type, TypeGuard
|
|
||||||
|
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
|
from ahriman.core.module_loader import implementations
|
||||||
from ahriman.web.views.base import BaseView
|
from ahriman.web.views.base import BaseView
|
||||||
|
|
||||||
|
|
||||||
__all__ = ["setup_routes"]
|
__all__ = ["setup_routes"]
|
||||||
|
|
||||||
|
|
||||||
def _dynamic_routes(module_root: Path, configuration: Configuration) -> dict[str, Type[View]]:
|
def _dynamic_routes(configuration: Configuration) -> dict[str, type[View]]:
|
||||||
"""
|
"""
|
||||||
extract dynamic routes based on views
|
extract dynamic routes based on views
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
module_root(Path): root module path with views
|
|
||||||
configuration(Configuration): configuration instance
|
configuration(Configuration): configuration instance
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
dict[str, Type[View]]: map of the route to its view
|
dict[str, type[View]]: map of the route to its view
|
||||||
"""
|
"""
|
||||||
def is_base_view(clazz: Any) -> TypeGuard[Type[BaseView]]:
|
routes: dict[str, type[View]] = {}
|
||||||
return isinstance(clazz, type) and issubclass(clazz, BaseView)
|
for view in implementations(ahriman.web.views, BaseView):
|
||||||
|
view_routes = view.routes(configuration)
|
||||||
routes: dict[str, Type[View]] = {}
|
routes.update([(route, view) for route in view_routes])
|
||||||
for module_info in _modules(module_root):
|
|
||||||
module = _module(module_info)
|
|
||||||
|
|
||||||
for attribute_name in dir(module):
|
|
||||||
view = getattr(module, attribute_name)
|
|
||||||
if not is_base_view(view):
|
|
||||||
continue
|
|
||||||
|
|
||||||
view_routes = view.routes(configuration)
|
|
||||||
routes.update([(route, view) for route in view_routes])
|
|
||||||
|
|
||||||
return routes
|
return routes
|
||||||
|
|
||||||
|
|
||||||
def _module(module_info: ModuleInfo) -> ModuleType:
|
|
||||||
"""
|
|
||||||
load module from its info
|
|
||||||
|
|
||||||
Args:
|
|
||||||
module_info(ModuleInfo): module info descriptor
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
ModuleType: loaded module
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
ValueError: if loader is not an instance of :class:`importlib.machinery.SourceFileLoader`
|
|
||||||
"""
|
|
||||||
module_spec = module_info.module_finder.find_spec(module_info.name, None)
|
|
||||||
if module_spec is None:
|
|
||||||
raise ValueError(f"Module specification of {module_info.name} is empty")
|
|
||||||
|
|
||||||
loader = module_spec.loader
|
|
||||||
if not isinstance(loader, SourceFileLoader):
|
|
||||||
raise ValueError(f"Module {module_info.name} loader is not an instance of SourceFileLoader")
|
|
||||||
|
|
||||||
module = ModuleType(loader.name)
|
|
||||||
loader.exec_module(module)
|
|
||||||
|
|
||||||
return module
|
|
||||||
|
|
||||||
|
|
||||||
def _modules(module_root: Path) -> Generator[ModuleInfo, None, None]:
|
|
||||||
"""
|
|
||||||
extract available modules from package
|
|
||||||
|
|
||||||
Args:
|
|
||||||
module_root(Path): module root path
|
|
||||||
|
|
||||||
Yields:
|
|
||||||
ModuleInfo: module information each available module
|
|
||||||
"""
|
|
||||||
for module_info in iter_modules([str(module_root)]):
|
|
||||||
if module_info.ispkg:
|
|
||||||
yield from _modules(module_root / module_info.name)
|
|
||||||
else:
|
|
||||||
yield module_info
|
|
||||||
|
|
||||||
|
|
||||||
def setup_routes(application: Application, configuration: Configuration) -> None:
|
def setup_routes(application: Application, configuration: Configuration) -> None:
|
||||||
"""
|
"""
|
||||||
setup all defined routes
|
setup all defined routes
|
||||||
@ -115,6 +57,5 @@ def setup_routes(application: Application, configuration: Configuration) -> None
|
|||||||
"""
|
"""
|
||||||
application.router.add_static("/static", configuration.getpath("web", "static_path"), follow_symlinks=True)
|
application.router.add_static("/static", configuration.getpath("web", "static_path"), follow_symlinks=True)
|
||||||
|
|
||||||
views_root = Path(__file__).parent / "views"
|
for route, view in _dynamic_routes(configuration).items():
|
||||||
for route, view in _dynamic_routes(views_root, configuration).items():
|
|
||||||
application.router.add_view(route, view)
|
application.router.add_view(route, view)
|
||||||
|
133
subpackages.py
Normal file
133
subpackages.py
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
#
|
||||||
|
# Copyright (c) 2021-2024 ahriman team.
|
||||||
|
#
|
||||||
|
# This file is part of ahriman
|
||||||
|
# (see https://github.com/arcan1s/ahriman).
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
import argparse
|
||||||
|
import shutil
|
||||||
|
import site
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
prefix = Path(sys.prefix).relative_to("/")
|
||||||
|
site_packages = Path(site.getsitepackages()[0]).relative_to("/")
|
||||||
|
SUBPACKAGES = {
|
||||||
|
"ahriman-core": [
|
||||||
|
prefix / "bin",
|
||||||
|
prefix / "lib" / "systemd",
|
||||||
|
prefix / "share",
|
||||||
|
site_packages,
|
||||||
|
],
|
||||||
|
"ahriman-triggers": [
|
||||||
|
prefix / "share" / "ahriman" / "settings" / "ahriman.ini.d" / "00-triggers.ini",
|
||||||
|
site_packages / "ahriman" / "application" / "handlers" / "triggers_support.py",
|
||||||
|
site_packages / "ahriman" / "core" / "distributed",
|
||||||
|
site_packages / "ahriman" / "core" / "support",
|
||||||
|
],
|
||||||
|
"ahriman-web": [
|
||||||
|
prefix / "lib" / "systemd" / "system" / "ahriman-web.service",
|
||||||
|
prefix / "lib" / "systemd" / "system" / "ahriman-web@.service",
|
||||||
|
prefix / "share" / "ahriman" / "settings" / "ahriman.ini.d" / "00-web.ini",
|
||||||
|
prefix / "share" / "ahriman" / "templates" / "api.jinja2",
|
||||||
|
prefix / "share" / "ahriman" / "templates" / "build-status",
|
||||||
|
prefix / "share" / "ahriman" / "templates" / "build-status.jinja2",
|
||||||
|
prefix / "share" / "ahriman" / "templates" / "error.jinja2",
|
||||||
|
site_packages / "ahriman" / "application" / "handlers" / "web.py",
|
||||||
|
site_packages / "ahriman" / "core" / "auth",
|
||||||
|
site_packages / "ahriman" / "web",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def subpackages(root: Path) -> dict[str, list[Path]]:
|
||||||
|
"""
|
||||||
|
extend list of subpackages
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(Path): root directory
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict[str, list[Path]]: extended list of files which belong to a specific package
|
||||||
|
"""
|
||||||
|
for package, paths in SUBPACKAGES.items():
|
||||||
|
new_paths = []
|
||||||
|
for path in paths:
|
||||||
|
full_path = root / path
|
||||||
|
|
||||||
|
match path.suffix:
|
||||||
|
case ".py":
|
||||||
|
pycache_path = full_path.parent / "__pycache__"
|
||||||
|
new_paths.extend(
|
||||||
|
new_path.relative_to(root) for new_path in pycache_path.glob(f"{full_path.stem}.*.pyc")
|
||||||
|
)
|
||||||
|
|
||||||
|
SUBPACKAGES[package].extend(new_paths)
|
||||||
|
|
||||||
|
return SUBPACKAGES
|
||||||
|
|
||||||
|
|
||||||
|
def process(root: Path, include: list[Path], exclude: list[Path]) -> None:
|
||||||
|
"""
|
||||||
|
remove files based on patterns
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(Path): root directory
|
||||||
|
include(list[Path]): list of files to include to the subpackage
|
||||||
|
exclude(list[Path]): list of files to exclude from the subpackage
|
||||||
|
"""
|
||||||
|
for subdirectory, _, files in root.walk(top_down=False):
|
||||||
|
for file in files:
|
||||||
|
full_path = subdirectory / file
|
||||||
|
relative_path = full_path.relative_to(root)
|
||||||
|
|
||||||
|
if not any(relative_path.is_relative_to(path) for path in include):
|
||||||
|
full_path.unlink()
|
||||||
|
elif any(relative_path.is_relative_to(path) for path in exclude):
|
||||||
|
full_path.unlink()
|
||||||
|
|
||||||
|
content = list(subdirectory.iterdir())
|
||||||
|
if not content:
|
||||||
|
shutil.rmtree(subdirectory)
|
||||||
|
|
||||||
|
|
||||||
|
def run() -> None:
|
||||||
|
"""
|
||||||
|
run application
|
||||||
|
"""
|
||||||
|
parser = argparse.ArgumentParser(description="Split package into subpackages")
|
||||||
|
parser.add_argument("root", help="package root", type=Path)
|
||||||
|
parser.add_argument("subpackage", help="subpackage name", choices=SUBPACKAGES.keys())
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
full_subpackages = subpackages(args.root)
|
||||||
|
include = full_subpackages[args.subpackage]
|
||||||
|
exclude = [
|
||||||
|
path
|
||||||
|
for subpackage, portion in full_subpackages.items()
|
||||||
|
if subpackage != args.subpackage
|
||||||
|
for path in portion
|
||||||
|
if not any(include_path.is_relative_to(path) for include_path in include)
|
||||||
|
]
|
||||||
|
|
||||||
|
process(args.root, include, exclude)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
run()
|
@ -4,7 +4,7 @@ import pytest
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
|
|
||||||
from ahriman.application.handlers import Handler
|
from ahriman.application.handlers.handler import Handler
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.exceptions import ExitCode, MissingArchitectureError, MultipleArchitecturesError
|
from ahriman.core.exceptions import ExitCode, MissingArchitectureError, MultipleArchitecturesError
|
||||||
from ahriman.models.log_handler import LogHandler
|
from ahriman.models.log_handler import LogHandler
|
||||||
@ -19,7 +19,7 @@ def test_call(args: argparse.Namespace, configuration: Configuration, mocker: Mo
|
|||||||
args.log_handler = LogHandler.Console
|
args.log_handler = LogHandler.Console
|
||||||
args.quiet = False
|
args.quiet = False
|
||||||
args.report = False
|
args.report = False
|
||||||
mocker.patch("ahriman.application.handlers.Handler.run")
|
mocker.patch("ahriman.application.handlers.handler.Handler.run")
|
||||||
configuration_mock = mocker.patch("ahriman.core.configuration.Configuration.from_path", return_value=configuration)
|
configuration_mock = mocker.patch("ahriman.core.configuration.Configuration.from_path", return_value=configuration)
|
||||||
log_handler_mock = mocker.patch("ahriman.core.log.log_loader.LogLoader.handler", return_value=args.log_handler)
|
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")
|
log_load_mock = mocker.patch("ahriman.core.log.log_loader.LogLoader.load")
|
||||||
@ -76,7 +76,7 @@ def test_execute(args: argparse.Namespace, mocker: MockerFixture) -> None:
|
|||||||
RepositoryId("i686", "aur"),
|
RepositoryId("i686", "aur"),
|
||||||
RepositoryId("x86_64", "aur"),
|
RepositoryId("x86_64", "aur"),
|
||||||
]
|
]
|
||||||
mocker.patch("ahriman.application.handlers.Handler.repositories_extract", return_value=ids)
|
mocker.patch("ahriman.application.handlers.handler.Handler.repositories_extract", return_value=ids)
|
||||||
starmap_mock = mocker.patch("multiprocessing.pool.Pool.starmap")
|
starmap_mock = mocker.patch("multiprocessing.pool.Pool.starmap")
|
||||||
|
|
||||||
Handler.execute(args)
|
Handler.execute(args)
|
||||||
@ -88,7 +88,7 @@ def test_execute_multiple_not_supported(args: argparse.Namespace, mocker: Mocker
|
|||||||
must raise an exception if multiple architectures are not supported by the handler
|
must raise an exception if multiple architectures are not supported by the handler
|
||||||
"""
|
"""
|
||||||
args.command = "web"
|
args.command = "web"
|
||||||
mocker.patch("ahriman.application.handlers.Handler.repositories_extract", return_value=[
|
mocker.patch("ahriman.application.handlers.handler.Handler.repositories_extract", return_value=[
|
||||||
RepositoryId("i686", "aur"),
|
RepositoryId("i686", "aur"),
|
||||||
RepositoryId("x86_64", "aur"),
|
RepositoryId("x86_64", "aur"),
|
||||||
])
|
])
|
||||||
@ -102,7 +102,7 @@ def test_execute_single(args: argparse.Namespace, mocker: MockerFixture) -> None
|
|||||||
"""
|
"""
|
||||||
must run execution in current process if only one architecture supplied
|
must run execution in current process if only one architecture supplied
|
||||||
"""
|
"""
|
||||||
mocker.patch("ahriman.application.handlers.Handler.repositories_extract", return_value=[
|
mocker.patch("ahriman.application.handlers.handler.Handler.repositories_extract", return_value=[
|
||||||
RepositoryId("x86_64", "aur"),
|
RepositoryId("x86_64", "aur"),
|
||||||
])
|
])
|
||||||
starmap_mock = mocker.patch("multiprocessing.pool.Pool.starmap")
|
starmap_mock = mocker.patch("multiprocessing.pool.Pool.starmap")
|
||||||
|
@ -3,7 +3,7 @@ import pytest
|
|||||||
|
|
||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
|
|
||||||
from ahriman.application.handlers import Add
|
from ahriman.application.handlers.add import Add
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.repository import Repository
|
from ahriman.core.repository import Repository
|
||||||
from ahriman.models.package import Package
|
from ahriman.models.package import Package
|
||||||
@ -82,7 +82,7 @@ def test_run_with_updates(args: argparse.Namespace, configuration: Configuration
|
|||||||
mocker.patch("ahriman.application.application.Application.add")
|
mocker.patch("ahriman.application.application.Application.add")
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
application_mock = mocker.patch("ahriman.application.application.Application.update", return_value=result)
|
application_mock = mocker.patch("ahriman.application.application.Application.update", return_value=result)
|
||||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_status")
|
check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_status")
|
||||||
changes_mock = mocker.patch("ahriman.application.application.Application.changes")
|
changes_mock = mocker.patch("ahriman.application.application.Application.changes")
|
||||||
updates_mock = mocker.patch("ahriman.application.application.Application.updates", return_value=[package_ahriman])
|
updates_mock = mocker.patch("ahriman.application.application.Application.updates", return_value=[package_ahriman])
|
||||||
dependencies_mock = mocker.patch("ahriman.application.application.Application.with_dependencies",
|
dependencies_mock = mocker.patch("ahriman.application.application.Application.with_dependencies",
|
||||||
@ -113,7 +113,7 @@ def test_run_no_changes(args: argparse.Namespace, configuration: Configuration,
|
|||||||
mocker.patch("ahriman.application.application.Application.add")
|
mocker.patch("ahriman.application.application.Application.add")
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
mocker.patch("ahriman.application.application.Application.update")
|
mocker.patch("ahriman.application.application.Application.update")
|
||||||
mocker.patch("ahriman.application.handlers.Handler.check_status")
|
mocker.patch("ahriman.application.handlers.handler.Handler.check_status")
|
||||||
mocker.patch("ahriman.application.application.Application.updates")
|
mocker.patch("ahriman.application.application.Application.updates")
|
||||||
mocker.patch("ahriman.application.application.Application.with_dependencies")
|
mocker.patch("ahriman.application.application.Application.with_dependencies")
|
||||||
mocker.patch("ahriman.application.application.Application.print_updates")
|
mocker.patch("ahriman.application.application.Application.print_updates")
|
||||||
@ -138,7 +138,7 @@ def test_run_empty_exception(args: argparse.Namespace, configuration: Configurat
|
|||||||
mocker.patch("ahriman.application.application.Application.with_dependencies")
|
mocker.patch("ahriman.application.application.Application.with_dependencies")
|
||||||
mocker.patch("ahriman.application.application.Application.updates")
|
mocker.patch("ahriman.application.application.Application.updates")
|
||||||
mocker.patch("ahriman.application.application.Application.print_updates")
|
mocker.patch("ahriman.application.application.Application.print_updates")
|
||||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_status")
|
check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_status")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
Add.run(args, repository_id, configuration, report=False)
|
Add.run(args, repository_id, configuration, report=False)
|
||||||
|
@ -4,7 +4,7 @@ from pathlib import Path
|
|||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
from unittest.mock import MagicMock
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
from ahriman.application.handlers import Backup
|
from ahriman.application.handlers.backup import Backup
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.models.repository_paths import RepositoryPaths
|
from ahriman.models.repository_paths import RepositoryPaths
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
|
|||||||
must run command
|
must run command
|
||||||
"""
|
"""
|
||||||
args = _default_args(args)
|
args = _default_args(args)
|
||||||
mocker.patch("ahriman.application.handlers.Backup.get_paths", return_value=[Path("path")])
|
mocker.patch("ahriman.application.handlers.backup.Backup.get_paths", return_value=[Path("path")])
|
||||||
tarfile = MagicMock()
|
tarfile = MagicMock()
|
||||||
add_mock = tarfile.__enter__.return_value = MagicMock()
|
add_mock = tarfile.__enter__.return_value = MagicMock()
|
||||||
mocker.patch("ahriman.application.handlers.backup.tarfile.open", return_value=tarfile)
|
mocker.patch("ahriman.application.handlers.backup.tarfile.open", return_value=tarfile)
|
||||||
|
@ -3,7 +3,7 @@ import pytest
|
|||||||
|
|
||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
|
|
||||||
from ahriman.application.handlers import Change
|
from ahriman.application.handlers.change import Change
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.database import SQLite
|
from ahriman.core.database import SQLite
|
||||||
from ahriman.core.repository import Repository
|
from ahriman.core.repository import Repository
|
||||||
@ -36,7 +36,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
|
|||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
application_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.package_changes_get",
|
application_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.package_changes_get",
|
||||||
return_value=Changes("sha", "change"))
|
return_value=Changes("sha", "change"))
|
||||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_status")
|
check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_status")
|
||||||
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
@ -55,7 +55,7 @@ def test_run_empty_exception(args: argparse.Namespace, configuration: Configurat
|
|||||||
args.exit_code = True
|
args.exit_code = True
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
mocker.patch("ahriman.core.status.local_client.LocalClient.package_changes_get", return_value=Changes())
|
mocker.patch("ahriman.core.status.local_client.LocalClient.package_changes_get", return_value=Changes())
|
||||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_status")
|
check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_status")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
Change.run(args, repository_id, configuration, report=False)
|
Change.run(args, repository_id, configuration, report=False)
|
||||||
|
@ -2,7 +2,7 @@ import argparse
|
|||||||
|
|
||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
|
|
||||||
from ahriman.application.handlers import Clean
|
from ahriman.application.handlers.clean import Clean
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.repository import Repository
|
from ahriman.core.repository import Repository
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import pytest
|
|||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
|
|
||||||
from ahriman.application.application import Application
|
from ahriman.application.application import Application
|
||||||
from ahriman.application.handlers import Copy
|
from ahriman.application.handlers.copy import Copy
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.repository import Repository
|
from ahriman.core.repository import Repository
|
||||||
from ahriman.models.build_status import BuildStatusEnum
|
from ahriman.models.build_status import BuildStatusEnum
|
||||||
@ -37,7 +37,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
|
|||||||
args = _default_args(args)
|
args = _default_args(args)
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
mocker.patch("ahriman.core.repository.Repository.packages", return_value=[package_ahriman])
|
mocker.patch("ahriman.core.repository.Repository.packages", return_value=[package_ahriman])
|
||||||
application_mock = mocker.patch("ahriman.application.handlers.Copy.copy_package")
|
application_mock = mocker.patch("ahriman.application.handlers.copy.Copy.copy_package")
|
||||||
update_mock = mocker.patch("ahriman.application.application.Application.update")
|
update_mock = mocker.patch("ahriman.application.application.Application.update")
|
||||||
remove_mock = mocker.patch("ahriman.application.application.Application.remove")
|
remove_mock = mocker.patch("ahriman.application.application.Application.remove")
|
||||||
on_start_mock = mocker.patch("ahriman.application.application.Application.on_start")
|
on_start_mock = mocker.patch("ahriman.application.application.Application.on_start")
|
||||||
@ -59,7 +59,7 @@ def test_run_remove(args: argparse.Namespace, configuration: Configuration, repo
|
|||||||
args.remove = True
|
args.remove = True
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
mocker.patch("ahriman.core.repository.Repository.packages", return_value=[package_ahriman])
|
mocker.patch("ahriman.core.repository.Repository.packages", return_value=[package_ahriman])
|
||||||
mocker.patch("ahriman.application.handlers.Copy.copy_package")
|
mocker.patch("ahriman.application.handlers.copy.Copy.copy_package")
|
||||||
mocker.patch("ahriman.application.application.Application.update")
|
mocker.patch("ahriman.application.application.Application.update")
|
||||||
remove_mock = mocker.patch("ahriman.application.application.Application.remove")
|
remove_mock = mocker.patch("ahriman.application.application.Application.remove")
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ def test_run_empty_exception(args: argparse.Namespace, configuration: Configurat
|
|||||||
args.exit_code = True
|
args.exit_code = True
|
||||||
mocker.patch("ahriman.core.repository.Repository.packages", return_value=[])
|
mocker.patch("ahriman.core.repository.Repository.packages", return_value=[])
|
||||||
mocker.patch("ahriman.application.application.Application.update")
|
mocker.patch("ahriman.application.application.Application.update")
|
||||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_status")
|
check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_status")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
Copy.run(args, repository_id, configuration, report=False)
|
Copy.run(args, repository_id, configuration, report=False)
|
||||||
|
@ -2,7 +2,7 @@ import argparse
|
|||||||
|
|
||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
|
|
||||||
from ahriman.application.handlers import Daemon
|
from ahriman.application.handlers.daemon import Daemon
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.repository import Repository
|
from ahriman.core.repository import Repository
|
||||||
from ahriman.models.package import Package
|
from ahriman.models.package import Package
|
||||||
@ -31,7 +31,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, package_ahr
|
|||||||
"""
|
"""
|
||||||
args = _default_args(args)
|
args = _default_args(args)
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
run_mock = mocker.patch("ahriman.application.handlers.Update.run")
|
run_mock = mocker.patch("ahriman.application.handlers.update.Update.run")
|
||||||
iter_mock = mocker.patch("ahriman.application.application.updates_iterator.UpdatesIterator.__iter__",
|
iter_mock = mocker.patch("ahriman.application.application.updates_iterator.UpdatesIterator.__iter__",
|
||||||
return_value=iter([[package_ahriman.base]]))
|
return_value=iter([[package_ahriman.base]]))
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ def test_run_no_partitions(args: argparse.Namespace, configuration: Configuratio
|
|||||||
args = _default_args(args)
|
args = _default_args(args)
|
||||||
args.partitions = False
|
args.partitions = False
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
run_mock = mocker.patch("ahriman.application.handlers.Update.run")
|
run_mock = mocker.patch("ahriman.application.handlers.update.Update.run")
|
||||||
iter_mock = mocker.patch("ahriman.application.application.updates_iterator.UpdatesIterator.__iter__",
|
iter_mock = mocker.patch("ahriman.application.application.updates_iterator.UpdatesIterator.__iter__",
|
||||||
return_value=iter([[]]))
|
return_value=iter([[]]))
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ def test_run_no_updates(args: argparse.Namespace, configuration: Configuration,
|
|||||||
"""
|
"""
|
||||||
args = _default_args(args)
|
args = _default_args(args)
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
run_mock = mocker.patch("ahriman.application.handlers.Update.run")
|
run_mock = mocker.patch("ahriman.application.handlers.update.Update.run")
|
||||||
iter_mock = mocker.patch("ahriman.application.application.updates_iterator.UpdatesIterator.__iter__",
|
iter_mock = mocker.patch("ahriman.application.application.updates_iterator.UpdatesIterator.__iter__",
|
||||||
return_value=iter([[package_ahriman.base], None]))
|
return_value=iter([[package_ahriman.base], None]))
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ import pytest
|
|||||||
|
|
||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
|
|
||||||
from ahriman.application.handlers import Dump
|
from ahriman.application.handlers.dump import Dump
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ import argparse
|
|||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
|
|
||||||
from ahriman.application.ahriman import _parser
|
from ahriman.application.ahriman import _parser
|
||||||
from ahriman.application.handlers import Help
|
from ahriman.application.handlers.help import Help
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import argparse
|
|||||||
|
|
||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
|
|
||||||
from ahriman.application.handlers import KeyImport
|
from ahriman.application.handlers.key_import import KeyImport
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.repository import Repository
|
from ahriman.core.repository import Repository
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ from pathlib import Path
|
|||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
|
|
||||||
from ahriman.application.application import Application
|
from ahriman.application.application import Application
|
||||||
from ahriman.application.handlers import Patch
|
from ahriman.application.handlers.patch import Patch
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.repository import Repository
|
from ahriman.core.repository import Repository
|
||||||
from ahriman.models.action import Action
|
from ahriman.models.action import Action
|
||||||
@ -40,9 +40,9 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
|
|||||||
args = _default_args(args)
|
args = _default_args(args)
|
||||||
args.action = Action.Update
|
args.action = Action.Update
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
patch_mock = mocker.patch("ahriman.application.handlers.Patch.patch_create_from_diff",
|
patch_mock = mocker.patch("ahriman.application.handlers.patch.Patch.patch_create_from_diff",
|
||||||
return_value=(args.package, PkgbuildPatch(None, "patch")))
|
return_value=(args.package, PkgbuildPatch(None, "patch")))
|
||||||
application_mock = mocker.patch("ahriman.application.handlers.Patch.patch_set_create")
|
application_mock = mocker.patch("ahriman.application.handlers.patch.Patch.patch_set_create")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
Patch.run(args, repository_id, configuration, report=False)
|
Patch.run(args, repository_id, configuration, report=False)
|
||||||
@ -61,8 +61,9 @@ def test_run_function(args: argparse.Namespace, configuration: Configuration, re
|
|||||||
args.variable = "version"
|
args.variable = "version"
|
||||||
patch = PkgbuildPatch(args.variable, args.patch)
|
patch = PkgbuildPatch(args.variable, args.patch)
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
patch_mock = mocker.patch("ahriman.application.handlers.Patch.patch_create_from_function", return_value=patch)
|
patch_mock = mocker.patch("ahriman.application.handlers.patch.Patch.patch_create_from_function",
|
||||||
application_mock = mocker.patch("ahriman.application.handlers.Patch.patch_set_create")
|
return_value=patch)
|
||||||
|
application_mock = mocker.patch("ahriman.application.handlers.patch.Patch.patch_set_create")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
Patch.run(args, repository_id, configuration, report=False)
|
Patch.run(args, repository_id, configuration, report=False)
|
||||||
@ -79,7 +80,7 @@ def test_run_list(args: argparse.Namespace, configuration: Configuration, reposi
|
|||||||
args.action = Action.List
|
args.action = Action.List
|
||||||
args.variable = ["version"]
|
args.variable = ["version"]
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
application_mock = mocker.patch("ahriman.application.handlers.Patch.patch_set_list")
|
application_mock = mocker.patch("ahriman.application.handlers.patch.Patch.patch_set_list")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
Patch.run(args, repository_id, configuration, report=False)
|
Patch.run(args, repository_id, configuration, report=False)
|
||||||
@ -95,7 +96,7 @@ def test_run_remove(args: argparse.Namespace, configuration: Configuration, repo
|
|||||||
args.action = Action.Remove
|
args.action = Action.Remove
|
||||||
args.variable = ["version"]
|
args.variable = ["version"]
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
application_mock = mocker.patch("ahriman.application.handlers.Patch.patch_set_remove")
|
application_mock = mocker.patch("ahriman.application.handlers.patch.Patch.patch_set_remove")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
Patch.run(args, repository_id, configuration, report=False)
|
Patch.run(args, repository_id, configuration, report=False)
|
||||||
@ -163,7 +164,7 @@ def test_patch_set_list(application: Application, mocker: MockerFixture) -> None
|
|||||||
get_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.package_patches_get",
|
get_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.package_patches_get",
|
||||||
return_value=[PkgbuildPatch(None, "patch"), PkgbuildPatch("version", "value")])
|
return_value=[PkgbuildPatch(None, "patch"), PkgbuildPatch("version", "value")])
|
||||||
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
||||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_status")
|
check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_status")
|
||||||
|
|
||||||
Patch.patch_set_list(application, "ahriman", ["version"], False)
|
Patch.patch_set_list(application, "ahriman", ["version"], False)
|
||||||
get_mock.assert_called_once_with("ahriman", None)
|
get_mock.assert_called_once_with("ahriman", None)
|
||||||
@ -178,7 +179,7 @@ def test_patch_set_list_all(application: Application, mocker: MockerFixture) ->
|
|||||||
get_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.package_patches_get",
|
get_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.package_patches_get",
|
||||||
return_value=[PkgbuildPatch(None, "patch")])
|
return_value=[PkgbuildPatch(None, "patch")])
|
||||||
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
||||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_status")
|
check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_status")
|
||||||
|
|
||||||
Patch.patch_set_list(application, "ahriman", None, False)
|
Patch.patch_set_list(application, "ahriman", None, False)
|
||||||
get_mock.assert_called_once_with("ahriman", None)
|
get_mock.assert_called_once_with("ahriman", None)
|
||||||
@ -191,7 +192,7 @@ def test_patch_set_list_empty_exception(application: Application, mocker: Mocker
|
|||||||
must raise ExitCode exception on empty patch list
|
must raise ExitCode exception on empty patch list
|
||||||
"""
|
"""
|
||||||
mocker.patch("ahriman.core.status.local_client.LocalClient.package_patches_get", return_value={})
|
mocker.patch("ahriman.core.status.local_client.LocalClient.package_patches_get", return_value={})
|
||||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_status")
|
check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_status")
|
||||||
|
|
||||||
Patch.patch_set_list(application, "ahriman", [], True)
|
Patch.patch_set_list(application, "ahriman", [], True)
|
||||||
check_mock.assert_called_once_with(True, [])
|
check_mock.assert_called_once_with(True, [])
|
||||||
|
@ -5,7 +5,7 @@ from pytest_mock import MockerFixture
|
|||||||
from unittest.mock import call as MockCall
|
from unittest.mock import call as MockCall
|
||||||
|
|
||||||
from ahriman.application.application import Application
|
from ahriman.application.application import Application
|
||||||
from ahriman.application.handlers import Rebuild
|
from ahriman.application.handlers.rebuild import Rebuild
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.repository import Repository
|
from ahriman.core.repository import Repository
|
||||||
from ahriman.models.build_status import BuildStatus, BuildStatusEnum
|
from ahriman.models.build_status import BuildStatus, BuildStatusEnum
|
||||||
@ -43,11 +43,12 @@ def test_run(args: argparse.Namespace, package_ahriman: Package, configuration:
|
|||||||
result = Result()
|
result = Result()
|
||||||
result.add_updated(package_ahriman)
|
result.add_updated(package_ahriman)
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
extract_mock = mocker.patch("ahriman.application.handlers.Rebuild.extract_packages", return_value=[package_ahriman])
|
extract_mock = mocker.patch("ahriman.application.handlers.rebuild.Rebuild.extract_packages",
|
||||||
|
return_value=[package_ahriman])
|
||||||
application_packages_mock = mocker.patch("ahriman.core.repository.repository.Repository.packages_depend_on",
|
application_packages_mock = mocker.patch("ahriman.core.repository.repository.Repository.packages_depend_on",
|
||||||
return_value=[package_ahriman])
|
return_value=[package_ahriman])
|
||||||
application_mock = mocker.patch("ahriman.application.application.Application.update", return_value=result)
|
application_mock = mocker.patch("ahriman.application.application.Application.update", return_value=result)
|
||||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_status")
|
check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_status")
|
||||||
on_start_mock = mocker.patch("ahriman.application.application.Application.on_start")
|
on_start_mock = mocker.patch("ahriman.application.application.Application.on_start")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
@ -70,7 +71,7 @@ def test_run_extract_packages(args: argparse.Namespace, configuration: Configura
|
|||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
mocker.patch("ahriman.application.application.Application.add")
|
mocker.patch("ahriman.application.application.Application.add")
|
||||||
mocker.patch("ahriman.application.application.Application.print_updates")
|
mocker.patch("ahriman.application.application.Application.print_updates")
|
||||||
extract_mock = mocker.patch("ahriman.application.handlers.Rebuild.extract_packages", return_value=[])
|
extract_mock = mocker.patch("ahriman.application.handlers.rebuild.Rebuild.extract_packages", return_value=[])
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
Rebuild.run(args, repository_id, configuration, report=False)
|
Rebuild.run(args, repository_id, configuration, report=False)
|
||||||
@ -85,9 +86,9 @@ def test_run_dry_run(args: argparse.Namespace, configuration: Configuration, rep
|
|||||||
args = _default_args(args)
|
args = _default_args(args)
|
||||||
args.dry_run = True
|
args.dry_run = True
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
mocker.patch("ahriman.application.handlers.Rebuild.extract_packages", return_value=[package_ahriman])
|
mocker.patch("ahriman.application.handlers.rebuild.Rebuild.extract_packages", return_value=[package_ahriman])
|
||||||
application_mock = mocker.patch("ahriman.application.application.Application.update")
|
application_mock = mocker.patch("ahriman.application.application.Application.update")
|
||||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_status")
|
check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_status")
|
||||||
print_mock = mocker.patch("ahriman.application.application.Application.print_updates")
|
print_mock = mocker.patch("ahriman.application.application.Application.print_updates")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
@ -106,7 +107,7 @@ def test_run_filter(args: argparse.Namespace, configuration: Configuration, repo
|
|||||||
args.depends_on = ["python-aur"]
|
args.depends_on = ["python-aur"]
|
||||||
mocker.patch("ahriman.application.application.Application.update")
|
mocker.patch("ahriman.application.application.Application.update")
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
mocker.patch("ahriman.application.handlers.Rebuild.extract_packages", return_value=[])
|
mocker.patch("ahriman.application.handlers.rebuild.Rebuild.extract_packages", return_value=[])
|
||||||
application_packages_mock = mocker.patch("ahriman.core.repository.repository.Repository.packages_depend_on")
|
application_packages_mock = mocker.patch("ahriman.core.repository.repository.Repository.packages_depend_on")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
@ -122,7 +123,7 @@ def test_run_without_filter(args: argparse.Namespace, configuration: Configurati
|
|||||||
args = _default_args(args)
|
args = _default_args(args)
|
||||||
mocker.patch("ahriman.application.application.Application.update")
|
mocker.patch("ahriman.application.application.Application.update")
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
mocker.patch("ahriman.application.handlers.Rebuild.extract_packages", return_value=[])
|
mocker.patch("ahriman.application.handlers.rebuild.Rebuild.extract_packages", return_value=[])
|
||||||
application_packages_mock = mocker.patch("ahriman.core.repository.repository.Repository.packages_depend_on")
|
application_packages_mock = mocker.patch("ahriman.core.repository.repository.Repository.packages_depend_on")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
@ -139,10 +140,10 @@ def test_run_update_empty_exception(args: argparse.Namespace, configuration: Con
|
|||||||
args.exit_code = True
|
args.exit_code = True
|
||||||
args.dry_run = True
|
args.dry_run = True
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
mocker.patch("ahriman.application.handlers.Rebuild.extract_packages")
|
mocker.patch("ahriman.application.handlers.rebuild.Rebuild.extract_packages")
|
||||||
mocker.patch("ahriman.core.repository.repository.Repository.packages_depend_on", return_value=[])
|
mocker.patch("ahriman.core.repository.repository.Repository.packages_depend_on", return_value=[])
|
||||||
mocker.patch("ahriman.application.application.Application.print_updates")
|
mocker.patch("ahriman.application.application.Application.print_updates")
|
||||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_status")
|
check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_status")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
Rebuild.run(args, repository_id, configuration, report=False)
|
Rebuild.run(args, repository_id, configuration, report=False)
|
||||||
@ -157,10 +158,10 @@ def test_run_build_empty_exception(args: argparse.Namespace, configuration: Conf
|
|||||||
args = _default_args(args)
|
args = _default_args(args)
|
||||||
args.exit_code = True
|
args.exit_code = True
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
mocker.patch("ahriman.application.handlers.Rebuild.extract_packages")
|
mocker.patch("ahriman.application.handlers.rebuild.Rebuild.extract_packages")
|
||||||
mocker.patch("ahriman.core.repository.repository.Repository.packages_depend_on", return_value=[package_ahriman])
|
mocker.patch("ahriman.core.repository.repository.Repository.packages_depend_on", return_value=[package_ahriman])
|
||||||
mocker.patch("ahriman.application.application.Application.update", return_value=Result())
|
mocker.patch("ahriman.application.application.Application.update", return_value=Result())
|
||||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_status")
|
check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_status")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
Rebuild.run(args, repository_id, configuration, report=False)
|
Rebuild.run(args, repository_id, configuration, report=False)
|
||||||
|
@ -2,7 +2,7 @@ import argparse
|
|||||||
|
|
||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
|
|
||||||
from ahriman.application.handlers import Remove
|
from ahriman.application.handlers.remove import Remove
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.repository import Repository
|
from ahriman.core.repository import Repository
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ import pytest
|
|||||||
|
|
||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
|
|
||||||
from ahriman.application.handlers import RemoveUnknown
|
from ahriman.application.handlers.remove_unknown import RemoveUnknown
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.repository import Repository
|
from ahriman.core.repository import Repository
|
||||||
from ahriman.models.package import Package
|
from ahriman.models.package import Package
|
||||||
|
@ -3,7 +3,7 @@ import pytest
|
|||||||
|
|
||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
|
|
||||||
from ahriman.application.handlers import Repositories
|
from ahriman.application.handlers.repositories import Repositories
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
|
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
|
|||||||
args = _default_args(args)
|
args = _default_args(args)
|
||||||
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
application_mock = mocker.patch("ahriman.application.handlers.Handler.repositories_extract",
|
application_mock = mocker.patch("ahriman.application.handlers.handler.Handler.repositories_extract",
|
||||||
return_value=[repository_id])
|
return_value=[repository_id])
|
||||||
|
|
||||||
Repositories.run(args, repository_id, configuration, report=False)
|
Repositories.run(args, repository_id, configuration, report=False)
|
||||||
|
@ -4,7 +4,7 @@ from pathlib import Path
|
|||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
from unittest.mock import MagicMock
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
from ahriman.application.handlers import Restore
|
from ahriman.application.handlers.restore import Restore
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import pytest
|
|||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
|
|
||||||
from ahriman.application.ahriman import _parser
|
from ahriman.application.ahriman import _parser
|
||||||
from ahriman.application.handlers import Run
|
from ahriman.application.handlers.run import Run
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.exceptions import ExitCode
|
from ahriman.core.exceptions import ExitCode
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
|
|||||||
must run command
|
must run command
|
||||||
"""
|
"""
|
||||||
args = _default_args(args)
|
args = _default_args(args)
|
||||||
application_mock = mocker.patch("ahriman.application.handlers.Run.run_command")
|
application_mock = mocker.patch("ahriman.application.handlers.run.Run.run_command")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
Run.run(args, repository_id, configuration, report=False)
|
Run.run(args, repository_id, configuration, report=False)
|
||||||
@ -42,7 +42,7 @@ def test_run_failed(args: argparse.Namespace, configuration: Configuration, mock
|
|||||||
"""
|
"""
|
||||||
args = _default_args(args)
|
args = _default_args(args)
|
||||||
args.command = ["help", "config"]
|
args.command = ["help", "config"]
|
||||||
application_mock = mocker.patch("ahriman.application.handlers.Run.run_command", return_value=False)
|
application_mock = mocker.patch("ahriman.application.handlers.run.Run.run_command", return_value=False)
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
with pytest.raises(ExitCode):
|
with pytest.raises(ExitCode):
|
||||||
@ -54,8 +54,13 @@ def test_run_command(mocker: MockerFixture) -> None:
|
|||||||
"""
|
"""
|
||||||
must correctly run external command
|
must correctly run external command
|
||||||
"""
|
"""
|
||||||
execute_mock = mocker.patch("ahriman.application.handlers.Help.execute")
|
# because of dynamic load we need to patch exact instance of the object
|
||||||
Run.run_command(["help"], _parser())
|
parser = _parser()
|
||||||
|
subparser = next((action for action in parser._actions if isinstance(action, argparse._SubParsersAction)), None)
|
||||||
|
action = subparser.choices["help"]
|
||||||
|
execute_mock = mocker.patch.object(action.get_default("handler"), "execute")
|
||||||
|
|
||||||
|
Run.run_command(["help"], parser)
|
||||||
execute_mock.assert_called_once_with(pytest.helpers.anyvar(int))
|
execute_mock.assert_called_once_with(pytest.helpers.anyvar(int))
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import pytest
|
|||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
from unittest.mock import call as MockCall
|
from unittest.mock import call as MockCall
|
||||||
|
|
||||||
from ahriman.application.handlers import Search
|
from ahriman.application.handlers.search import Search
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.exceptions import OptionError
|
from ahriman.core.exceptions import OptionError
|
||||||
from ahriman.core.repository import Repository
|
from ahriman.core.repository import Repository
|
||||||
@ -39,7 +39,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
|
|||||||
aur_search_mock = mocker.patch("ahriman.core.alpm.remote.AUR.multisearch", return_value=[aur_package_ahriman])
|
aur_search_mock = mocker.patch("ahriman.core.alpm.remote.AUR.multisearch", return_value=[aur_package_ahriman])
|
||||||
official_search_mock = mocker.patch("ahriman.core.alpm.remote.Official.multisearch",
|
official_search_mock = mocker.patch("ahriman.core.alpm.remote.Official.multisearch",
|
||||||
return_value=[aur_package_ahriman])
|
return_value=[aur_package_ahriman])
|
||||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_status")
|
check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_status")
|
||||||
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
@ -64,7 +64,7 @@ def test_run_empty_exception(args: argparse.Namespace, configuration: Configurat
|
|||||||
mocker.patch("ahriman.core.alpm.remote.Official.multisearch", return_value=[])
|
mocker.patch("ahriman.core.alpm.remote.Official.multisearch", return_value=[])
|
||||||
mocker.patch("ahriman.core.formatters.Printer.print")
|
mocker.patch("ahriman.core.formatters.Printer.print")
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_status")
|
check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_status")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
Search.run(args, repository_id, configuration, report=False)
|
Search.run(args, repository_id, configuration, report=False)
|
||||||
@ -80,7 +80,7 @@ def test_run_sort(args: argparse.Namespace, configuration: Configuration, reposi
|
|||||||
mocker.patch("ahriman.core.alpm.remote.AUR.multisearch", return_value=[aur_package_ahriman])
|
mocker.patch("ahriman.core.alpm.remote.AUR.multisearch", return_value=[aur_package_ahriman])
|
||||||
mocker.patch("ahriman.core.alpm.remote.Official.multisearch", return_value=[])
|
mocker.patch("ahriman.core.alpm.remote.Official.multisearch", return_value=[])
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
sort_mock = mocker.patch("ahriman.application.handlers.Search.sort")
|
sort_mock = mocker.patch("ahriman.application.handlers.search.Search.sort")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
Search.run(args, repository_id, configuration, report=False)
|
Search.run(args, repository_id, configuration, report=False)
|
||||||
@ -100,7 +100,7 @@ def test_run_sort_by(args: argparse.Namespace, configuration: Configuration, rep
|
|||||||
mocker.patch("ahriman.core.alpm.remote.AUR.multisearch", return_value=[aur_package_ahriman])
|
mocker.patch("ahriman.core.alpm.remote.AUR.multisearch", return_value=[aur_package_ahriman])
|
||||||
mocker.patch("ahriman.core.alpm.remote.Official.multisearch", return_value=[])
|
mocker.patch("ahriman.core.alpm.remote.Official.multisearch", return_value=[])
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
sort_mock = mocker.patch("ahriman.application.handlers.Search.sort")
|
sort_mock = mocker.patch("ahriman.application.handlers.search.Search.sort")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
Search.run(args, repository_id, configuration, report=False)
|
Search.run(args, repository_id, configuration, report=False)
|
||||||
|
@ -4,7 +4,7 @@ import pytest
|
|||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
|
|
||||||
from ahriman import __version__
|
from ahriman import __version__
|
||||||
from ahriman.application.handlers import ServiceUpdates
|
from ahriman.application.handlers.service_updates import ServiceUpdates
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.repository import Repository
|
from ahriman.core.repository import Repository
|
||||||
from ahriman.models.package import Package
|
from ahriman.models.package import Package
|
||||||
@ -34,7 +34,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
|
|||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
package_mock = mocker.patch("ahriman.models.package.Package.from_aur", return_value=package_ahriman)
|
package_mock = mocker.patch("ahriman.models.package.Package.from_aur", return_value=package_ahriman)
|
||||||
application_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
application_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
||||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_status")
|
check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_status")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
ServiceUpdates.run(args, repository_id, configuration, report=False)
|
ServiceUpdates.run(args, repository_id, configuration, report=False)
|
||||||
@ -53,7 +53,7 @@ def test_run_skip(args: argparse.Namespace, configuration: Configuration, reposi
|
|||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
mocker.patch("ahriman.models.package.Package.from_aur", return_value=package_ahriman)
|
mocker.patch("ahriman.models.package.Package.from_aur", return_value=package_ahriman)
|
||||||
application_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
application_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
||||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_status")
|
check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_status")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
ServiceUpdates.run(args, repository_id, configuration, report=False)
|
ServiceUpdates.run(args, repository_id, configuration, report=False)
|
||||||
|
@ -7,7 +7,7 @@ from typing import Any
|
|||||||
from unittest.mock import call as MockCall
|
from unittest.mock import call as MockCall
|
||||||
from urllib.parse import quote_plus as urlencode
|
from urllib.parse import quote_plus as urlencode
|
||||||
|
|
||||||
from ahriman.application.handlers import Setup
|
from ahriman.application.handlers.setup import Setup
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.exceptions import MissingArchitectureError
|
from ahriman.core.exceptions import MissingArchitectureError
|
||||||
from ahriman.core.repository import Repository
|
from ahriman.core.repository import Repository
|
||||||
@ -50,11 +50,11 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
|
|||||||
"""
|
"""
|
||||||
args = _default_args(args)
|
args = _default_args(args)
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
ahriman_configuration_mock = mocker.patch("ahriman.application.handlers.Setup.configuration_create_ahriman")
|
ahriman_configuration_mock = mocker.patch("ahriman.application.handlers.setup.Setup.configuration_create_ahriman")
|
||||||
devtools_configuration_mock = mocker.patch("ahriman.application.handlers.Setup.configuration_create_devtools")
|
devtools_configuration_mock = mocker.patch("ahriman.application.handlers.setup.Setup.configuration_create_devtools")
|
||||||
makepkg_configuration_mock = mocker.patch("ahriman.application.handlers.Setup.configuration_create_makepkg")
|
makepkg_configuration_mock = mocker.patch("ahriman.application.handlers.setup.Setup.configuration_create_makepkg")
|
||||||
sudo_configuration_mock = mocker.patch("ahriman.application.handlers.Setup.configuration_create_sudo")
|
sudo_configuration_mock = mocker.patch("ahriman.application.handlers.setup.Setup.configuration_create_sudo")
|
||||||
executable_mock = mocker.patch("ahriman.application.handlers.Setup.executable_create")
|
executable_mock = mocker.patch("ahriman.application.handlers.setup.Setup.executable_create")
|
||||||
init_mock = mocker.patch("ahriman.core.alpm.repo.Repo.init")
|
init_mock = mocker.patch("ahriman.core.alpm.repo.Repo.init")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
@ -95,12 +95,12 @@ def test_run_with_server(args: argparse.Namespace, configuration: Configuration,
|
|||||||
args = _default_args(args)
|
args = _default_args(args)
|
||||||
args.server = "server"
|
args.server = "server"
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
mocker.patch("ahriman.application.handlers.Setup.configuration_create_ahriman")
|
mocker.patch("ahriman.application.handlers.setup.Setup.configuration_create_ahriman")
|
||||||
mocker.patch("ahriman.application.handlers.Setup.configuration_create_makepkg")
|
mocker.patch("ahriman.application.handlers.setup.Setup.configuration_create_makepkg")
|
||||||
mocker.patch("ahriman.application.handlers.Setup.configuration_create_sudo")
|
mocker.patch("ahriman.application.handlers.setup.Setup.configuration_create_sudo")
|
||||||
mocker.patch("ahriman.application.handlers.Setup.executable_create")
|
mocker.patch("ahriman.application.handlers.setup.Setup.executable_create")
|
||||||
mocker.patch("ahriman.core.alpm.repo.Repo.init")
|
mocker.patch("ahriman.core.alpm.repo.Repo.init")
|
||||||
devtools_configuration_mock = mocker.patch("ahriman.application.handlers.Setup.configuration_create_devtools")
|
devtools_configuration_mock = mocker.patch("ahriman.application.handlers.setup.Setup.configuration_create_devtools")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
Setup.run(args, repository_id, configuration, report=False)
|
Setup.run(args, repository_id, configuration, report=False)
|
||||||
|
@ -3,7 +3,7 @@ import pytest
|
|||||||
|
|
||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
|
|
||||||
from ahriman.application.handlers import Shell
|
from ahriman.application.handlers.shell import Shell
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.repository import Repository
|
from ahriman.core.repository import Repository
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import argparse
|
|||||||
|
|
||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
|
|
||||||
from ahriman.application.handlers import Sign
|
from ahriman.application.handlers.sign import Sign
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.repository import Repository
|
from ahriman.core.repository import Repository
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ from pathlib import Path
|
|||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
from unittest.mock import call as MockCall
|
from unittest.mock import call as MockCall
|
||||||
|
|
||||||
from ahriman.application.handlers import Statistics
|
from ahriman.application.handlers.statistics import Statistics
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.repository import Repository
|
from ahriman.core.repository import Repository
|
||||||
from ahriman.core.utils import pretty_datetime, utcnow
|
from ahriman.core.utils import pretty_datetime, utcnow
|
||||||
@ -42,7 +42,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
|
|||||||
events = [Event("1", "1"), Event("2", "2")]
|
events = [Event("1", "1"), Event("2", "2")]
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
events_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.event_get", return_value=events)
|
events_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.event_get", return_value=events)
|
||||||
application_mock = mocker.patch("ahriman.application.handlers.Statistics.stats_per_package")
|
application_mock = mocker.patch("ahriman.application.handlers.statistics.Statistics.stats_per_package")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
Statistics.run(args, repository_id, configuration, report=False)
|
Statistics.run(args, repository_id, configuration, report=False)
|
||||||
@ -60,7 +60,7 @@ def test_run_for_package(args: argparse.Namespace, configuration: Configuration,
|
|||||||
events = [Event("1", "1"), Event("2", "2")]
|
events = [Event("1", "1"), Event("2", "2")]
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
events_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.event_get", return_value=events)
|
events_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.event_get", return_value=events)
|
||||||
application_mock = mocker.patch("ahriman.application.handlers.Statistics.stats_for_package")
|
application_mock = mocker.patch("ahriman.application.handlers.statistics.Statistics.stats_for_package")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
Statistics.run(args, repository_id, configuration, report=False)
|
Statistics.run(args, repository_id, configuration, report=False)
|
||||||
@ -77,7 +77,7 @@ def test_run_convert_from_date(args: argparse.Namespace, configuration: Configur
|
|||||||
date = utcnow()
|
date = utcnow()
|
||||||
args.from_date = date.isoformat()
|
args.from_date = date.isoformat()
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
mocker.patch("ahriman.application.handlers.Statistics.stats_per_package")
|
mocker.patch("ahriman.application.handlers.statistics.Statistics.stats_per_package")
|
||||||
events_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.event_get", return_value=[])
|
events_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.event_get", return_value=[])
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
@ -94,7 +94,7 @@ def test_run_convert_to_date(args: argparse.Namespace, configuration: Configurat
|
|||||||
date = utcnow()
|
date = utcnow()
|
||||||
args.to_date = date.isoformat()
|
args.to_date = date.isoformat()
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
mocker.patch("ahriman.application.handlers.Statistics.stats_per_package")
|
mocker.patch("ahriman.application.handlers.statistics.Statistics.stats_per_package")
|
||||||
events_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.event_get", return_value=[])
|
events_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.event_get", return_value=[])
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
@ -147,8 +147,8 @@ def test_stats_for_package(mocker: MockerFixture) -> None:
|
|||||||
must print statistics for the package
|
must print statistics for the package
|
||||||
"""
|
"""
|
||||||
events = [Event("event", "1"), Event("event", "1")]
|
events = [Event("event", "1"), Event("event", "1")]
|
||||||
events_mock = mocker.patch("ahriman.application.handlers.Statistics.event_stats")
|
events_mock = mocker.patch("ahriman.application.handlers.statistics.Statistics.event_stats")
|
||||||
chart_plot = mocker.patch("ahriman.application.handlers.Statistics.plot_times")
|
chart_plot = mocker.patch("ahriman.application.handlers.statistics.Statistics.plot_times")
|
||||||
|
|
||||||
Statistics.stats_for_package("event", events, None)
|
Statistics.stats_for_package("event", events, None)
|
||||||
events_mock.assert_called_once_with("event", events)
|
events_mock.assert_called_once_with("event", events)
|
||||||
@ -161,8 +161,8 @@ def test_stats_for_package_with_chart(mocker: MockerFixture) -> None:
|
|||||||
"""
|
"""
|
||||||
local = Path("local")
|
local = Path("local")
|
||||||
events = [Event("event", "1"), Event("event", "1")]
|
events = [Event("event", "1"), Event("event", "1")]
|
||||||
mocker.patch("ahriman.application.handlers.Statistics.event_stats")
|
mocker.patch("ahriman.application.handlers.statistics.Statistics.event_stats")
|
||||||
chart_plot = mocker.patch("ahriman.application.handlers.Statistics.plot_times")
|
chart_plot = mocker.patch("ahriman.application.handlers.statistics.Statistics.plot_times")
|
||||||
|
|
||||||
Statistics.stats_for_package("event", events, local)
|
Statistics.stats_for_package("event", events, local)
|
||||||
chart_plot.assert_called_once_with("event", events, local)
|
chart_plot.assert_called_once_with("event", events, local)
|
||||||
@ -174,8 +174,8 @@ def test_stats_per_package(mocker: MockerFixture) -> None:
|
|||||||
"""
|
"""
|
||||||
events = [Event("event", "1"), Event("event", "2"), Event("event", "1")]
|
events = [Event("event", "1"), Event("event", "2"), Event("event", "1")]
|
||||||
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
||||||
events_mock = mocker.patch("ahriman.application.handlers.Statistics.event_stats")
|
events_mock = mocker.patch("ahriman.application.handlers.statistics.Statistics.event_stats")
|
||||||
chart_plot = mocker.patch("ahriman.application.handlers.Statistics.plot_packages")
|
chart_plot = mocker.patch("ahriman.application.handlers.statistics.Statistics.plot_packages")
|
||||||
|
|
||||||
Statistics.stats_per_package("event", events, None)
|
Statistics.stats_per_package("event", events, None)
|
||||||
print_mock.assert_has_calls([
|
print_mock.assert_has_calls([
|
||||||
@ -192,8 +192,8 @@ def test_stats_per_package_with_chart(mocker: MockerFixture) -> None:
|
|||||||
"""
|
"""
|
||||||
local = Path("local")
|
local = Path("local")
|
||||||
events = [Event("event", "1"), Event("event", "2"), Event("event", "1")]
|
events = [Event("event", "1"), Event("event", "2"), Event("event", "1")]
|
||||||
mocker.patch("ahriman.application.handlers.Statistics.event_stats")
|
mocker.patch("ahriman.application.handlers.statistics.Statistics.event_stats")
|
||||||
chart_plot = mocker.patch("ahriman.application.handlers.Statistics.plot_packages")
|
chart_plot = mocker.patch("ahriman.application.handlers.statistics.Statistics.plot_packages")
|
||||||
|
|
||||||
Statistics.stats_per_package("event", events, local)
|
Statistics.stats_per_package("event", events, local)
|
||||||
chart_plot.assert_called_once_with("event", {"1": 2, "2": 1}, local)
|
chart_plot.assert_called_once_with("event", {"1": 2, "2": 1}, local)
|
||||||
|
@ -4,7 +4,7 @@ import pytest
|
|||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
from unittest.mock import call as MockCall
|
from unittest.mock import call as MockCall
|
||||||
|
|
||||||
from ahriman.application.handlers import Status
|
from ahriman.application.handlers.status import Status
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.database import SQLite
|
from ahriman.core.database import SQLite
|
||||||
from ahriman.core.repository import Repository
|
from ahriman.core.repository import Repository
|
||||||
@ -43,7 +43,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
|
|||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
application_mock = mocker.patch("ahriman.core.status.Client.status_get")
|
application_mock = mocker.patch("ahriman.core.status.Client.status_get")
|
||||||
packages_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.package_get", return_value=packages)
|
packages_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.package_get", return_value=packages)
|
||||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_status")
|
check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_status")
|
||||||
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
@ -67,7 +67,7 @@ def test_run_empty_exception(args: argparse.Namespace, configuration: Configurat
|
|||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
mocker.patch("ahriman.core.status.Client.status_get")
|
mocker.patch("ahriman.core.status.Client.status_get")
|
||||||
mocker.patch("ahriman.core.status.local_client.LocalClient.package_get", return_value=[])
|
mocker.patch("ahriman.core.status.local_client.LocalClient.package_get", return_value=[])
|
||||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_status")
|
check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_status")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
Status.run(args, repository_id, configuration, report=False)
|
Status.run(args, repository_id, configuration, report=False)
|
||||||
|
@ -2,7 +2,7 @@ import argparse
|
|||||||
|
|
||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
|
|
||||||
from ahriman.application.handlers import StatusUpdate
|
from ahriman.application.handlers.status_update import StatusUpdate
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.database import SQLite
|
from ahriman.core.database import SQLite
|
||||||
from ahriman.core.repository import Repository
|
from ahriman.core.repository import Repository
|
||||||
|
@ -4,7 +4,7 @@ import pytest
|
|||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
from unittest.mock import call as MockCall
|
from unittest.mock import call as MockCall
|
||||||
|
|
||||||
from ahriman.application.handlers import Structure
|
from ahriman.application.handlers.structure import Structure
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.repository import Repository
|
from ahriman.core.repository import Repository
|
||||||
from ahriman.models.package import Package
|
from ahriman.models.package import Package
|
||||||
|
@ -4,7 +4,7 @@ from pathlib import Path
|
|||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
from unittest.mock import call as MockCall
|
from unittest.mock import call as MockCall
|
||||||
|
|
||||||
from ahriman.application.handlers import TreeMigrate
|
from ahriman.application.handlers.tree_migrate import TreeMigrate
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.models.repository_id import RepositoryId
|
from ahriman.models.repository_id import RepositoryId
|
||||||
from ahriman.models.repository_paths import RepositoryPaths
|
from ahriman.models.repository_paths import RepositoryPaths
|
||||||
@ -15,7 +15,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
|
|||||||
must run command
|
must run command
|
||||||
"""
|
"""
|
||||||
tree_create_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
|
tree_create_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
|
||||||
application_mock = mocker.patch("ahriman.application.handlers.TreeMigrate.tree_move")
|
application_mock = mocker.patch("ahriman.application.handlers.tree_migrate.TreeMigrate.tree_move")
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
old_paths = configuration.repository_paths
|
old_paths = configuration.repository_paths
|
||||||
new_paths = RepositoryPaths(old_paths.root, old_paths.repository_id, _force_current_tree=True)
|
new_paths = RepositoryPaths(old_paths.root, old_paths.repository_id, _force_current_tree=True)
|
||||||
|
@ -2,7 +2,7 @@ import argparse
|
|||||||
|
|
||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
|
|
||||||
from ahriman.application.handlers import Triggers
|
from ahriman.application.handlers.triggers import Triggers
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.repository import Repository
|
from ahriman.core.repository import Repository
|
||||||
from ahriman.models.package import Package
|
from ahriman.models.package import Package
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
# nothing to test here
|
@ -4,7 +4,7 @@ import pytest
|
|||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
|
|
||||||
from ahriman.application.ahriman import _parser
|
from ahriman.application.ahriman import _parser
|
||||||
from ahriman.application.handlers import UnsafeCommands
|
from ahriman.application.handlers.unsafe_commands import UnsafeCommands
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
|
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
|
|||||||
must run command
|
must run command
|
||||||
"""
|
"""
|
||||||
args = _default_args(args)
|
args = _default_args(args)
|
||||||
commands_mock = mocker.patch("ahriman.application.handlers.UnsafeCommands.get_unsafe_commands",
|
commands_mock = mocker.patch("ahriman.application.handlers.unsafe_commands.UnsafeCommands.get_unsafe_commands",
|
||||||
return_value=["command"])
|
return_value=["command"])
|
||||||
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
||||||
|
|
||||||
@ -44,9 +44,9 @@ def test_run_check(args: argparse.Namespace, configuration: Configuration, mocke
|
|||||||
"""
|
"""
|
||||||
args = _default_args(args)
|
args = _default_args(args)
|
||||||
args.subcommand = ["clean"]
|
args.subcommand = ["clean"]
|
||||||
commands_mock = mocker.patch("ahriman.application.handlers.UnsafeCommands.get_unsafe_commands",
|
commands_mock = mocker.patch("ahriman.application.handlers.unsafe_commands.UnsafeCommands.get_unsafe_commands",
|
||||||
return_value=["command"])
|
return_value=["command"])
|
||||||
check_mock = mocker.patch("ahriman.application.handlers.UnsafeCommands.check_unsafe")
|
check_mock = mocker.patch("ahriman.application.handlers.unsafe_commands.UnsafeCommands.check_unsafe")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
UnsafeCommands.run(args, repository_id, configuration, report=False)
|
UnsafeCommands.run(args, repository_id, configuration, report=False)
|
||||||
@ -58,7 +58,7 @@ def test_check_unsafe(mocker: MockerFixture) -> None:
|
|||||||
"""
|
"""
|
||||||
must check if command is unsafe
|
must check if command is unsafe
|
||||||
"""
|
"""
|
||||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_status")
|
check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_status")
|
||||||
UnsafeCommands.check_unsafe(["service-clean"], ["service-clean"], _parser())
|
UnsafeCommands.check_unsafe(["service-clean"], ["service-clean"], _parser())
|
||||||
check_mock.assert_called_once_with(True, False)
|
check_mock.assert_called_once_with(True, False)
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ def test_check_unsafe_safe(mocker: MockerFixture) -> None:
|
|||||||
"""
|
"""
|
||||||
must check if command is safe
|
must check if command is safe
|
||||||
"""
|
"""
|
||||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_status")
|
check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_status")
|
||||||
UnsafeCommands.check_unsafe(["package-status"], ["service-clean"], _parser())
|
UnsafeCommands.check_unsafe(["package-status"], ["service-clean"], _parser())
|
||||||
check_mock.assert_called_once_with(True, True)
|
check_mock.assert_called_once_with(True, True)
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ from pytest_mock import MockerFixture
|
|||||||
from unittest.mock import call as MockCall
|
from unittest.mock import call as MockCall
|
||||||
|
|
||||||
from ahriman.application.application import Application
|
from ahriman.application.application import Application
|
||||||
from ahriman.application.handlers import Update
|
from ahriman.application.handlers.update import Update
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.repository import Repository
|
from ahriman.core.repository import Repository
|
||||||
from ahriman.models.package import Package
|
from ahriman.models.package import Package
|
||||||
@ -49,7 +49,7 @@ def test_run(args: argparse.Namespace, package_ahriman: Package, configuration:
|
|||||||
result.add_updated(package_ahriman)
|
result.add_updated(package_ahriman)
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
application_mock = mocker.patch("ahriman.application.application.Application.update", return_value=result)
|
application_mock = mocker.patch("ahriman.application.application.Application.update", return_value=result)
|
||||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_status")
|
check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_status")
|
||||||
dependencies_mock = mocker.patch("ahriman.application.application.Application.with_dependencies",
|
dependencies_mock = mocker.patch("ahriman.application.application.Application.with_dependencies",
|
||||||
return_value=[package_ahriman])
|
return_value=[package_ahriman])
|
||||||
updates_mock = mocker.patch("ahriman.application.application.Application.updates", return_value=[package_ahriman])
|
updates_mock = mocker.patch("ahriman.application.application.Application.updates", return_value=[package_ahriman])
|
||||||
@ -81,7 +81,7 @@ def test_run_empty_exception(args: argparse.Namespace, configuration: Configurat
|
|||||||
args.dry_run = True
|
args.dry_run = True
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
mocker.patch("ahriman.application.application.Application.updates", return_value=[])
|
mocker.patch("ahriman.application.application.Application.updates", return_value=[])
|
||||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_status")
|
check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_status")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
Update.run(args, repository_id, configuration, report=False)
|
Update.run(args, repository_id, configuration, report=False)
|
||||||
@ -101,7 +101,7 @@ def test_run_update_empty_exception(args: argparse.Namespace, package_ahriman: P
|
|||||||
mocker.patch("ahriman.application.application.Application.with_dependencies", return_value=[package_ahriman])
|
mocker.patch("ahriman.application.application.Application.with_dependencies", return_value=[package_ahriman])
|
||||||
mocker.patch("ahriman.application.application.Application.print_updates")
|
mocker.patch("ahriman.application.application.Application.print_updates")
|
||||||
mocker.patch("ahriman.application.application.Application.changes")
|
mocker.patch("ahriman.application.application.Application.changes")
|
||||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_status")
|
check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_status")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
Update.run(args, repository_id, configuration, report=False)
|
Update.run(args, repository_id, configuration, report=False)
|
||||||
@ -117,7 +117,7 @@ def test_run_dry_run(args: argparse.Namespace, package_ahriman: Package, configu
|
|||||||
args.dry_run = True
|
args.dry_run = True
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
application_mock = mocker.patch("ahriman.application.application.Application.update")
|
application_mock = mocker.patch("ahriman.application.application.Application.update")
|
||||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_status")
|
check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_status")
|
||||||
updates_mock = mocker.patch("ahriman.application.application.Application.updates", return_value=[package_ahriman])
|
updates_mock = mocker.patch("ahriman.application.application.Application.updates", return_value=[package_ahriman])
|
||||||
changes_mock = mocker.patch("ahriman.application.application.Application.changes")
|
changes_mock = mocker.patch("ahriman.application.application.Application.changes")
|
||||||
|
|
||||||
@ -140,7 +140,7 @@ def test_run_no_changes(args: argparse.Namespace, configuration: Configuration,
|
|||||||
args.changes = False
|
args.changes = False
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||||
mocker.patch("ahriman.application.application.Application.update")
|
mocker.patch("ahriman.application.application.Application.update")
|
||||||
mocker.patch("ahriman.application.handlers.Handler.check_status")
|
mocker.patch("ahriman.application.handlers.handler.Handler.check_status")
|
||||||
mocker.patch("ahriman.application.application.Application.updates")
|
mocker.patch("ahriman.application.application.Application.updates")
|
||||||
changes_mock = mocker.patch("ahriman.application.application.Application.changes")
|
changes_mock = mocker.patch("ahriman.application.application.Application.changes")
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import pytest
|
|||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
from unittest.mock import call as MockCall
|
from unittest.mock import call as MockCall
|
||||||
|
|
||||||
from ahriman.application.handlers import Users
|
from ahriman.application.handlers.users import Users
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.database import SQLite
|
from ahriman.core.database import SQLite
|
||||||
from ahriman.core.exceptions import PasswordError
|
from ahriman.core.exceptions import PasswordError
|
||||||
@ -42,7 +42,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, database: S
|
|||||||
packager_id=args.packager, key=args.key)
|
packager_id=args.packager, key=args.key)
|
||||||
mocker.patch("ahriman.core.database.SQLite.load", return_value=database)
|
mocker.patch("ahriman.core.database.SQLite.load", return_value=database)
|
||||||
mocker.patch("ahriman.models.user.User.hash_password", return_value=user)
|
mocker.patch("ahriman.models.user.User.hash_password", return_value=user)
|
||||||
create_user_mock = mocker.patch("ahriman.application.handlers.Users.user_create", return_value=user)
|
create_user_mock = mocker.patch("ahriman.application.handlers.users.Users.user_create", return_value=user)
|
||||||
update_mock = mocker.patch("ahriman.core.database.SQLite.user_update")
|
update_mock = mocker.patch("ahriman.core.database.SQLite.user_update")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
@ -60,7 +60,7 @@ def test_run_empty_salt(args: argparse.Namespace, configuration: Configuration,
|
|||||||
user = User(username=args.username, password=args.password, access=args.role,
|
user = User(username=args.username, password=args.password, access=args.role,
|
||||||
packager_id=args.packager, key=args.key)
|
packager_id=args.packager, key=args.key)
|
||||||
mocker.patch("ahriman.models.user.User.hash_password", return_value=user)
|
mocker.patch("ahriman.models.user.User.hash_password", return_value=user)
|
||||||
create_user_mock = mocker.patch("ahriman.application.handlers.Users.user_create", return_value=user)
|
create_user_mock = mocker.patch("ahriman.application.handlers.users.Users.user_create", return_value=user)
|
||||||
update_mock = mocker.patch("ahriman.core.database.SQLite.user_update")
|
update_mock = mocker.patch("ahriman.core.database.SQLite.user_update")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
@ -80,7 +80,7 @@ def test_run_empty_salt_without_password(args: argparse.Namespace, configuration
|
|||||||
packager_id=args.packager, key=args.key)
|
packager_id=args.packager, key=args.key)
|
||||||
mocker.patch("ahriman.core.database.SQLite.load", return_value=database)
|
mocker.patch("ahriman.core.database.SQLite.load", return_value=database)
|
||||||
mocker.patch("ahriman.models.user.User.hash_password", return_value=user)
|
mocker.patch("ahriman.models.user.User.hash_password", return_value=user)
|
||||||
create_user_mock = mocker.patch("ahriman.application.handlers.Users.user_create", return_value=user)
|
create_user_mock = mocker.patch("ahriman.application.handlers.users.Users.user_create", return_value=user)
|
||||||
update_mock = mocker.patch("ahriman.core.database.SQLite.user_update")
|
update_mock = mocker.patch("ahriman.core.database.SQLite.user_update")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
@ -97,7 +97,7 @@ def test_run_list(args: argparse.Namespace, configuration: Configuration, databa
|
|||||||
args = _default_args(args)
|
args = _default_args(args)
|
||||||
args.action = Action.List
|
args.action = Action.List
|
||||||
mocker.patch("ahriman.core.database.SQLite.load", return_value=database)
|
mocker.patch("ahriman.core.database.SQLite.load", return_value=database)
|
||||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_status")
|
check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_status")
|
||||||
list_mock = mocker.patch("ahriman.core.database.SQLite.user_list", return_value=[user])
|
list_mock = mocker.patch("ahriman.core.database.SQLite.user_list", return_value=[user])
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
@ -116,7 +116,7 @@ def test_run_empty_exception(args: argparse.Namespace, configuration: Configurat
|
|||||||
args.exit_code = True
|
args.exit_code = True
|
||||||
mocker.patch("ahriman.core.database.SQLite.load", return_value=database)
|
mocker.patch("ahriman.core.database.SQLite.load", return_value=database)
|
||||||
mocker.patch("ahriman.core.database.SQLite.user_list", return_value=[])
|
mocker.patch("ahriman.core.database.SQLite.user_list", return_value=[])
|
||||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_status")
|
check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_status")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
Users.run(args, repository_id, configuration, report=False)
|
Users.run(args, repository_id, configuration, report=False)
|
||||||
|
@ -4,7 +4,7 @@ import pytest
|
|||||||
|
|
||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
|
|
||||||
from ahriman.application.handlers import Validate
|
from ahriman.application.handlers.validate import Validate
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.configuration.schema import CONFIGURATION_SCHEMA
|
from ahriman.core.configuration.schema import CONFIGURATION_SCHEMA
|
||||||
from ahriman.core.configuration.validator import Validator
|
from ahriman.core.configuration.validator import Validator
|
||||||
|
@ -4,7 +4,7 @@ import pytest
|
|||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
from unittest.mock import call as MockCall
|
from unittest.mock import call as MockCall
|
||||||
|
|
||||||
from ahriman.application.handlers import Versions
|
from ahriman.application.handlers.versions import Versions
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
|
|
||||||
|
|
||||||
@ -12,7 +12,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
|
|||||||
"""
|
"""
|
||||||
must run command
|
must run command
|
||||||
"""
|
"""
|
||||||
application_mock = mocker.patch("ahriman.application.handlers.Versions.package_dependencies")
|
application_mock = mocker.patch("ahriman.application.handlers.versions.Versions.package_dependencies")
|
||||||
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
|
@ -3,7 +3,7 @@ import pytest
|
|||||||
|
|
||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
|
|
||||||
from ahriman.application.handlers import Web
|
from ahriman.application.handlers.web import Web
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.repository import Repository
|
from ahriman.core.repository import Repository
|
||||||
from ahriman.models.log_handler import LogHandler
|
from ahriman.models.log_handler import LogHandler
|
||||||
@ -43,7 +43,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
|
|||||||
stop_mock = mocker.patch("ahriman.core.spawn.Spawn.stop")
|
stop_mock = mocker.patch("ahriman.core.spawn.Spawn.stop")
|
||||||
join_mock = mocker.patch("ahriman.core.spawn.Spawn.join")
|
join_mock = mocker.patch("ahriman.core.spawn.Spawn.join")
|
||||||
_, repository_id = configuration.check_loaded()
|
_, repository_id = configuration.check_loaded()
|
||||||
mocker.patch("ahriman.application.handlers.Handler.repositories_extract", return_value=[repository_id])
|
mocker.patch("ahriman.application.handlers.handler.Handler.repositories_extract", return_value=[repository_id])
|
||||||
|
|
||||||
Web.run(args, repository_id, configuration, report=False)
|
Web.run(args, repository_id, configuration, report=False)
|
||||||
setup_mock.assert_called_once_with(configuration, pytest.helpers.anyvar(int), [repository_id])
|
setup_mock.assert_called_once_with(configuration, pytest.helpers.anyvar(int), [repository_id])
|
||||||
|
@ -5,7 +5,7 @@ from pathlib import Path
|
|||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
|
|
||||||
from ahriman.application import ahriman
|
from ahriman.application import ahriman
|
||||||
from ahriman.application.handlers import Handler
|
from ahriman.application.handlers.handler import Handler
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.models.action import Action
|
from ahriman.models.action import Action
|
||||||
from ahriman.models.build_status import BuildStatusEnum
|
from ahriman.models.build_status import BuildStatusEnum
|
||||||
|
25
tests/ahriman/core/test_module_loader.py
Normal file
25
tests/ahriman/core/test_module_loader.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import ahriman.web.views
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from ahriman.core.module_loader import _modules, implementations
|
||||||
|
from ahriman.web.views.base import BaseView
|
||||||
|
|
||||||
|
|
||||||
|
def test_implementations() -> None:
|
||||||
|
"""
|
||||||
|
must load implementations from the package
|
||||||
|
"""
|
||||||
|
routes = list(implementations(ahriman.web.views, BaseView))
|
||||||
|
assert routes
|
||||||
|
assert all(isinstance(view, type) for view in routes)
|
||||||
|
assert all(issubclass(view, BaseView) for view in routes)
|
||||||
|
|
||||||
|
|
||||||
|
def test_modules() -> None:
|
||||||
|
"""
|
||||||
|
must load modules
|
||||||
|
"""
|
||||||
|
modules = list(_modules(Path(__file__).parent.parent, "ahriman.web.views"))
|
||||||
|
assert modules
|
||||||
|
assert all(not module.ispkg for module in modules)
|
@ -132,7 +132,7 @@ def test_get_local_files(github: GitHub, resource_path_root: Path, mocker: Mocke
|
|||||||
"""
|
"""
|
||||||
must get all local files recursively
|
must get all local files recursively
|
||||||
"""
|
"""
|
||||||
walk_mock = mocker.patch("ahriman.core.utils.walk")
|
walk_mock = mocker.patch("ahriman.core.upload.github.walk")
|
||||||
github.get_local_files(resource_path_root)
|
github.get_local_files(resource_path_root)
|
||||||
walk_mock.assert_called()
|
walk_mock.assert_called()
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user