mirror of
https://github.com/arcan1s/ahriman.git
synced 2025-07-15 23:09:56 +00:00
Compare commits
12 Commits
2.10.1
...
1384efb31d
Author | SHA1 | Date | |
---|---|---|---|
1384efb31d | |||
8c6486c233 | |||
a1d0e993a8 | |||
572880eb73 | |||
d9eaf17a11 | |||
95e29d16bb | |||
1f2d56e605 | |||
1baf04998d | |||
3a88d00db0 | |||
b58d8d96ff | |||
4abe3b8963 | |||
237fec3f85 |
2
.github/workflows/setup.sh
vendored
2
.github/workflows/setup.sh
vendored
@ -12,7 +12,7 @@ pacman --noconfirm -Syu
|
||||
# main dependencies
|
||||
pacman --noconfirm -Sy base-devel devtools git pyalpm python-cerberus python-inflection python-passlib python-requests python-srcinfo python-systemd sudo
|
||||
# make dependencies
|
||||
pacman --noconfirm -Sy python-build python-installer python-wheel
|
||||
pacman --noconfirm -Sy python-build python-flit python-installer python-wheel
|
||||
# optional dependencies
|
||||
if [[ -z $MINIMAL_INSTALL ]]; then
|
||||
# VCS support
|
||||
|
@ -21,4 +21,3 @@ python:
|
||||
- docs
|
||||
- s3
|
||||
- web
|
||||
system_packages: true
|
||||
|
@ -158,7 +158,7 @@ Again, the most checks can be performed by `make check` command, though some add
|
||||
* One file should define only one class, exception is class satellites in case if file length remains less than 400 lines.
|
||||
* It is possible to create file which contains some functions (e.g. `ahriman.core.util`), but in this case you would need to define `__all__` attribute.
|
||||
* The file size mentioned above must be applicable in general. In case of big classes consider splitting them into traits. Note, however, that `pylint` includes comments and docstrings into counter, thus you need to check file size by other tools.
|
||||
* No global variable is allowed outside of `ahriman.version` module. `ahriman.core.context` is also special case.
|
||||
* No global variable is allowed outside of `ahriman` module. `ahriman.core.context` is also special case.
|
||||
* Single quotes are not allowed. The reason behind this restriction is the fact that docstrings must be written by using double quotes only, and we would like to make style consistent.
|
||||
* If your class writes anything to log, the `ahriman.core.log.LazyLogging` trait must be used.
|
||||
* Web API methods must be documented by using `aiohttp_apispec` library. Schema testing mostly should be implemented in related view class tests. Recommended example for documentation (excluding comments):
|
||||
|
@ -29,7 +29,7 @@ COPY "docker/install-aur-package.sh" "/usr/local/bin/install-aur-package"
|
||||
## install package dependencies
|
||||
## darcs is not installed by reasons, because it requires a lot haskell packages which dramatically increase image size
|
||||
RUN pacman -Sy --noconfirm --asdeps devtools git pyalpm python-cerberus python-inflection python-passlib python-requests python-srcinfo && \
|
||||
pacman -Sy --noconfirm --asdeps python-build python-installer python-wheel && \
|
||||
pacman -Sy --noconfirm --asdeps python-build python-flit python-installer python-wheel && \
|
||||
pacman -Sy --noconfirm --asdeps breezy mercurial python-aiohttp python-aiohttp-cors python-boto3 python-cryptography python-jinja python-requests-unixsocket python-systemd rsync subversion && \
|
||||
runuser -u build -- install-aur-package python-aioauth-client python-aiohttp-apispec-git python-aiohttp-jinja2 \
|
||||
python-aiohttp-debugtoolbar python-aiohttp-session python-aiohttp-security
|
||||
@ -39,7 +39,7 @@ RUN pacman -Sy --noconfirm --asdeps devtools git pyalpm python-cerberus python-i
|
||||
COPY --chown=build . "/home/build/ahriman"
|
||||
## create package archive and install it
|
||||
RUN cd "/home/build/ahriman" && \
|
||||
make VERSION=$(python -c "from src.ahriman.version import __version__; print(__version__)") archlinux && \
|
||||
make VERSION=$(python -c "from src.ahriman import __version__; print(__version__)") archlinux && \
|
||||
cp ./*-src.tar.xz "package/archlinux" && \
|
||||
cd "package/archlinux" && \
|
||||
runuser -u build -- makepkg --noconfirm --install --skipchecksums && \
|
||||
|
6
Makefile
6
Makefile
@ -3,7 +3,7 @@
|
||||
|
||||
PROJECT := ahriman
|
||||
|
||||
FILES := AUTHORS CONTRIBUTING.md COPYING Makefile README.md SECURITY.md docs package src setup.py tox.ini web.png
|
||||
FILES := AUTHORS CONTRIBUTING.md COPYING Makefile README.md SECURITY.md docs package pyproject.toml src tox.ini web.png
|
||||
TARGET_FILES := $(addprefix $(PROJECT)/, $(FILES))
|
||||
IGNORE_FILES := package/archlinux src/.mypy_cache
|
||||
|
||||
@ -38,7 +38,7 @@ html: specification
|
||||
tox -e docs-html
|
||||
|
||||
push: specification archlinux
|
||||
git add package/archlinux/PKGBUILD src/ahriman/version.py docs/ahriman-architecture.svg docs/ahriman.1 docs/completions/
|
||||
git add package/archlinux/PKGBUILD src/ahriman/__init__.py docs/ahriman-architecture.svg package/share/man/man1/ahriman.1 package/share/bash-completion/completions/_ahriman package/share/zsh/site-functions/_ahriman
|
||||
git commit -m "Release $(VERSION)"
|
||||
git tag "$(VERSION)"
|
||||
git push
|
||||
@ -56,4 +56,4 @@ version:
|
||||
ifndef VERSION
|
||||
$(error VERSION is required, but not set)
|
||||
endif
|
||||
sed -i 's/^__version__ = .*/__version__ = "$(VERSION)"/' src/ahriman/version.py
|
||||
sed -i 's/^__version__ = .*/__version__ = "$(VERSION)"/' src/ahriman/__init__.py
|
||||
|
@ -16,6 +16,7 @@ Wrapper for managing custom repository inspired by [repo-scripts](https://github
|
||||
* VCS packages support.
|
||||
* Official repository support.
|
||||
* Ability to patch AUR packages and even create package from local PKGBUILDs.
|
||||
* Various rebuild options with ability to automatically bump package version.
|
||||
* Sign support with gpg (repository, package), multiple packagers support.
|
||||
* Triggers for repository updates, e.g. synchronization to remote services (rsync, s3 and github) and report generation (email, html, telegram).
|
||||
* Repository status interface with optional authorization and control options:
|
||||
|
@ -59,7 +59,7 @@ systemd-machine-id-setup &> /dev/null
|
||||
if [ -n "$AHRIMAN_FORCE_ROOT" ]; then
|
||||
AHRIMAN_EXECUTABLE=("ahriman")
|
||||
elif ahriman help-commands-unsafe -- "$@" &> /dev/null; then
|
||||
AHRIMAN_EXECUTABLE=("sudo" "-u" "$AHRIMAN_USER" "--" "ahriman")
|
||||
AHRIMAN_EXECUTABLE=("sudo" "-E" "-u" "$AHRIMAN_USER" "--" "ahriman")
|
||||
else
|
||||
AHRIMAN_EXECUTABLE=("ahriman")
|
||||
fi
|
||||
|
File diff suppressed because it is too large
Load Diff
Before Width: | Height: | Size: 809 KiB After Width: | Height: | Size: 829 KiB |
@ -76,6 +76,14 @@ ahriman.core.database.migrations.m008\_packagers module
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.core.database.migrations.m009\_local\_source module
|
||||
-----------------------------------------------------------
|
||||
|
||||
.. automodule:: ahriman.core.database.migrations.m009_local_source
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Module contents
|
||||
---------------
|
||||
|
||||
|
@ -12,17 +12,6 @@ Subpackages
|
||||
ahriman.models
|
||||
ahriman.web
|
||||
|
||||
Submodules
|
||||
----------
|
||||
|
||||
ahriman.version module
|
||||
----------------------
|
||||
|
||||
.. automodule:: ahriman.version
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Module contents
|
||||
---------------
|
||||
|
||||
|
@ -168,6 +168,7 @@ This feature is divided into to stages: check AUR for updates and run rebuild fo
|
||||
#. For each level of tree it does:
|
||||
|
||||
#. Download package data from AUR.
|
||||
#. Bump ``pkgrel`` if there is duplicate version in the local repository (see explanation below).
|
||||
#. Build every package in clean chroot.
|
||||
#. Sign packages if required.
|
||||
#. Add packages to database and sign database if required.
|
||||
@ -175,6 +176,20 @@ This feature is divided into to stages: check AUR for updates and run rebuild fo
|
||||
|
||||
After any step any package data is being removed.
|
||||
|
||||
pkgrel bump rules
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
The application is able to automatically bump package release (``pkgrel``) during build process if there is duplicate version in repository. The version will be incremented as following:
|
||||
|
||||
#. Get version of the remote package.
|
||||
#. Get version of the local package if any.
|
||||
#. If local version is not set, proceed with remote one.
|
||||
#. If local version is set and epoch or package version (``pkgver``) are different, proceed with remote version.
|
||||
#. If local version is set and remote version is newer than local one, proceed with remote.
|
||||
#. Extract ``pkgrel`` value.
|
||||
#. If it has ``major.minor`` notation (e.g. ``1.1``), then increment last part by 1, e.g. ``1.1 -> 1.2``, ``1.0.1 -> 1.0.2``.
|
||||
#. If ``pkgrel`` is a number (e.g. ``1``), then append 1 to the end of the string, e.g. ``1 -> 1.1``.
|
||||
|
||||
Core functions reference
|
||||
------------------------
|
||||
|
||||
@ -216,7 +231,7 @@ The package provides several authorization methods: disabled, based on configura
|
||||
|
||||
Disabled (default) authorization provider just allows everything for everyone and does not have any specific configuration (it uses some default configuration parameters though). It also provides generic interface for derived classes.
|
||||
|
||||
Mapping (aka configuration) provider uses hashed passwords with salt from the database in order to authenticate users. This provider also enables user permission checking (read/write) (authorization). Thus, it defines the following methods:
|
||||
Mapping (aka configuration) provider uses hashed passwords with optional salt from the database in order to authenticate users. This provider also enables user permission checking (read/write) (authorization). Thus, it defines the following methods:
|
||||
|
||||
* ``check_credentials`` - user password validation (authentication).
|
||||
* ``verify_access`` - user permission validation (authorization).
|
||||
|
@ -15,7 +15,7 @@ import sys
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from ahriman.version import __version__
|
||||
from ahriman import __version__
|
||||
|
||||
|
||||
basedir = Path(__file__).resolve().parent.parent / "src"
|
||||
|
@ -12,6 +12,15 @@ There are two variable types which have been added to default ones, they are pat
|
||||
|
||||
Path values, except for casting to ``pathlib.Path`` type, will be also expanded to absolute paths relative to the configuration path. E.g. if path is set to ``ahriman.ini.d/logging.ini`` and root configuration path is ``/etc/ahriman.ini``, the value will be expanded to ``/etc/ahriman.ini.d/logging.ini``. In order to disable path expand, use the full path, e.g. ``/etc/ahriman.ini.d/logging.ini``.
|
||||
|
||||
Configuration allows string interpolation from environment variables, e.g.:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[section]
|
||||
key = $SECRET
|
||||
|
||||
will try to read value from ``SECRET`` environment variable. In case if the required environment variable wasn't found, it will keep original value (i.e. ``$SECRET`` in the example). Dollar sign can be set as ``$$``.
|
||||
|
||||
There is also additional subcommand which will allow to validate configuration and print found errors. In order to do so, run ``service-config-validate`` subcommand, e.g.:
|
||||
|
||||
.. code-block:: shell
|
||||
@ -54,7 +63,7 @@ Base authorization settings. ``OAuth`` provider requires ``aioauth-client`` libr
|
||||
* ``max_age`` - parameter which controls both cookie expiration and token expiration inside the service, integer, optional, default is 7 days.
|
||||
* ``oauth_provider`` - OAuth2 provider class name as is in ``aioauth-client`` (e.g. ``GoogleClient``, ``GithubClient`` etc), string, required in case if ``oauth`` is used.
|
||||
* ``oauth_scopes`` - scopes list for OAuth2 provider, which will allow retrieving user email (which is used for checking user permissions), e.g. ``https://www.googleapis.com/auth/userinfo.email`` for ``GoogleClient`` or ``user:email`` for ``GithubClient``, space separated list of strings, required in case if ``oauth`` is used.
|
||||
* ``salt`` - password hash salt, string, required in case if authorization enabled (automatically generated by ``user-add`` subcommand).
|
||||
* ``salt`` - additional password hash salt, string, optional.
|
||||
|
||||
Authorized users are stored inside internal database, if any of external provides are used the password field for non-service users must be empty.
|
||||
|
||||
@ -179,7 +188,8 @@ Available options are:
|
||||
Remote push trigger
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
* ``commit_author`` - git commit author, string, optional. In case if not set, the git will generate author for you. Note, however, that in this case it will disclosure your hostname.
|
||||
* ``commit_email`` - git commit email, string, optional, default is ``ahriman@localhost``.
|
||||
* ``commit_user`` - git commit user, string, optional, default is ``ahriman``.
|
||||
* ``push_url`` - url of the remote repository to which PKGBUILDs should be pushed after build process, string, required.
|
||||
* ``push_branch`` - branch of the remote repository to which PKGBUILDs should be pushed after build process, string, optional, default is ``master``.
|
||||
|
||||
|
@ -305,7 +305,7 @@ TL;DR
|
||||
|
||||
sudo -u ahriman ahriman repo-rebuild --depends-on python
|
||||
|
||||
You can even rebuild the whole repository (which is particular useful in case if you would like to change packager) if you do not supply ``--depends-on`` option.
|
||||
You can even rebuild the whole repository (which is particular useful in case if you would like to change packager) if you do not supply ``--depends-on`` option. This action will automatically increment ``pkgrel`` value; in case if you don't want to, the ``--no-increment`` option has to be supplied.
|
||||
|
||||
However, note that you do not need to rebuild repository in case if you just changed signing option, just use ``repo-sign`` command instead.
|
||||
|
||||
@ -870,6 +870,8 @@ How to enable basic authorization
|
||||
target = configuration
|
||||
salt = somerandomstring
|
||||
|
||||
The ``salt`` parameter is optional, but recommended.
|
||||
|
||||
#.
|
||||
In order to provide access for reporting from application instances you can (recommended way) use unix sockets by configuring the following (note, that it requires ``python-requests-unixsocket`` package to be installed):
|
||||
|
||||
@ -934,7 +936,7 @@ How to enable OAuth authorization
|
||||
Configure ``oauth_provider`` and ``oauth_scopes`` in case if you would like to use different from Google provider. Scope must grant access to user email. ``web.address`` is required to make callback URL available from internet.
|
||||
|
||||
#.
|
||||
If you are not going to use unix socket, you also need to create service user (remember to set ``auth.salt`` option before):
|
||||
If you are not going to use unix socket, you also need to create service user (remember to set ``auth.salt`` option before if required):
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
|
@ -12,6 +12,7 @@ Features
|
||||
* VCS packages support.
|
||||
* Official repository support.
|
||||
* Ability to patch AUR packages and even create package from local PKGBUILDs.
|
||||
* Various rebuild options with ability to automatically bump package version.
|
||||
* Sign support with gpg (repository, package), multiple packagers support.
|
||||
* Triggers for repository updates, e.g. synchronization to remote services (rsync, s3 and github) and report generation (email, html, telegram).
|
||||
* Repository status interface with optional authorization and control options.
|
||||
|
@ -1,14 +1,14 @@
|
||||
# Maintainer: Evgeniy Alekseev
|
||||
|
||||
pkgname='ahriman'
|
||||
pkgver=2.10.1
|
||||
pkgver=2.10.2
|
||||
pkgrel=1
|
||||
pkgdesc="ArcH linux ReposItory MANager"
|
||||
arch=('any')
|
||||
url="https://github.com/arcan1s/ahriman"
|
||||
license=('GPL3')
|
||||
depends=('devtools>=1:1.0.0' 'git' 'pyalpm' 'python-cerberus' 'python-inflection' 'python-passlib' 'python-requests' 'python-srcinfo')
|
||||
makedepends=('python-build' 'python-installer' 'python-wheel')
|
||||
makedepends=('python-build' 'python-flit' 'python-installer' 'python-wheel')
|
||||
optdepends=('breezy: -bzr packages support'
|
||||
'darcs: -darcs packages support'
|
||||
'mercurial: -hg packages support'
|
||||
@ -45,8 +45,10 @@ package() {
|
||||
|
||||
python -m installer --destdir="$pkgdir" "dist/$pkgname-$pkgver-py3-none-any.whl"
|
||||
|
||||
# python-installer actually thinks that you cannot just copy files to root
|
||||
# thus we need to copy them manually
|
||||
# thanks too PEP517, which we all wanted, you need to install data files manually nowadays
|
||||
pushd package && find . -type f -exec install -Dm644 "{}" "$pkgdir/usr/{}" \; && popd
|
||||
|
||||
# keep usr/share configs as reference and copy them to /etc
|
||||
install -Dm644 "$pkgdir/usr/share/$pkgname/settings/ahriman.ini" "$pkgdir/etc/ahriman.ini"
|
||||
install -Dm644 "$pkgdir/usr/share/$pkgname/settings/ahriman.ini.d/logging.ini" "$pkgdir/etc/ahriman.ini.d/logging.ini"
|
||||
|
||||
|
@ -1,3 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec python -B -m ahriman.application.ahriman "$@"
|
@ -112,7 +112,7 @@
|
||||
|
||||
const payload = response.map(description => {
|
||||
const package_base = description.package.base;
|
||||
const web_url = description.package.remote?.web_url;
|
||||
const web_url = description.package.remote.web_url;
|
||||
return {
|
||||
id: package_base,
|
||||
base: web_url ? `<a href="${safe(web_url)}" title="${safe(package_base)}">${safe(package_base)}</a>` : safe(package_base),
|
||||
|
@ -10,9 +10,9 @@ _shtab_ahriman_help_commands_unsafe_option_strings=('-h' '--help')
|
||||
_shtab_ahriman_help_updates_option_strings=('-h' '--help' '-e' '--exit-code')
|
||||
_shtab_ahriman_help_version_option_strings=('-h' '--help')
|
||||
_shtab_ahriman_version_option_strings=('-h' '--help')
|
||||
_shtab_ahriman_package_add_option_strings=('-h' '--help' '--dependencies' '--no-dependencies' '-e' '--exit-code' '-n' '--now' '-y' '--refresh' '-s' '--source' '-u' '--username')
|
||||
_shtab_ahriman_add_option_strings=('-h' '--help' '--dependencies' '--no-dependencies' '-e' '--exit-code' '-n' '--now' '-y' '--refresh' '-s' '--source' '-u' '--username')
|
||||
_shtab_ahriman_package_update_option_strings=('-h' '--help' '--dependencies' '--no-dependencies' '-e' '--exit-code' '-n' '--now' '-y' '--refresh' '-s' '--source' '-u' '--username')
|
||||
_shtab_ahriman_package_add_option_strings=('-h' '--help' '--dependencies' '--no-dependencies' '-e' '--exit-code' '--increment' '--no-increment' '-n' '--now' '-y' '--refresh' '-s' '--source' '-u' '--username')
|
||||
_shtab_ahriman_add_option_strings=('-h' '--help' '--dependencies' '--no-dependencies' '-e' '--exit-code' '--increment' '--no-increment' '-n' '--now' '-y' '--refresh' '-s' '--source' '-u' '--username')
|
||||
_shtab_ahriman_package_update_option_strings=('-h' '--help' '--dependencies' '--no-dependencies' '-e' '--exit-code' '--increment' '--no-increment' '-n' '--now' '-y' '--refresh' '-s' '--source' '-u' '--username')
|
||||
_shtab_ahriman_package_remove_option_strings=('-h' '--help')
|
||||
_shtab_ahriman_remove_option_strings=('-h' '--help')
|
||||
_shtab_ahriman_package_status_option_strings=('-h' '--help' '--ahriman' '-e' '--exit-code' '--info' '--no-info' '-s' '--status')
|
||||
@ -31,8 +31,8 @@ _shtab_ahriman_repo_create_keyring_option_strings=('-h' '--help')
|
||||
_shtab_ahriman_repo_create_mirrorlist_option_strings=('-h' '--help')
|
||||
_shtab_ahriman_repo_daemon_option_strings=('-h' '--help' '-i' '--interval' '--aur' '--no-aur' '--dependencies' '--no-dependencies' '--local' '--no-local' '--manual' '--no-manual' '--vcs' '--no-vcs' '-y' '--refresh')
|
||||
_shtab_ahriman_daemon_option_strings=('-h' '--help' '-i' '--interval' '--aur' '--no-aur' '--dependencies' '--no-dependencies' '--local' '--no-local' '--manual' '--no-manual' '--vcs' '--no-vcs' '-y' '--refresh')
|
||||
_shtab_ahriman_repo_rebuild_option_strings=('-h' '--help' '--depends-on' '--dry-run' '--from-database' '-e' '--exit-code' '-s' '--status' '-u' '--username')
|
||||
_shtab_ahriman_rebuild_option_strings=('-h' '--help' '--depends-on' '--dry-run' '--from-database' '-e' '--exit-code' '-s' '--status' '-u' '--username')
|
||||
_shtab_ahriman_repo_rebuild_option_strings=('-h' '--help' '--depends-on' '--dry-run' '--from-database' '--increment' '--no-increment' '-e' '--exit-code' '-s' '--status' '-u' '--username')
|
||||
_shtab_ahriman_rebuild_option_strings=('-h' '--help' '--depends-on' '--dry-run' '--from-database' '--increment' '--no-increment' '-e' '--exit-code' '-s' '--status' '-u' '--username')
|
||||
_shtab_ahriman_repo_remove_unknown_option_strings=('-h' '--help' '--dry-run')
|
||||
_shtab_ahriman_remove_unknown_option_strings=('-h' '--help' '--dry-run')
|
||||
_shtab_ahriman_repo_report_option_strings=('-h' '--help')
|
||||
@ -45,8 +45,8 @@ _shtab_ahriman_repo_sync_option_strings=('-h' '--help')
|
||||
_shtab_ahriman_sync_option_strings=('-h' '--help')
|
||||
_shtab_ahriman_repo_tree_option_strings=('-h' '--help')
|
||||
_shtab_ahriman_repo_triggers_option_strings=('-h' '--help')
|
||||
_shtab_ahriman_repo_update_option_strings=('-h' '--help' '--aur' '--no-aur' '--dependencies' '--no-dependencies' '--dry-run' '-e' '--exit-code' '--local' '--no-local' '--manual' '--no-manual' '-u' '--username' '--vcs' '--no-vcs' '-y' '--refresh')
|
||||
_shtab_ahriman_update_option_strings=('-h' '--help' '--aur' '--no-aur' '--dependencies' '--no-dependencies' '--dry-run' '-e' '--exit-code' '--local' '--no-local' '--manual' '--no-manual' '-u' '--username' '--vcs' '--no-vcs' '-y' '--refresh')
|
||||
_shtab_ahriman_repo_update_option_strings=('-h' '--help' '--aur' '--no-aur' '--dependencies' '--no-dependencies' '--dry-run' '-e' '--exit-code' '--increment' '--no-increment' '--local' '--no-local' '--manual' '--no-manual' '-u' '--username' '--vcs' '--no-vcs' '-y' '--refresh')
|
||||
_shtab_ahriman_update_option_strings=('-h' '--help' '--aur' '--no-aur' '--dependencies' '--no-dependencies' '--dry-run' '-e' '--exit-code' '--increment' '--no-increment' '--local' '--no-local' '--manual' '--no-manual' '-u' '--username' '--vcs' '--no-vcs' '-y' '--refresh')
|
||||
_shtab_ahriman_service_clean_option_strings=('-h' '--help' '--cache' '--no-cache' '--chroot' '--no-chroot' '--manual' '--no-manual' '--packages' '--no-packages' '--pacman' '--no-pacman')
|
||||
_shtab_ahriman_clean_option_strings=('-h' '--help' '--cache' '--no-cache' '--chroot' '--no-chroot' '--manual' '--no-manual' '--packages' '--no-packages' '--pacman' '--no-pacman')
|
||||
_shtab_ahriman_repo_clean_option_strings=('-h' '--help' '--cache' '--no-cache' '--chroot' '--no-chroot' '--manual' '--no-manual' '--packages' '--no-packages' '--pacman' '--no-pacman')
|
||||
@ -151,6 +151,8 @@ _shtab_ahriman_package_add___dependencies_nargs=0
|
||||
_shtab_ahriman_package_add___no_dependencies_nargs=0
|
||||
_shtab_ahriman_package_add__e_nargs=0
|
||||
_shtab_ahriman_package_add___exit_code_nargs=0
|
||||
_shtab_ahriman_package_add___increment_nargs=0
|
||||
_shtab_ahriman_package_add___no_increment_nargs=0
|
||||
_shtab_ahriman_package_add__n_nargs=0
|
||||
_shtab_ahriman_package_add___now_nargs=0
|
||||
_shtab_ahriman_package_add__y_nargs=0
|
||||
@ -162,6 +164,8 @@ _shtab_ahriman_add___dependencies_nargs=0
|
||||
_shtab_ahriman_add___no_dependencies_nargs=0
|
||||
_shtab_ahriman_add__e_nargs=0
|
||||
_shtab_ahriman_add___exit_code_nargs=0
|
||||
_shtab_ahriman_add___increment_nargs=0
|
||||
_shtab_ahriman_add___no_increment_nargs=0
|
||||
_shtab_ahriman_add__n_nargs=0
|
||||
_shtab_ahriman_add___now_nargs=0
|
||||
_shtab_ahriman_add__y_nargs=0
|
||||
@ -173,6 +177,8 @@ _shtab_ahriman_package_update___dependencies_nargs=0
|
||||
_shtab_ahriman_package_update___no_dependencies_nargs=0
|
||||
_shtab_ahriman_package_update__e_nargs=0
|
||||
_shtab_ahriman_package_update___exit_code_nargs=0
|
||||
_shtab_ahriman_package_update___increment_nargs=0
|
||||
_shtab_ahriman_package_update___no_increment_nargs=0
|
||||
_shtab_ahriman_package_update__n_nargs=0
|
||||
_shtab_ahriman_package_update___now_nargs=0
|
||||
_shtab_ahriman_package_update__y_nargs=0
|
||||
@ -274,12 +280,16 @@ _shtab_ahriman_repo_rebuild__h_nargs=0
|
||||
_shtab_ahriman_repo_rebuild___help_nargs=0
|
||||
_shtab_ahriman_repo_rebuild___dry_run_nargs=0
|
||||
_shtab_ahriman_repo_rebuild___from_database_nargs=0
|
||||
_shtab_ahriman_repo_rebuild___increment_nargs=0
|
||||
_shtab_ahriman_repo_rebuild___no_increment_nargs=0
|
||||
_shtab_ahriman_repo_rebuild__e_nargs=0
|
||||
_shtab_ahriman_repo_rebuild___exit_code_nargs=0
|
||||
_shtab_ahriman_rebuild__h_nargs=0
|
||||
_shtab_ahriman_rebuild___help_nargs=0
|
||||
_shtab_ahriman_rebuild___dry_run_nargs=0
|
||||
_shtab_ahriman_rebuild___from_database_nargs=0
|
||||
_shtab_ahriman_rebuild___increment_nargs=0
|
||||
_shtab_ahriman_rebuild___no_increment_nargs=0
|
||||
_shtab_ahriman_rebuild__e_nargs=0
|
||||
_shtab_ahriman_rebuild___exit_code_nargs=0
|
||||
_shtab_ahriman_repo_remove_unknown__h_nargs=0
|
||||
@ -321,6 +331,8 @@ _shtab_ahriman_repo_update___no_dependencies_nargs=0
|
||||
_shtab_ahriman_repo_update___dry_run_nargs=0
|
||||
_shtab_ahriman_repo_update__e_nargs=0
|
||||
_shtab_ahriman_repo_update___exit_code_nargs=0
|
||||
_shtab_ahriman_repo_update___increment_nargs=0
|
||||
_shtab_ahriman_repo_update___no_increment_nargs=0
|
||||
_shtab_ahriman_repo_update___local_nargs=0
|
||||
_shtab_ahriman_repo_update___no_local_nargs=0
|
||||
_shtab_ahriman_repo_update___manual_nargs=0
|
||||
@ -339,6 +351,8 @@ _shtab_ahriman_update___no_dependencies_nargs=0
|
||||
_shtab_ahriman_update___dry_run_nargs=0
|
||||
_shtab_ahriman_update__e_nargs=0
|
||||
_shtab_ahriman_update___exit_code_nargs=0
|
||||
_shtab_ahriman_update___increment_nargs=0
|
||||
_shtab_ahriman_update___no_increment_nargs=0
|
||||
_shtab_ahriman_update___local_nargs=0
|
||||
_shtab_ahriman_update___no_local_nargs=0
|
||||
_shtab_ahriman_update___manual_nargs=0
|
||||
@ -489,7 +503,7 @@ _shtab_replace_nonword() {
|
||||
# set default values (called for the initial parser & any subparsers)
|
||||
_set_parser_defaults() {
|
||||
local subparsers_var="${prefix}_subparsers[@]"
|
||||
sub_parsers=${!subparsers_var}
|
||||
sub_parsers=${!subparsers_var-}
|
||||
|
||||
local current_option_strings_var="${prefix}_option_strings[@]"
|
||||
current_option_strings=${!current_option_strings_var}
|
||||
@ -506,13 +520,13 @@ _set_new_action() {
|
||||
current_action="${prefix}_$(_shtab_replace_nonword $1)"
|
||||
|
||||
local current_action_compgen_var=${current_action}_COMPGEN
|
||||
current_action_compgen="${!current_action_compgen_var}"
|
||||
current_action_compgen="${!current_action_compgen_var-}"
|
||||
|
||||
local current_action_choices_var="${current_action}_choices[@]"
|
||||
current_action_choices="${!current_action_choices_var}"
|
||||
current_action_choices="${!current_action_choices_var-}"
|
||||
|
||||
local current_action_nargs_var="${current_action}_nargs"
|
||||
if [ -n "${!current_action_nargs_var}" ]; then
|
||||
if [ -n "${!current_action_nargs_var-}" ]; then
|
||||
current_action_nargs="${!current_action_nargs_var}"
|
||||
else
|
||||
current_action_nargs=1
|
||||
@ -534,8 +548,8 @@ _shtab_ahriman() {
|
||||
local completing_word="${COMP_WORDS[COMP_CWORD]}"
|
||||
COMPREPLY=()
|
||||
|
||||
prefix=_shtab_ahriman
|
||||
word_index=0
|
||||
local prefix=_shtab_ahriman
|
||||
local word_index=0
|
||||
_set_parser_defaults
|
||||
word_index=1
|
||||
|
||||
@ -544,13 +558,13 @@ _shtab_ahriman() {
|
||||
while [ $word_index -ne $COMP_CWORD ]; do
|
||||
local this_word="${COMP_WORDS[$word_index]}"
|
||||
|
||||
if [[ -n $sub_parsers && " ${sub_parsers[@]} " =~ " ${this_word} " ]]; then
|
||||
if [[ -n $sub_parsers && " ${sub_parsers[@]} " == *" ${this_word} "* ]]; then
|
||||
# valid subcommand: add it to the prefix & reset the current action
|
||||
prefix="${prefix}_$(_shtab_replace_nonword $this_word)"
|
||||
_set_parser_defaults
|
||||
fi
|
||||
|
||||
if [[ " ${current_option_strings[@]} " =~ " ${this_word} " ]]; then
|
||||
if [[ " ${current_option_strings[@]} " == *" ${this_word} "* ]]; then
|
||||
# a new action should be acquired (due to recognised option string or
|
||||
# no more input expected from current action);
|
||||
# the next positional action can fill in here
|
@ -1,4 +1,4 @@
|
||||
.TH AHRIMAN "1" "2023\-07\-28" "ahriman" "Generated Python Manual"
|
||||
.TH AHRIMAN "1" "2023\-08\-07" "ahriman" "Generated Python Manual"
|
||||
.SH NAME
|
||||
ahriman
|
||||
.SH SYNOPSIS
|
||||
@ -224,7 +224,7 @@ usage: ahriman help\-version [\-h]
|
||||
print application and its dependencies versions
|
||||
|
||||
.SH COMMAND \fI\,'ahriman package\-add'\/\fR
|
||||
usage: ahriman package\-add [\-h] [\-\-dependencies | \-\-no\-dependencies] [\-e] [\-n] [\-y]
|
||||
usage: ahriman package\-add [\-h] [\-\-dependencies | \-\-no\-dependencies] [\-e] [\-\-increment | \-\-no\-increment] [\-n] [\-y]
|
||||
[\-s {auto,archive,aur,directory,local,remote,repository}] [\-u USERNAME]
|
||||
package [package ...]
|
||||
|
||||
@ -243,6 +243,10 @@ process missing package dependencies
|
||||
\fB\-e\fR, \fB\-\-exit\-code\fR
|
||||
return non\-zero exit status if result is empty
|
||||
|
||||
.TP
|
||||
\fB\-\-increment\fR, \fB\-\-no\-increment\fR
|
||||
increment package release (pkgrel) version on duplicate
|
||||
|
||||
.TP
|
||||
\fB\-n\fR, \fB\-\-now\fR
|
||||
run update function after
|
||||
@ -459,8 +463,8 @@ fetch actual version of VCS packages
|
||||
download fresh package databases from the mirror before actions, \-yy to force refresh even if up to date
|
||||
|
||||
.SH COMMAND \fI\,'ahriman repo\-rebuild'\/\fR
|
||||
usage: ahriman repo\-rebuild [\-h] [\-\-depends\-on DEPENDS_ON] [\-\-dry\-run] [\-\-from\-database] [\-e]
|
||||
[\-s {unknown,pending,building,failed,success}] [\-u USERNAME]
|
||||
usage: ahriman repo\-rebuild [\-h] [\-\-depends\-on DEPENDS_ON] [\-\-dry\-run] [\-\-from\-database] [\-\-increment | \-\-no\-increment]
|
||||
[\-e] [\-s {unknown,pending,building,failed,success}] [\-u USERNAME]
|
||||
|
||||
force rebuild whole repository
|
||||
|
||||
@ -479,6 +483,10 @@ read packages from database instead of filesystem. This feature in particular is
|
||||
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.
|
||||
|
||||
.TP
|
||||
\fB\-\-increment\fR, \fB\-\-no\-increment\fR
|
||||
increment package release (pkgrel) on duplicate
|
||||
|
||||
.TP
|
||||
\fB\-e\fR, \fB\-\-exit\-code\fR
|
||||
return non\-zero exit status if result is empty
|
||||
@ -560,7 +568,8 @@ instead of running all triggers as set by configuration, just process specified
|
||||
|
||||
.SH COMMAND \fI\,'ahriman repo\-update'\/\fR
|
||||
usage: ahriman repo\-update [\-h] [\-\-aur | \-\-no\-aur] [\-\-dependencies | \-\-no\-dependencies] [\-\-dry\-run] [\-e]
|
||||
[\-\-local | \-\-no\-local] [\-\-manual | \-\-no\-manual] [\-u USERNAME] [\-\-vcs | \-\-no\-vcs] [\-y]
|
||||
[\-\-increment | \-\-no\-increment] [\-\-local | \-\-no\-local] [\-\-manual | \-\-no\-manual] [\-u USERNAME]
|
||||
[\-\-vcs | \-\-no\-vcs] [\-y]
|
||||
[package ...]
|
||||
|
||||
check for packages updates and run build process if requested
|
||||
@ -586,6 +595,10 @@ just perform check for updates, same as check command
|
||||
\fB\-e\fR, \fB\-\-exit\-code\fR
|
||||
return non\-zero exit status if result is empty
|
||||
|
||||
.TP
|
||||
\fB\-\-increment\fR, \fB\-\-no\-increment\fR
|
||||
increment package release (pkgrel) on duplicate
|
||||
|
||||
.TP
|
||||
\fB\-\-local\fR, \fB\-\-no\-local\fR
|
||||
enable or disable checking of local packages for updates
|
@ -77,87 +77,88 @@ _shtab_ahriman_commands() {
|
||||
|
||||
_shtab_ahriman_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"*"{-a,--architecture}"[target architectures. For several subcommands it can be used multiple times]:architecture:"
|
||||
{-c,--configuration}"[configuration path]:configuration:"
|
||||
"--force[force run, remove file lock]"
|
||||
{-l,--lock}"[lock file]:lock:"
|
||||
"--log-handler[explicit log handler specification. If none set, the handler will be guessed from environment]:log_handler:(console syslog journald)"
|
||||
{--report,--no-report}"[force enable or disable reporting to web service]:report:"
|
||||
{-q,--quiet}"[force disable any logging]"
|
||||
"--unsafe[allow to run ahriman as non-ahriman user. Some actions might be unavailable]"
|
||||
"*"{-a,--architecture}"[target architectures. For several subcommands it can be used multiple times (default\: None)]:architecture:"
|
||||
{-c,--configuration}"[configuration path (default\: \/etc\/ahriman.ini)]:configuration:"
|
||||
"--force[force run, remove file lock (default\: False)]"
|
||||
{-l,--lock}"[lock file (default\: \/tmp\/ahriman.lock)]:lock:"
|
||||
"--log-handler[explicit log handler specification. If none set, the handler will be guessed from environment (default\: None)]:log_handler:(console syslog journald)"
|
||||
{--report,--no-report}"[force enable or disable reporting to web service (default\: True)]:report:"
|
||||
{-q,--quiet}"[force disable any logging (default\: False)]"
|
||||
"--unsafe[allow to run ahriman as non-ahriman user. Some actions might be unavailable (default\: False)]"
|
||||
"(- : *)"{-V,--version}"[show program\'s version number and exit]"
|
||||
)
|
||||
|
||||
_shtab_ahriman_add_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--dependencies,--no-dependencies}"[process missing package dependencies]:dependencies:"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty]"
|
||||
{-n,--now}"[run update function after]"
|
||||
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date]"
|
||||
{-s,--source}"[explicitly specify the package source for this command]:source:(auto archive aur directory local remote repository)"
|
||||
{-u,--username}"[build as user]:username:"
|
||||
{--dependencies,--no-dependencies}"[process missing package dependencies (default\: True)]:dependencies:"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{--increment,--no-increment}"[increment package release (pkgrel) version on duplicate (default\: True)]:increment:"
|
||||
{-n,--now}"[run update function after (default\: False)]"
|
||||
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date (default\: False)]"
|
||||
{-s,--source}"[explicitly specify the package source for this command (default\: PackageSource.Auto)]:source:(auto archive aur directory local remote repository)"
|
||||
{-u,--username}"[build as user (default\: None)]:username:"
|
||||
"(*):package source (base name, path to local files, remote URL):"
|
||||
)
|
||||
|
||||
_shtab_ahriman_aur_search_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty]"
|
||||
{--info,--no-info}"[show additional package information]:info:"
|
||||
"--sort-by[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]:sort_by:(description first_submitted id last_modified maintainer name num_votes out_of_date package_base package_base_id popularity repository submitter url url_path version)"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{--info,--no-info}"[show additional package information (default\: False)]:info:"
|
||||
"--sort-by[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)]:sort_by:(description first_submitted id last_modified maintainer name num_votes out_of_date package_base package_base_id popularity repository submitter url url_path version)"
|
||||
"(*):search terms, can be specified multiple times, the result will match all terms:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_check_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty]"
|
||||
{--vcs,--no-vcs}"[fetch actual version of VCS packages]:vcs:"
|
||||
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date]"
|
||||
"(*)::filter check by package base:"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{--vcs,--no-vcs}"[fetch actual version of VCS packages (default\: True)]:vcs:"
|
||||
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date (default\: False)]"
|
||||
"(*)::filter check by package base (default\: None):"
|
||||
)
|
||||
|
||||
_shtab_ahriman_clean_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--cache,--no-cache}"[clear directory with package caches]:cache:"
|
||||
{--chroot,--no-chroot}"[clear build chroot]:chroot:"
|
||||
{--manual,--no-manual}"[clear manually added packages queue]:manual:"
|
||||
{--packages,--no-packages}"[clear directory with built packages]:packages:"
|
||||
{--pacman,--no-pacman}"[clear directory with pacman local database cache]:pacman:"
|
||||
{--cache,--no-cache}"[clear directory with package caches (default\: False)]:cache:"
|
||||
{--chroot,--no-chroot}"[clear build chroot (default\: False)]:chroot:"
|
||||
{--manual,--no-manual}"[clear manually added packages queue (default\: False)]:manual:"
|
||||
{--packages,--no-packages}"[clear directory with built packages (default\: False)]:packages:"
|
||||
{--pacman,--no-pacman}"[clear directory with pacman local database cache (default\: False)]:pacman:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_config_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--secure,--no-secure}"[hide passwords and secrets from output]:secure:"
|
||||
{--secure,--no-secure}"[hide passwords and secrets from output (default\: True)]:secure:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_config_validate_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-e,--exit-code}"[return non-zero exit status if configuration is invalid]"
|
||||
{-e,--exit-code}"[return non-zero exit status if configuration is invalid (default\: False)]"
|
||||
)
|
||||
|
||||
_shtab_ahriman_daemon_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-i,--interval}"[interval between runs in seconds]:interval:"
|
||||
{--aur,--no-aur}"[enable or disable checking for AUR updates]:aur:"
|
||||
{--dependencies,--no-dependencies}"[process missing package dependencies]:dependencies:"
|
||||
{--local,--no-local}"[enable or disable checking of local packages for updates]:local:"
|
||||
{--manual,--no-manual}"[include or exclude manual updates]:manual:"
|
||||
{--vcs,--no-vcs}"[fetch actual version of VCS packages]:vcs:"
|
||||
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date]"
|
||||
{-i,--interval}"[interval between runs in seconds (default\: 43200)]:interval:"
|
||||
{--aur,--no-aur}"[enable or disable checking for AUR updates (default\: True)]:aur:"
|
||||
{--dependencies,--no-dependencies}"[process missing package dependencies (default\: True)]:dependencies:"
|
||||
{--local,--no-local}"[enable or disable checking of local packages for updates (default\: True)]:local:"
|
||||
{--manual,--no-manual}"[include or exclude manual updates (default\: True)]:manual:"
|
||||
{--vcs,--no-vcs}"[fetch actual version of VCS packages (default\: True)]:vcs:"
|
||||
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date (default\: False)]"
|
||||
)
|
||||
|
||||
_shtab_ahriman_help_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
":show help message for specific command:"
|
||||
":show help message for specific command (default\: None):"
|
||||
)
|
||||
|
||||
_shtab_ahriman_help_commands_unsafe_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"(*)::instead of showing commands, just test command line for unsafe subcommand and return 0 in case if command is safe and 1 otherwise:"
|
||||
"(*)::instead of showing commands, just test command line for unsafe subcommand and return 0 in case if command is safe and 1 otherwise (default\: None):"
|
||||
)
|
||||
|
||||
_shtab_ahriman_help_updates_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-e,--exit-code}"[return non-zero exit code if updates available]"
|
||||
{-e,--exit-code}"[return non-zero exit code if updates available (default\: False)]"
|
||||
)
|
||||
|
||||
_shtab_ahriman_help_version_options=(
|
||||
@ -166,35 +167,36 @@ _shtab_ahriman_help_version_options=(
|
||||
|
||||
_shtab_ahriman_init_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"--build-as-user[force makepkg user to the specific one]:build_as_user:"
|
||||
"--build-command[build command prefix]:build_command:"
|
||||
"--from-configuration[path to default devtools pacman configuration]:from_configuration:"
|
||||
{--generate-salt,--no-generate-salt}"[generate salt for user passwords]:generate_salt:"
|
||||
{--makeflags-jobs,--no-makeflags-jobs}"[append MAKEFLAGS variable with parallelism set to number of cores]:makeflags_jobs:"
|
||||
"--mirror[use the specified explicitly mirror instead of including mirrorlist]:mirror:"
|
||||
{--multilib,--no-multilib}"[add or do not multilib repository]:multilib:"
|
||||
"--packager[packager name and email]:packager:"
|
||||
"--repository[repository name]:repository:"
|
||||
"--sign-key[sign key id]:sign_key:"
|
||||
"*--sign-target[sign options]:sign_target:(disabled packages repository)"
|
||||
"--web-port[port of the web service]:web_port:"
|
||||
"--web-unix-socket[path to unix socket used for interprocess communications]:web_unix_socket:"
|
||||
"--build-as-user[force makepkg user to the specific one (default\: None)]:build_as_user:"
|
||||
"--build-command[build command prefix (default\: ahriman)]:build_command:"
|
||||
"--from-configuration[path to default devtools pacman configuration (default\: \/usr\/share\/devtools\/pacman.conf.d\/extra.conf)]:from_configuration:"
|
||||
{--generate-salt,--no-generate-salt}"[generate salt for user passwords (default\: False)]:generate_salt:"
|
||||
{--makeflags-jobs,--no-makeflags-jobs}"[append MAKEFLAGS variable with parallelism set to number of cores (default\: True)]:makeflags_jobs:"
|
||||
"--mirror[use the specified explicitly mirror instead of including mirrorlist (default\: None)]:mirror:"
|
||||
{--multilib,--no-multilib}"[add or do not multilib repository (default\: True)]:multilib:"
|
||||
"--packager[packager name and email (default\: None)]:packager:"
|
||||
"--repository[repository name (default\: None)]:repository:"
|
||||
"--sign-key[sign key id (default\: None)]:sign_key:"
|
||||
"*--sign-target[sign options (default\: None)]:sign_target:(disabled packages repository)"
|
||||
"--web-port[port of the web service (default\: None)]:web_port:"
|
||||
"--web-unix-socket[path to unix socket used for interprocess communications (default\: None)]:web_unix_socket:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_key_import_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"--key-server[key server for key import]:key_server:"
|
||||
"--key-server[key server for key import (default\: keyserver.ubuntu.com)]:key_server:"
|
||||
":PGP key to import from public server:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_package_add_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--dependencies,--no-dependencies}"[process missing package dependencies]:dependencies:"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty]"
|
||||
{-n,--now}"[run update function after]"
|
||||
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date]"
|
||||
{-s,--source}"[explicitly specify the package source for this command]:source:(auto archive aur directory local remote repository)"
|
||||
{-u,--username}"[build as user]:username:"
|
||||
{--dependencies,--no-dependencies}"[process missing package dependencies (default\: True)]:dependencies:"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{--increment,--no-increment}"[increment package release (pkgrel) version on duplicate (default\: True)]:increment:"
|
||||
{-n,--now}"[run update function after (default\: False)]"
|
||||
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date (default\: False)]"
|
||||
{-s,--source}"[explicitly specify the package source for this command (default\: PackageSource.Auto)]:source:(auto archive aur directory local remote repository)"
|
||||
{-u,--username}"[build as user (default\: None)]:username:"
|
||||
"(*):package source (base name, path to local files, remote URL):"
|
||||
)
|
||||
|
||||
@ -205,11 +207,11 @@ _shtab_ahriman_package_remove_options=(
|
||||
|
||||
_shtab_ahriman_package_status_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"--ahriman[get service status itself]"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty]"
|
||||
{--info,--no-info}"[show additional package information]:info:"
|
||||
{-s,--status}"[filter packages by status]:status:(unknown pending building failed success)"
|
||||
"(*)::filter status by package base:"
|
||||
"--ahriman[get service status itself (default\: False)]"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{--info,--no-info}"[show additional package information (default\: False)]:info:"
|
||||
{-s,--status}"[filter packages by status (default\: None)]:status:(unknown pending building failed success)"
|
||||
"(*)::filter status by package base (default\: None):"
|
||||
)
|
||||
|
||||
_shtab_ahriman_package_status_remove_options=(
|
||||
@ -219,18 +221,19 @@ _shtab_ahriman_package_status_remove_options=(
|
||||
|
||||
_shtab_ahriman_package_status_update_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-s,--status}"[new package build status]:status:(unknown pending building failed success)"
|
||||
"(*)::set status for specified packages. If no packages supplied, service status will be updated:"
|
||||
{-s,--status}"[new package build status (default\: BuildStatusEnum.Success)]:status:(unknown pending building failed success)"
|
||||
"(*)::set status for specified packages. If no packages supplied, service status will be updated (default\: None):"
|
||||
)
|
||||
|
||||
_shtab_ahriman_package_update_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--dependencies,--no-dependencies}"[process missing package dependencies]:dependencies:"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty]"
|
||||
{-n,--now}"[run update function after]"
|
||||
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date]"
|
||||
{-s,--source}"[explicitly specify the package source for this command]:source:(auto archive aur directory local remote repository)"
|
||||
{-u,--username}"[build as user]:username:"
|
||||
{--dependencies,--no-dependencies}"[process missing package dependencies (default\: True)]:dependencies:"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{--increment,--no-increment}"[increment package release (pkgrel) version on duplicate (default\: True)]:increment:"
|
||||
{-n,--now}"[run update function after (default\: False)]"
|
||||
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date (default\: False)]"
|
||||
{-s,--source}"[explicitly specify the package source for this command (default\: PackageSource.Auto)]:source:(auto archive aur directory local remote repository)"
|
||||
{-u,--username}"[build as user (default\: None)]:username:"
|
||||
"(*):package source (base name, path to local files, remote URL):"
|
||||
)
|
||||
|
||||
@ -238,36 +241,37 @@ _shtab_ahriman_patch_add_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
":package base:"
|
||||
":PKGBUILD variable or function name. If variable is a function, it must end with ():"
|
||||
":path to file which contains function or variable value. If not set, the value will be read from stdin:"
|
||||
":path to file which contains function or variable value. If not set, the value will be read from stdin (default\: None):"
|
||||
)
|
||||
|
||||
_shtab_ahriman_patch_list_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty]"
|
||||
"*"{-v,--variable}"[if set, show only patches for specified PKGBUILD variables]:variable:"
|
||||
":package base:"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
"*"{-v,--variable}"[if set, show only patches for specified PKGBUILD variables (default\: None)]:variable:"
|
||||
":package base (default\: None):"
|
||||
)
|
||||
|
||||
_shtab_ahriman_patch_remove_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"*"{-v,--variable}"[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]:variable:"
|
||||
"*"{-v,--variable}"[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 (default\: None)]:variable:"
|
||||
":package base:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_patch_set_add_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"*"{-t,--track}"[files which has to be tracked]:track:"
|
||||
"*"{-t,--track}"[files which has to be tracked (default\: \[\'\*.diff\', \'\*.patch\'\])]:track:"
|
||||
":path to directory with changed files for patch addition\/update:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_rebuild_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"*--depends-on[only rebuild packages that depend on specified packages]:depends_on:"
|
||||
"--dry-run[just perform check for packages without rebuild process itself]"
|
||||
"--from-database[read packages from database instead of filesystem. This feature in particular is required in case if you would like to restore repository from another repository instance. Note, however, that in order to restore packages you need to have original ahriman instance run with web service and have run repo-update at least once.]"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty]"
|
||||
{-s,--status}"[filter packages by status. Requires --from-database to be set]:status:(unknown pending building failed success)"
|
||||
{-u,--username}"[build as user]:username:"
|
||||
"*--depends-on[only rebuild packages that depend on specified packages (default\: None)]:depends_on:"
|
||||
"--dry-run[just perform check for packages without rebuild process itself (default\: False)]"
|
||||
"--from-database[read packages from database instead of filesystem. This feature in particular is required in case if you would like to restore repository from another repository instance. Note, however, that in order to restore packages you need to have original ahriman instance run with web service and have run repo-update at least once. (default\: False)]"
|
||||
{--increment,--no-increment}"[increment package release (pkgrel) on duplicate (default\: True)]:increment:"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{-s,--status}"[filter packages by status. Requires --from-database to be set (default\: None)]:status:(unknown pending building failed success)"
|
||||
{-u,--username}"[build as user (default\: None)]:username:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_remove_options=(
|
||||
@ -277,7 +281,7 @@ _shtab_ahriman_remove_options=(
|
||||
|
||||
_shtab_ahriman_remove_unknown_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"--dry-run[just perform check for packages without removal]"
|
||||
"--dry-run[just perform check for packages without removal (default\: False)]"
|
||||
)
|
||||
|
||||
_shtab_ahriman_repo_backup_options=(
|
||||
@ -287,29 +291,29 @@ _shtab_ahriman_repo_backup_options=(
|
||||
|
||||
_shtab_ahriman_repo_check_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty]"
|
||||
{--vcs,--no-vcs}"[fetch actual version of VCS packages]:vcs:"
|
||||
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date]"
|
||||
"(*)::filter check by package base:"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{--vcs,--no-vcs}"[fetch actual version of VCS packages (default\: True)]:vcs:"
|
||||
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date (default\: False)]"
|
||||
"(*)::filter check by package base (default\: None):"
|
||||
)
|
||||
|
||||
_shtab_ahriman_repo_clean_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--cache,--no-cache}"[clear directory with package caches]:cache:"
|
||||
{--chroot,--no-chroot}"[clear build chroot]:chroot:"
|
||||
{--manual,--no-manual}"[clear manually added packages queue]:manual:"
|
||||
{--packages,--no-packages}"[clear directory with built packages]:packages:"
|
||||
{--pacman,--no-pacman}"[clear directory with pacman local database cache]:pacman:"
|
||||
{--cache,--no-cache}"[clear directory with package caches (default\: False)]:cache:"
|
||||
{--chroot,--no-chroot}"[clear build chroot (default\: False)]:chroot:"
|
||||
{--manual,--no-manual}"[clear manually added packages queue (default\: False)]:manual:"
|
||||
{--packages,--no-packages}"[clear directory with built packages (default\: False)]:packages:"
|
||||
{--pacman,--no-pacman}"[clear directory with pacman local database cache (default\: False)]:pacman:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_repo_config_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--secure,--no-secure}"[hide passwords and secrets from output]:secure:"
|
||||
{--secure,--no-secure}"[hide passwords and secrets from output (default\: True)]:secure:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_repo_config_validate_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-e,--exit-code}"[return non-zero exit status if configuration is invalid]"
|
||||
{-e,--exit-code}"[return non-zero exit status if configuration is invalid (default\: False)]"
|
||||
)
|
||||
|
||||
_shtab_ahriman_repo_create_keyring_options=(
|
||||
@ -322,45 +326,46 @@ _shtab_ahriman_repo_create_mirrorlist_options=(
|
||||
|
||||
_shtab_ahriman_repo_daemon_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-i,--interval}"[interval between runs in seconds]:interval:"
|
||||
{--aur,--no-aur}"[enable or disable checking for AUR updates]:aur:"
|
||||
{--dependencies,--no-dependencies}"[process missing package dependencies]:dependencies:"
|
||||
{--local,--no-local}"[enable or disable checking of local packages for updates]:local:"
|
||||
{--manual,--no-manual}"[include or exclude manual updates]:manual:"
|
||||
{--vcs,--no-vcs}"[fetch actual version of VCS packages]:vcs:"
|
||||
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date]"
|
||||
{-i,--interval}"[interval between runs in seconds (default\: 43200)]:interval:"
|
||||
{--aur,--no-aur}"[enable or disable checking for AUR updates (default\: True)]:aur:"
|
||||
{--dependencies,--no-dependencies}"[process missing package dependencies (default\: True)]:dependencies:"
|
||||
{--local,--no-local}"[enable or disable checking of local packages for updates (default\: True)]:local:"
|
||||
{--manual,--no-manual}"[include or exclude manual updates (default\: True)]:manual:"
|
||||
{--vcs,--no-vcs}"[fetch actual version of VCS packages (default\: True)]:vcs:"
|
||||
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date (default\: False)]"
|
||||
)
|
||||
|
||||
_shtab_ahriman_repo_init_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"--build-as-user[force makepkg user to the specific one]:build_as_user:"
|
||||
"--build-command[build command prefix]:build_command:"
|
||||
"--from-configuration[path to default devtools pacman configuration]:from_configuration:"
|
||||
{--generate-salt,--no-generate-salt}"[generate salt for user passwords]:generate_salt:"
|
||||
{--makeflags-jobs,--no-makeflags-jobs}"[append MAKEFLAGS variable with parallelism set to number of cores]:makeflags_jobs:"
|
||||
"--mirror[use the specified explicitly mirror instead of including mirrorlist]:mirror:"
|
||||
{--multilib,--no-multilib}"[add or do not multilib repository]:multilib:"
|
||||
"--packager[packager name and email]:packager:"
|
||||
"--repository[repository name]:repository:"
|
||||
"--sign-key[sign key id]:sign_key:"
|
||||
"*--sign-target[sign options]:sign_target:(disabled packages repository)"
|
||||
"--web-port[port of the web service]:web_port:"
|
||||
"--web-unix-socket[path to unix socket used for interprocess communications]:web_unix_socket:"
|
||||
"--build-as-user[force makepkg user to the specific one (default\: None)]:build_as_user:"
|
||||
"--build-command[build command prefix (default\: ahriman)]:build_command:"
|
||||
"--from-configuration[path to default devtools pacman configuration (default\: \/usr\/share\/devtools\/pacman.conf.d\/extra.conf)]:from_configuration:"
|
||||
{--generate-salt,--no-generate-salt}"[generate salt for user passwords (default\: False)]:generate_salt:"
|
||||
{--makeflags-jobs,--no-makeflags-jobs}"[append MAKEFLAGS variable with parallelism set to number of cores (default\: True)]:makeflags_jobs:"
|
||||
"--mirror[use the specified explicitly mirror instead of including mirrorlist (default\: None)]:mirror:"
|
||||
{--multilib,--no-multilib}"[add or do not multilib repository (default\: True)]:multilib:"
|
||||
"--packager[packager name and email (default\: None)]:packager:"
|
||||
"--repository[repository name (default\: None)]:repository:"
|
||||
"--sign-key[sign key id (default\: None)]:sign_key:"
|
||||
"*--sign-target[sign options (default\: None)]:sign_target:(disabled packages repository)"
|
||||
"--web-port[port of the web service (default\: None)]:web_port:"
|
||||
"--web-unix-socket[path to unix socket used for interprocess communications (default\: None)]:web_unix_socket:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_repo_rebuild_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"*--depends-on[only rebuild packages that depend on specified packages]:depends_on:"
|
||||
"--dry-run[just perform check for packages without rebuild process itself]"
|
||||
"--from-database[read packages from database instead of filesystem. This feature in particular is required in case if you would like to restore repository from another repository instance. Note, however, that in order to restore packages you need to have original ahriman instance run with web service and have run repo-update at least once.]"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty]"
|
||||
{-s,--status}"[filter packages by status. Requires --from-database to be set]:status:(unknown pending building failed success)"
|
||||
{-u,--username}"[build as user]:username:"
|
||||
"*--depends-on[only rebuild packages that depend on specified packages (default\: None)]:depends_on:"
|
||||
"--dry-run[just perform check for packages without rebuild process itself (default\: False)]"
|
||||
"--from-database[read packages from database instead of filesystem. This feature in particular is required in case if you would like to restore repository from another repository instance. Note, however, that in order to restore packages you need to have original ahriman instance run with web service and have run repo-update at least once. (default\: False)]"
|
||||
{--increment,--no-increment}"[increment package release (pkgrel) on duplicate (default\: True)]:increment:"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{-s,--status}"[filter packages by status. Requires --from-database to be set (default\: None)]:status:(unknown pending building failed success)"
|
||||
{-u,--username}"[build as user (default\: None)]:username:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_repo_remove_unknown_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"--dry-run[just perform check for packages without removal]"
|
||||
"--dry-run[just perform check for packages without removal (default\: False)]"
|
||||
)
|
||||
|
||||
_shtab_ahriman_repo_report_options=(
|
||||
@ -369,35 +374,35 @@ _shtab_ahriman_repo_report_options=(
|
||||
|
||||
_shtab_ahriman_repo_restore_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-o,--output}"[root path of the extracted files]:output:"
|
||||
{-o,--output}"[root path of the extracted files (default\: \/)]:output:"
|
||||
":path of the input archive:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_repo_setup_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"--build-as-user[force makepkg user to the specific one]:build_as_user:"
|
||||
"--build-command[build command prefix]:build_command:"
|
||||
"--from-configuration[path to default devtools pacman configuration]:from_configuration:"
|
||||
{--generate-salt,--no-generate-salt}"[generate salt for user passwords]:generate_salt:"
|
||||
{--makeflags-jobs,--no-makeflags-jobs}"[append MAKEFLAGS variable with parallelism set to number of cores]:makeflags_jobs:"
|
||||
"--mirror[use the specified explicitly mirror instead of including mirrorlist]:mirror:"
|
||||
{--multilib,--no-multilib}"[add or do not multilib repository]:multilib:"
|
||||
"--packager[packager name and email]:packager:"
|
||||
"--repository[repository name]:repository:"
|
||||
"--sign-key[sign key id]:sign_key:"
|
||||
"*--sign-target[sign options]:sign_target:(disabled packages repository)"
|
||||
"--web-port[port of the web service]:web_port:"
|
||||
"--web-unix-socket[path to unix socket used for interprocess communications]:web_unix_socket:"
|
||||
"--build-as-user[force makepkg user to the specific one (default\: None)]:build_as_user:"
|
||||
"--build-command[build command prefix (default\: ahriman)]:build_command:"
|
||||
"--from-configuration[path to default devtools pacman configuration (default\: \/usr\/share\/devtools\/pacman.conf.d\/extra.conf)]:from_configuration:"
|
||||
{--generate-salt,--no-generate-salt}"[generate salt for user passwords (default\: False)]:generate_salt:"
|
||||
{--makeflags-jobs,--no-makeflags-jobs}"[append MAKEFLAGS variable with parallelism set to number of cores (default\: True)]:makeflags_jobs:"
|
||||
"--mirror[use the specified explicitly mirror instead of including mirrorlist (default\: None)]:mirror:"
|
||||
{--multilib,--no-multilib}"[add or do not multilib repository (default\: True)]:multilib:"
|
||||
"--packager[packager name and email (default\: None)]:packager:"
|
||||
"--repository[repository name (default\: None)]:repository:"
|
||||
"--sign-key[sign key id (default\: None)]:sign_key:"
|
||||
"*--sign-target[sign options (default\: None)]:sign_target:(disabled packages repository)"
|
||||
"--web-port[port of the web service (default\: None)]:web_port:"
|
||||
"--web-unix-socket[path to unix socket used for interprocess communications (default\: None)]:web_unix_socket:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_repo_sign_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"(*)::sign only specified packages:"
|
||||
"(*)::sign only specified packages (default\: None):"
|
||||
)
|
||||
|
||||
_shtab_ahriman_repo_status_update_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-s,--status}"[new status]:status:(unknown pending building failed success)"
|
||||
{-s,--status}"[new status (default\: BuildStatusEnum.Success)]:status:(unknown pending building failed success)"
|
||||
)
|
||||
|
||||
_shtab_ahriman_repo_sync_options=(
|
||||
@ -410,21 +415,22 @@ _shtab_ahriman_repo_tree_options=(
|
||||
|
||||
_shtab_ahriman_repo_triggers_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"(*)::instead of running all triggers as set by configuration, just process specified ones in order of mention:"
|
||||
"(*)::instead of running all triggers as set by configuration, just process specified ones in order of mention (default\: None):"
|
||||
)
|
||||
|
||||
_shtab_ahriman_repo_update_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--aur,--no-aur}"[enable or disable checking for AUR updates]:aur:"
|
||||
{--dependencies,--no-dependencies}"[process missing package dependencies]:dependencies:"
|
||||
"--dry-run[just perform check for updates, same as check command]"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty]"
|
||||
{--local,--no-local}"[enable or disable checking of local packages for updates]:local:"
|
||||
{--manual,--no-manual}"[include or exclude manual updates]:manual:"
|
||||
{-u,--username}"[build as user]:username:"
|
||||
{--vcs,--no-vcs}"[fetch actual version of VCS packages]:vcs:"
|
||||
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date]"
|
||||
"(*)::filter check by package base:"
|
||||
{--aur,--no-aur}"[enable or disable checking for AUR updates (default\: True)]:aur:"
|
||||
{--dependencies,--no-dependencies}"[process missing package dependencies (default\: True)]:dependencies:"
|
||||
"--dry-run[just perform check for updates, same as check command (default\: False)]"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{--increment,--no-increment}"[increment package release (pkgrel) on duplicate (default\: True)]:increment:"
|
||||
{--local,--no-local}"[enable or disable checking of local packages for updates (default\: True)]:local:"
|
||||
{--manual,--no-manual}"[include or exclude manual updates (default\: True)]:manual:"
|
||||
{-u,--username}"[build as user (default\: None)]:username:"
|
||||
{--vcs,--no-vcs}"[fetch actual version of VCS packages (default\: True)]:vcs:"
|
||||
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date (default\: False)]"
|
||||
"(*)::filter check by package base (default\: None):"
|
||||
)
|
||||
|
||||
_shtab_ahriman_report_options=(
|
||||
@ -433,99 +439,99 @@ _shtab_ahriman_report_options=(
|
||||
|
||||
_shtab_ahriman_search_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty]"
|
||||
{--info,--no-info}"[show additional package information]:info:"
|
||||
"--sort-by[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]:sort_by:(description first_submitted id last_modified maintainer name num_votes out_of_date package_base package_base_id popularity repository submitter url url_path version)"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{--info,--no-info}"[show additional package information (default\: False)]:info:"
|
||||
"--sort-by[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)]:sort_by:(description first_submitted id last_modified maintainer name num_votes out_of_date package_base package_base_id popularity repository submitter url url_path version)"
|
||||
"(*):search terms, can be specified multiple times, the result will match all terms:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_service_clean_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--cache,--no-cache}"[clear directory with package caches]:cache:"
|
||||
{--chroot,--no-chroot}"[clear build chroot]:chroot:"
|
||||
{--manual,--no-manual}"[clear manually added packages queue]:manual:"
|
||||
{--packages,--no-packages}"[clear directory with built packages]:packages:"
|
||||
{--pacman,--no-pacman}"[clear directory with pacman local database cache]:pacman:"
|
||||
{--cache,--no-cache}"[clear directory with package caches (default\: False)]:cache:"
|
||||
{--chroot,--no-chroot}"[clear build chroot (default\: False)]:chroot:"
|
||||
{--manual,--no-manual}"[clear manually added packages queue (default\: False)]:manual:"
|
||||
{--packages,--no-packages}"[clear directory with built packages (default\: False)]:packages:"
|
||||
{--pacman,--no-pacman}"[clear directory with pacman local database cache (default\: False)]:pacman:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_service_config_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--secure,--no-secure}"[hide passwords and secrets from output]:secure:"
|
||||
{--secure,--no-secure}"[hide passwords and secrets from output (default\: True)]:secure:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_service_config_validate_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-e,--exit-code}"[return non-zero exit status if configuration is invalid]"
|
||||
{-e,--exit-code}"[return non-zero exit status if configuration is invalid (default\: False)]"
|
||||
)
|
||||
|
||||
_shtab_ahriman_service_key_import_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"--key-server[key server for key import]:key_server:"
|
||||
"--key-server[key server for key import (default\: keyserver.ubuntu.com)]:key_server:"
|
||||
":PGP key to import from public server:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_service_setup_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"--build-as-user[force makepkg user to the specific one]:build_as_user:"
|
||||
"--build-command[build command prefix]:build_command:"
|
||||
"--from-configuration[path to default devtools pacman configuration]:from_configuration:"
|
||||
{--generate-salt,--no-generate-salt}"[generate salt for user passwords]:generate_salt:"
|
||||
{--makeflags-jobs,--no-makeflags-jobs}"[append MAKEFLAGS variable with parallelism set to number of cores]:makeflags_jobs:"
|
||||
"--mirror[use the specified explicitly mirror instead of including mirrorlist]:mirror:"
|
||||
{--multilib,--no-multilib}"[add or do not multilib repository]:multilib:"
|
||||
"--packager[packager name and email]:packager:"
|
||||
"--repository[repository name]:repository:"
|
||||
"--sign-key[sign key id]:sign_key:"
|
||||
"*--sign-target[sign options]:sign_target:(disabled packages repository)"
|
||||
"--web-port[port of the web service]:web_port:"
|
||||
"--web-unix-socket[path to unix socket used for interprocess communications]:web_unix_socket:"
|
||||
"--build-as-user[force makepkg user to the specific one (default\: None)]:build_as_user:"
|
||||
"--build-command[build command prefix (default\: ahriman)]:build_command:"
|
||||
"--from-configuration[path to default devtools pacman configuration (default\: \/usr\/share\/devtools\/pacman.conf.d\/extra.conf)]:from_configuration:"
|
||||
{--generate-salt,--no-generate-salt}"[generate salt for user passwords (default\: False)]:generate_salt:"
|
||||
{--makeflags-jobs,--no-makeflags-jobs}"[append MAKEFLAGS variable with parallelism set to number of cores (default\: True)]:makeflags_jobs:"
|
||||
"--mirror[use the specified explicitly mirror instead of including mirrorlist (default\: None)]:mirror:"
|
||||
{--multilib,--no-multilib}"[add or do not multilib repository (default\: True)]:multilib:"
|
||||
"--packager[packager name and email (default\: None)]:packager:"
|
||||
"--repository[repository name (default\: None)]:repository:"
|
||||
"--sign-key[sign key id (default\: None)]:sign_key:"
|
||||
"*--sign-target[sign options (default\: None)]:sign_target:(disabled packages repository)"
|
||||
"--web-port[port of the web service (default\: None)]:web_port:"
|
||||
"--web-unix-socket[path to unix socket used for interprocess communications (default\: None)]:web_unix_socket:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_service_shell_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
":instead of dropping into shell, just execute the specified code:"
|
||||
":instead of dropping into shell, just execute the specified code (default\: None):"
|
||||
)
|
||||
|
||||
_shtab_ahriman_setup_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"--build-as-user[force makepkg user to the specific one]:build_as_user:"
|
||||
"--build-command[build command prefix]:build_command:"
|
||||
"--from-configuration[path to default devtools pacman configuration]:from_configuration:"
|
||||
{--generate-salt,--no-generate-salt}"[generate salt for user passwords]:generate_salt:"
|
||||
{--makeflags-jobs,--no-makeflags-jobs}"[append MAKEFLAGS variable with parallelism set to number of cores]:makeflags_jobs:"
|
||||
"--mirror[use the specified explicitly mirror instead of including mirrorlist]:mirror:"
|
||||
{--multilib,--no-multilib}"[add or do not multilib repository]:multilib:"
|
||||
"--packager[packager name and email]:packager:"
|
||||
"--repository[repository name]:repository:"
|
||||
"--sign-key[sign key id]:sign_key:"
|
||||
"*--sign-target[sign options]:sign_target:(disabled packages repository)"
|
||||
"--web-port[port of the web service]:web_port:"
|
||||
"--web-unix-socket[path to unix socket used for interprocess communications]:web_unix_socket:"
|
||||
"--build-as-user[force makepkg user to the specific one (default\: None)]:build_as_user:"
|
||||
"--build-command[build command prefix (default\: ahriman)]:build_command:"
|
||||
"--from-configuration[path to default devtools pacman configuration (default\: \/usr\/share\/devtools\/pacman.conf.d\/extra.conf)]:from_configuration:"
|
||||
{--generate-salt,--no-generate-salt}"[generate salt for user passwords (default\: False)]:generate_salt:"
|
||||
{--makeflags-jobs,--no-makeflags-jobs}"[append MAKEFLAGS variable with parallelism set to number of cores (default\: True)]:makeflags_jobs:"
|
||||
"--mirror[use the specified explicitly mirror instead of including mirrorlist (default\: None)]:mirror:"
|
||||
{--multilib,--no-multilib}"[add or do not multilib repository (default\: True)]:multilib:"
|
||||
"--packager[packager name and email (default\: None)]:packager:"
|
||||
"--repository[repository name (default\: None)]:repository:"
|
||||
"--sign-key[sign key id (default\: None)]:sign_key:"
|
||||
"*--sign-target[sign options (default\: None)]:sign_target:(disabled packages repository)"
|
||||
"--web-port[port of the web service (default\: None)]:web_port:"
|
||||
"--web-unix-socket[path to unix socket used for interprocess communications (default\: None)]:web_unix_socket:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_shell_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
":instead of dropping into shell, just execute the specified code:"
|
||||
":instead of dropping into shell, just execute the specified code (default\: None):"
|
||||
)
|
||||
|
||||
_shtab_ahriman_sign_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"(*)::sign only specified packages:"
|
||||
"(*)::sign only specified packages (default\: None):"
|
||||
)
|
||||
|
||||
_shtab_ahriman_status_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"--ahriman[get service status itself]"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty]"
|
||||
{--info,--no-info}"[show additional package information]:info:"
|
||||
{-s,--status}"[filter packages by status]:status:(unknown pending building failed success)"
|
||||
"(*)::filter status by package base:"
|
||||
"--ahriman[get service status itself (default\: False)]"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{--info,--no-info}"[show additional package information (default\: False)]:info:"
|
||||
{-s,--status}"[filter packages by status (default\: None)]:status:(unknown pending building failed success)"
|
||||
"(*)::filter status by package base (default\: None):"
|
||||
)
|
||||
|
||||
_shtab_ahriman_status_update_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-s,--status}"[new package build status]:status:(unknown pending building failed success)"
|
||||
"(*)::set status for specified packages. If no packages supplied, service status will be updated:"
|
||||
{-s,--status}"[new package build status (default\: BuildStatusEnum.Success)]:status:(unknown pending building failed success)"
|
||||
"(*)::set status for specified packages. If no packages supplied, service status will be updated (default\: None):"
|
||||
)
|
||||
|
||||
_shtab_ahriman_sync_options=(
|
||||
@ -534,32 +540,33 @@ _shtab_ahriman_sync_options=(
|
||||
|
||||
_shtab_ahriman_update_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--aur,--no-aur}"[enable or disable checking for AUR updates]:aur:"
|
||||
{--dependencies,--no-dependencies}"[process missing package dependencies]:dependencies:"
|
||||
"--dry-run[just perform check for updates, same as check command]"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty]"
|
||||
{--local,--no-local}"[enable or disable checking of local packages for updates]:local:"
|
||||
{--manual,--no-manual}"[include or exclude manual updates]:manual:"
|
||||
{-u,--username}"[build as user]:username:"
|
||||
{--vcs,--no-vcs}"[fetch actual version of VCS packages]:vcs:"
|
||||
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date]"
|
||||
"(*)::filter check by package base:"
|
||||
{--aur,--no-aur}"[enable or disable checking for AUR updates (default\: True)]:aur:"
|
||||
{--dependencies,--no-dependencies}"[process missing package dependencies (default\: True)]:dependencies:"
|
||||
"--dry-run[just perform check for updates, same as check command (default\: False)]"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{--increment,--no-increment}"[increment package release (pkgrel) on duplicate (default\: True)]:increment:"
|
||||
{--local,--no-local}"[enable or disable checking of local packages for updates (default\: True)]:local:"
|
||||
{--manual,--no-manual}"[include or exclude manual updates (default\: True)]:manual:"
|
||||
{-u,--username}"[build as user (default\: None)]:username:"
|
||||
{--vcs,--no-vcs}"[fetch actual version of VCS packages (default\: True)]:vcs:"
|
||||
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date (default\: False)]"
|
||||
"(*)::filter check by package base (default\: None):"
|
||||
)
|
||||
|
||||
_shtab_ahriman_user_add_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"--key[optional PGP key used by this user. The private key must be imported]:key:"
|
||||
"--packager[optional packager id used for build process in form of \`Name Surname \<mail\@example.com\>\`]:packager:"
|
||||
{-p,--password}"[user password. Blank password will be treated as empty password, which is in particular must be used for OAuth2 authorization type.]:password:"
|
||||
{-r,--role}"[user access level]:role:(unauthorized read reporter full)"
|
||||
"--key[optional PGP key used by this user. The private key must be imported (default\: None)]:key:"
|
||||
"--packager[optional packager id used for build process in form of \`Name Surname \<mail\@example.com\>\` (default\: None)]:packager:"
|
||||
{-p,--password}"[user password. Blank password will be treated as empty password, which is in particular must be used for OAuth2 authorization type. (default\: None)]:password:"
|
||||
{-r,--role}"[user access level (default\: UserAccess.Read)]:role:(unauthorized read reporter full)"
|
||||
":username for web service:"
|
||||
)
|
||||
|
||||
_shtab_ahriman_user_list_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty]"
|
||||
{-r,--role}"[filter users by role]:role:(unauthorized read reporter full)"
|
||||
":filter users by username:"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{-r,--role}"[filter users by role (default\: None)]:role:(unauthorized read reporter full)"
|
||||
":filter users by username (default\: None):"
|
||||
)
|
||||
|
||||
_shtab_ahriman_user_remove_options=(
|
||||
@ -582,7 +589,7 @@ _shtab_ahriman() {
|
||||
if ((${_shtab_ahriman_options[(I)${(q)one_or_more}*]} + ${_shtab_ahriman_options[(I)${(q)remainder}*]} == 0)); then # noqa: E501
|
||||
_shtab_ahriman_options+=(': :_shtab_ahriman_commands' '*::: :->ahriman')
|
||||
fi
|
||||
_arguments -C $_shtab_ahriman_options
|
||||
_arguments -C -s $_shtab_ahriman_options
|
||||
|
||||
case $state in
|
||||
ahriman)
|
||||
@ -590,72 +597,72 @@ _shtab_ahriman() {
|
||||
(( CURRENT += 1 ))
|
||||
curcontext="${curcontext%:*:*}:_shtab_ahriman-$line[1]:"
|
||||
case $line[1] in
|
||||
add) _arguments -C $_shtab_ahriman_add_options ;;
|
||||
aur-search) _arguments -C $_shtab_ahriman_aur_search_options ;;
|
||||
check) _arguments -C $_shtab_ahriman_check_options ;;
|
||||
clean) _arguments -C $_shtab_ahriman_clean_options ;;
|
||||
config) _arguments -C $_shtab_ahriman_config_options ;;
|
||||
config-validate) _arguments -C $_shtab_ahriman_config_validate_options ;;
|
||||
daemon) _arguments -C $_shtab_ahriman_daemon_options ;;
|
||||
help) _arguments -C $_shtab_ahriman_help_options ;;
|
||||
help-commands-unsafe) _arguments -C $_shtab_ahriman_help_commands_unsafe_options ;;
|
||||
help-updates) _arguments -C $_shtab_ahriman_help_updates_options ;;
|
||||
help-version) _arguments -C $_shtab_ahriman_help_version_options ;;
|
||||
init) _arguments -C $_shtab_ahriman_init_options ;;
|
||||
key-import) _arguments -C $_shtab_ahriman_key_import_options ;;
|
||||
package-add) _arguments -C $_shtab_ahriman_package_add_options ;;
|
||||
package-remove) _arguments -C $_shtab_ahriman_package_remove_options ;;
|
||||
package-status) _arguments -C $_shtab_ahriman_package_status_options ;;
|
||||
package-status-remove) _arguments -C $_shtab_ahriman_package_status_remove_options ;;
|
||||
package-status-update) _arguments -C $_shtab_ahriman_package_status_update_options ;;
|
||||
package-update) _arguments -C $_shtab_ahriman_package_update_options ;;
|
||||
patch-add) _arguments -C $_shtab_ahriman_patch_add_options ;;
|
||||
patch-list) _arguments -C $_shtab_ahriman_patch_list_options ;;
|
||||
patch-remove) _arguments -C $_shtab_ahriman_patch_remove_options ;;
|
||||
patch-set-add) _arguments -C $_shtab_ahriman_patch_set_add_options ;;
|
||||
rebuild) _arguments -C $_shtab_ahriman_rebuild_options ;;
|
||||
remove) _arguments -C $_shtab_ahriman_remove_options ;;
|
||||
remove-unknown) _arguments -C $_shtab_ahriman_remove_unknown_options ;;
|
||||
repo-backup) _arguments -C $_shtab_ahriman_repo_backup_options ;;
|
||||
repo-check) _arguments -C $_shtab_ahriman_repo_check_options ;;
|
||||
repo-clean) _arguments -C $_shtab_ahriman_repo_clean_options ;;
|
||||
repo-config) _arguments -C $_shtab_ahriman_repo_config_options ;;
|
||||
repo-config-validate) _arguments -C $_shtab_ahriman_repo_config_validate_options ;;
|
||||
repo-create-keyring) _arguments -C $_shtab_ahriman_repo_create_keyring_options ;;
|
||||
repo-create-mirrorlist) _arguments -C $_shtab_ahriman_repo_create_mirrorlist_options ;;
|
||||
repo-daemon) _arguments -C $_shtab_ahriman_repo_daemon_options ;;
|
||||
repo-init) _arguments -C $_shtab_ahriman_repo_init_options ;;
|
||||
repo-rebuild) _arguments -C $_shtab_ahriman_repo_rebuild_options ;;
|
||||
repo-remove-unknown) _arguments -C $_shtab_ahriman_repo_remove_unknown_options ;;
|
||||
repo-report) _arguments -C $_shtab_ahriman_repo_report_options ;;
|
||||
repo-restore) _arguments -C $_shtab_ahriman_repo_restore_options ;;
|
||||
repo-setup) _arguments -C $_shtab_ahriman_repo_setup_options ;;
|
||||
repo-sign) _arguments -C $_shtab_ahriman_repo_sign_options ;;
|
||||
repo-status-update) _arguments -C $_shtab_ahriman_repo_status_update_options ;;
|
||||
repo-sync) _arguments -C $_shtab_ahriman_repo_sync_options ;;
|
||||
repo-tree) _arguments -C $_shtab_ahriman_repo_tree_options ;;
|
||||
repo-triggers) _arguments -C $_shtab_ahriman_repo_triggers_options ;;
|
||||
repo-update) _arguments -C $_shtab_ahriman_repo_update_options ;;
|
||||
report) _arguments -C $_shtab_ahriman_report_options ;;
|
||||
search) _arguments -C $_shtab_ahriman_search_options ;;
|
||||
service-clean) _arguments -C $_shtab_ahriman_service_clean_options ;;
|
||||
service-config) _arguments -C $_shtab_ahriman_service_config_options ;;
|
||||
service-config-validate) _arguments -C $_shtab_ahriman_service_config_validate_options ;;
|
||||
service-key-import) _arguments -C $_shtab_ahriman_service_key_import_options ;;
|
||||
service-setup) _arguments -C $_shtab_ahriman_service_setup_options ;;
|
||||
service-shell) _arguments -C $_shtab_ahriman_service_shell_options ;;
|
||||
setup) _arguments -C $_shtab_ahriman_setup_options ;;
|
||||
shell) _arguments -C $_shtab_ahriman_shell_options ;;
|
||||
sign) _arguments -C $_shtab_ahriman_sign_options ;;
|
||||
status) _arguments -C $_shtab_ahriman_status_options ;;
|
||||
status-update) _arguments -C $_shtab_ahriman_status_update_options ;;
|
||||
sync) _arguments -C $_shtab_ahriman_sync_options ;;
|
||||
update) _arguments -C $_shtab_ahriman_update_options ;;
|
||||
user-add) _arguments -C $_shtab_ahriman_user_add_options ;;
|
||||
user-list) _arguments -C $_shtab_ahriman_user_list_options ;;
|
||||
user-remove) _arguments -C $_shtab_ahriman_user_remove_options ;;
|
||||
version) _arguments -C $_shtab_ahriman_version_options ;;
|
||||
web) _arguments -C $_shtab_ahriman_web_options ;;
|
||||
add) _arguments -C -s $_shtab_ahriman_add_options ;;
|
||||
aur-search) _arguments -C -s $_shtab_ahriman_aur_search_options ;;
|
||||
check) _arguments -C -s $_shtab_ahriman_check_options ;;
|
||||
clean) _arguments -C -s $_shtab_ahriman_clean_options ;;
|
||||
config) _arguments -C -s $_shtab_ahriman_config_options ;;
|
||||
config-validate) _arguments -C -s $_shtab_ahriman_config_validate_options ;;
|
||||
daemon) _arguments -C -s $_shtab_ahriman_daemon_options ;;
|
||||
help) _arguments -C -s $_shtab_ahriman_help_options ;;
|
||||
help-commands-unsafe) _arguments -C -s $_shtab_ahriman_help_commands_unsafe_options ;;
|
||||
help-updates) _arguments -C -s $_shtab_ahriman_help_updates_options ;;
|
||||
help-version) _arguments -C -s $_shtab_ahriman_help_version_options ;;
|
||||
init) _arguments -C -s $_shtab_ahriman_init_options ;;
|
||||
key-import) _arguments -C -s $_shtab_ahriman_key_import_options ;;
|
||||
package-add) _arguments -C -s $_shtab_ahriman_package_add_options ;;
|
||||
package-remove) _arguments -C -s $_shtab_ahriman_package_remove_options ;;
|
||||
package-status) _arguments -C -s $_shtab_ahriman_package_status_options ;;
|
||||
package-status-remove) _arguments -C -s $_shtab_ahriman_package_status_remove_options ;;
|
||||
package-status-update) _arguments -C -s $_shtab_ahriman_package_status_update_options ;;
|
||||
package-update) _arguments -C -s $_shtab_ahriman_package_update_options ;;
|
||||
patch-add) _arguments -C -s $_shtab_ahriman_patch_add_options ;;
|
||||
patch-list) _arguments -C -s $_shtab_ahriman_patch_list_options ;;
|
||||
patch-remove) _arguments -C -s $_shtab_ahriman_patch_remove_options ;;
|
||||
patch-set-add) _arguments -C -s $_shtab_ahriman_patch_set_add_options ;;
|
||||
rebuild) _arguments -C -s $_shtab_ahriman_rebuild_options ;;
|
||||
remove) _arguments -C -s $_shtab_ahriman_remove_options ;;
|
||||
remove-unknown) _arguments -C -s $_shtab_ahriman_remove_unknown_options ;;
|
||||
repo-backup) _arguments -C -s $_shtab_ahriman_repo_backup_options ;;
|
||||
repo-check) _arguments -C -s $_shtab_ahriman_repo_check_options ;;
|
||||
repo-clean) _arguments -C -s $_shtab_ahriman_repo_clean_options ;;
|
||||
repo-config) _arguments -C -s $_shtab_ahriman_repo_config_options ;;
|
||||
repo-config-validate) _arguments -C -s $_shtab_ahriman_repo_config_validate_options ;;
|
||||
repo-create-keyring) _arguments -C -s $_shtab_ahriman_repo_create_keyring_options ;;
|
||||
repo-create-mirrorlist) _arguments -C -s $_shtab_ahriman_repo_create_mirrorlist_options ;;
|
||||
repo-daemon) _arguments -C -s $_shtab_ahriman_repo_daemon_options ;;
|
||||
repo-init) _arguments -C -s $_shtab_ahriman_repo_init_options ;;
|
||||
repo-rebuild) _arguments -C -s $_shtab_ahriman_repo_rebuild_options ;;
|
||||
repo-remove-unknown) _arguments -C -s $_shtab_ahriman_repo_remove_unknown_options ;;
|
||||
repo-report) _arguments -C -s $_shtab_ahriman_repo_report_options ;;
|
||||
repo-restore) _arguments -C -s $_shtab_ahriman_repo_restore_options ;;
|
||||
repo-setup) _arguments -C -s $_shtab_ahriman_repo_setup_options ;;
|
||||
repo-sign) _arguments -C -s $_shtab_ahriman_repo_sign_options ;;
|
||||
repo-status-update) _arguments -C -s $_shtab_ahriman_repo_status_update_options ;;
|
||||
repo-sync) _arguments -C -s $_shtab_ahriman_repo_sync_options ;;
|
||||
repo-tree) _arguments -C -s $_shtab_ahriman_repo_tree_options ;;
|
||||
repo-triggers) _arguments -C -s $_shtab_ahriman_repo_triggers_options ;;
|
||||
repo-update) _arguments -C -s $_shtab_ahriman_repo_update_options ;;
|
||||
report) _arguments -C -s $_shtab_ahriman_report_options ;;
|
||||
search) _arguments -C -s $_shtab_ahriman_search_options ;;
|
||||
service-clean) _arguments -C -s $_shtab_ahriman_service_clean_options ;;
|
||||
service-config) _arguments -C -s $_shtab_ahriman_service_config_options ;;
|
||||
service-config-validate) _arguments -C -s $_shtab_ahriman_service_config_validate_options ;;
|
||||
service-key-import) _arguments -C -s $_shtab_ahriman_service_key_import_options ;;
|
||||
service-setup) _arguments -C -s $_shtab_ahriman_service_setup_options ;;
|
||||
service-shell) _arguments -C -s $_shtab_ahriman_service_shell_options ;;
|
||||
setup) _arguments -C -s $_shtab_ahriman_setup_options ;;
|
||||
shell) _arguments -C -s $_shtab_ahriman_shell_options ;;
|
||||
sign) _arguments -C -s $_shtab_ahriman_sign_options ;;
|
||||
status) _arguments -C -s $_shtab_ahriman_status_options ;;
|
||||
status-update) _arguments -C -s $_shtab_ahriman_status_update_options ;;
|
||||
sync) _arguments -C -s $_shtab_ahriman_sync_options ;;
|
||||
update) _arguments -C -s $_shtab_ahriman_update_options ;;
|
||||
user-add) _arguments -C -s $_shtab_ahriman_user_add_options ;;
|
||||
user-list) _arguments -C -s $_shtab_ahriman_user_list_options ;;
|
||||
user-remove) _arguments -C -s $_shtab_ahriman_user_remove_options ;;
|
||||
version) _arguments -C -s $_shtab_ahriman_version_options ;;
|
||||
web) _arguments -C -s $_shtab_ahriman_web_options ;;
|
||||
esac
|
||||
esac
|
||||
}
|
84
pyproject.toml
Normal file
84
pyproject.toml
Normal file
@ -0,0 +1,84 @@
|
||||
[build-system]
|
||||
requires = ["flit_core"]
|
||||
build-backend = "flit_core.buildapi"
|
||||
|
||||
[project]
|
||||
name = "ahriman"
|
||||
|
||||
description = "ArcH linux ReposItory MANager"
|
||||
readme = "README.md"
|
||||
|
||||
requires-python = ">=3.11"
|
||||
|
||||
license = {file = "COPYING"}
|
||||
authors = [
|
||||
{name = "ahriman team"},
|
||||
]
|
||||
|
||||
dependencies = [
|
||||
"cerberus",
|
||||
"inflection",
|
||||
"passlib",
|
||||
"requests",
|
||||
"srcinfo",
|
||||
]
|
||||
|
||||
dynamic = ["version"]
|
||||
|
||||
[project.urls]
|
||||
Documentation = "https://ahriman.readthedocs.io/"
|
||||
Repository = "https://github.com/arcan1s/ahriman"
|
||||
Changelog = "https://github.com/arcan1s/ahriman/releases"
|
||||
|
||||
[project.scripts]
|
||||
ahriman = "ahriman.application.ahriman:run"
|
||||
|
||||
[project.optional-dependencies]
|
||||
check = [
|
||||
"autopep8",
|
||||
"bandit",
|
||||
"mypy",
|
||||
"pylint",
|
||||
]
|
||||
docs = [
|
||||
"Sphinx",
|
||||
"argparse-manpage",
|
||||
"pydeps",
|
||||
"shtab",
|
||||
"sphinx-argparse",
|
||||
"sphinx-rtd-theme>=1.1.1", # https://stackoverflow.com/a/74355734
|
||||
]
|
||||
journald = [
|
||||
"systemd-python",
|
||||
]
|
||||
# FIXME technically this dependency is required, but in some cases we do not have access to
|
||||
# the libalpm which is required in order to install the package. Thus in case if we do not
|
||||
# really need to run the application we can move it to "optional" dependencies
|
||||
pacman = [
|
||||
"pyalpm",
|
||||
]
|
||||
s3 = [
|
||||
"boto3",
|
||||
]
|
||||
tests = [
|
||||
"pytest",
|
||||
"pytest-aiohttp",
|
||||
"pytest-cov",
|
||||
"pytest-helpers-namespace",
|
||||
"pytest-mock",
|
||||
"pytest-resource-path",
|
||||
"pytest-spec",
|
||||
]
|
||||
web = [
|
||||
"Jinja2",
|
||||
"aioauth-client",
|
||||
"aiohttp",
|
||||
"aiohttp-apispec",
|
||||
"aiohttp_cors",
|
||||
"aiohttp_jinja2",
|
||||
"aiohttp_debugtoolbar",
|
||||
"aiohttp_session",
|
||||
"aiohttp_security",
|
||||
"cryptography",
|
||||
"requests-unixsocket", # required by unix socket support
|
||||
]
|
159
setup.py
159
setup.py
@ -1,159 +0,0 @@
|
||||
from pathlib import Path
|
||||
from setuptools import find_packages, setup
|
||||
from typing import Any
|
||||
|
||||
|
||||
metadata_path = Path(__file__).resolve().parent / "src/ahriman/version.py"
|
||||
metadata: dict[str, Any] = {}
|
||||
with metadata_path.open() as metadata_file:
|
||||
exec(metadata_file.read(), metadata) # pylint: disable=exec-used
|
||||
|
||||
|
||||
setup(
|
||||
name="ahriman",
|
||||
|
||||
version=metadata["__version__"],
|
||||
zip_safe=False,
|
||||
|
||||
description="ArcH linux ReposItory MANager",
|
||||
|
||||
author="ahriman team",
|
||||
author_email="",
|
||||
url="https://github.com/arcan1s/ahriman",
|
||||
|
||||
license="GPL3",
|
||||
|
||||
packages=find_packages("src"),
|
||||
package_dir={"": "src"},
|
||||
package_data={"": ["py.typed"]},
|
||||
|
||||
dependency_links=[
|
||||
],
|
||||
install_requires=[
|
||||
"cerberus",
|
||||
"inflection",
|
||||
"passlib",
|
||||
"requests",
|
||||
"srcinfo",
|
||||
],
|
||||
setup_requires=[
|
||||
],
|
||||
tests_require=[
|
||||
"pytest",
|
||||
"pytest-aiohttp",
|
||||
"pytest-cov",
|
||||
"pytest-helpers-namespace",
|
||||
"pytest-mock",
|
||||
"pytest-spec",
|
||||
"pytest-resource-path",
|
||||
],
|
||||
|
||||
include_package_data=True,
|
||||
scripts=[
|
||||
"package/bin/ahriman",
|
||||
],
|
||||
data_files=[
|
||||
# configuration
|
||||
("share/ahriman/settings", [
|
||||
"package/share/ahriman/settings/ahriman.ini",
|
||||
]),
|
||||
("share/ahriman/settings/ahriman.ini.d", [
|
||||
"package/share/ahriman/settings/ahriman.ini.d/logging.ini",
|
||||
]),
|
||||
# systemd files
|
||||
("lib/systemd/system", [
|
||||
"package/lib/systemd/system/ahriman@.service",
|
||||
"package/lib/systemd/system/ahriman@.timer",
|
||||
"package/lib/systemd/system/ahriman-web@.service",
|
||||
]),
|
||||
# templates
|
||||
("share/ahriman/templates", [
|
||||
"package/share/ahriman/templates/api.jinja2",
|
||||
"package/share/ahriman/templates/build-status.jinja2",
|
||||
"package/share/ahriman/templates/email-index.jinja2",
|
||||
"package/share/ahriman/templates/error.jinja2",
|
||||
"package/share/ahriman/templates/repo-index.jinja2",
|
||||
"package/share/ahriman/templates/shell",
|
||||
"package/share/ahriman/templates/telegram-index.jinja2",
|
||||
]),
|
||||
("share/ahriman/templates/build-status", [
|
||||
"package/share/ahriman/templates/build-status/alerts.jinja2",
|
||||
"package/share/ahriman/templates/build-status/key-import-modal.jinja2",
|
||||
"package/share/ahriman/templates/build-status/login-modal.jinja2",
|
||||
"package/share/ahriman/templates/build-status/package-add-modal.jinja2",
|
||||
"package/share/ahriman/templates/build-status/package-info-modal.jinja2",
|
||||
"package/share/ahriman/templates/build-status/package-rebuild-modal.jinja2",
|
||||
"package/share/ahriman/templates/build-status/table.jinja2",
|
||||
]),
|
||||
("share/ahriman/templates/static", [
|
||||
"package/share/ahriman/templates/static/favicon.ico",
|
||||
]),
|
||||
("share/ahriman/templates/utils", [
|
||||
"package/share/ahriman/templates/utils/bootstrap-scripts.jinja2",
|
||||
"package/share/ahriman/templates/utils/style.jinja2",
|
||||
]),
|
||||
# man pages
|
||||
("share/man/man1", [
|
||||
"docs/ahriman.1",
|
||||
]),
|
||||
# shell completions
|
||||
("share/bash-completion/completions", [
|
||||
"docs/completions/bash/_ahriman",
|
||||
]),
|
||||
("share/zsh/site-functions", [
|
||||
"docs/completions/zsh/_ahriman",
|
||||
]),
|
||||
],
|
||||
|
||||
extras_require={
|
||||
"check": [
|
||||
"autopep8",
|
||||
"bandit",
|
||||
"mypy",
|
||||
"pylint",
|
||||
],
|
||||
"docs": [
|
||||
"Sphinx",
|
||||
"argparse-manpage",
|
||||
"pydeps",
|
||||
"shtab",
|
||||
"sphinx-argparse",
|
||||
"sphinx-rtd-theme>=1.1.1", # https://stackoverflow.com/a/74355734
|
||||
"sphinxcontrib-napoleon",
|
||||
],
|
||||
"journald": [
|
||||
"systemd-python",
|
||||
],
|
||||
# FIXME technically this dependency is required, but in some cases we do not have access to
|
||||
# the libalpm which is required in order to install the package. Thus in case if we do not
|
||||
# really need to run the application we can move it to "optional" dependencies
|
||||
"pacman": [
|
||||
"pyalpm",
|
||||
],
|
||||
"s3": [
|
||||
"boto3",
|
||||
],
|
||||
"tests": [
|
||||
"pytest",
|
||||
"pytest-aiohttp",
|
||||
"pytest-cov",
|
||||
"pytest-helpers-namespace",
|
||||
"pytest-mock",
|
||||
"pytest-resource-path",
|
||||
"pytest-spec",
|
||||
],
|
||||
"web": [
|
||||
"Jinja2",
|
||||
"aioauth-client",
|
||||
"aiohttp",
|
||||
"aiohttp-apispec",
|
||||
"aiohttp_cors",
|
||||
"aiohttp_jinja2",
|
||||
"aiohttp_debugtoolbar",
|
||||
"aiohttp_session",
|
||||
"aiohttp_security",
|
||||
"cryptography",
|
||||
"requests-unixsocket", # required by unix socket support
|
||||
],
|
||||
},
|
||||
)
|
@ -17,3 +17,4 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
__version__ = "2.10.2"
|
||||
|
@ -19,13 +19,12 @@
|
||||
#
|
||||
# pylint: disable=too-many-lines
|
||||
import argparse
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
from pathlib import Path
|
||||
from typing import TypeVar
|
||||
|
||||
from ahriman import version
|
||||
from ahriman import __version__
|
||||
from ahriman.application import handlers
|
||||
from ahriman.core.util import enum_values, extract_user
|
||||
from ahriman.models.action import Action
|
||||
@ -85,7 +84,7 @@ def _parser() -> argparse.ArgumentParser:
|
||||
parser.add_argument("-q", "--quiet", help="force disable any logging", action="store_true")
|
||||
parser.add_argument("--unsafe", help="allow to run ahriman as non-ahriman user. Some actions might be unavailable",
|
||||
action="store_true")
|
||||
parser.add_argument("-V", "--version", action="version", version=version.__version__)
|
||||
parser.add_argument("-V", "--version", action="version", version=__version__)
|
||||
|
||||
subparsers = parser.add_subparsers(title="command", help="command to run", dest="command", required=True)
|
||||
|
||||
@ -256,6 +255,8 @@ def _set_package_add_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||
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",
|
||||
@ -577,6 +578,8 @@ def _set_repo_rebuild_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||
"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))
|
||||
@ -751,6 +754,8 @@ def _set_repo_update_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||
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",
|
||||
@ -994,18 +999,15 @@ def _set_web_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||
return parser
|
||||
|
||||
|
||||
def run() -> None:
|
||||
def run() -> int:
|
||||
"""
|
||||
run application instance
|
||||
|
||||
Returns:
|
||||
int: application status code
|
||||
"""
|
||||
if __name__ == "__main__":
|
||||
args_parser = _parser()
|
||||
args = args_parser.parse_args()
|
||||
args_parser = _parser()
|
||||
args = args_parser.parse_args()
|
||||
|
||||
handler: handlers.Handler = args.handler
|
||||
status = handler.execute(args)
|
||||
|
||||
sys.exit(status)
|
||||
|
||||
|
||||
run()
|
||||
handler: handlers.Handler = args.handler
|
||||
return handler.execute(args)
|
||||
|
@ -142,8 +142,13 @@ class Application(ApplicationPackages, ApplicationRepository):
|
||||
|
||||
while missing := missing_dependencies(with_dependencies.values()):
|
||||
for package_name, username in missing.items():
|
||||
package = Package.from_aur(package_name, self.repository.pacman, username)
|
||||
if (source_dir := self.repository.paths.cache_for(package_name)).is_dir():
|
||||
# there is local cache, load package from it
|
||||
package = Package.from_build(source_dir, self.repository.architecture, username)
|
||||
else:
|
||||
package = Package.from_aur(package_name, self.repository.pacman, username)
|
||||
with_dependencies[package.base] = package
|
||||
|
||||
# register package in local database
|
||||
self.database.remote_update(package)
|
||||
self.repository.reporter.set_unknown(package)
|
||||
|
@ -95,7 +95,7 @@ class ApplicationPackages(ApplicationProperties):
|
||||
if (source_dir := Path(source)).is_dir():
|
||||
package = Package.from_build(source_dir, self.architecture, username)
|
||||
cache_dir = self.repository.paths.cache_for(package.base)
|
||||
shutil.copytree(source_dir, cache_dir) # copy package to store in caches
|
||||
shutil.copytree(source_dir, cache_dir, dirs_exist_ok=True) # copy package to store in caches
|
||||
Sources.init(cache_dir) # we need to run init command in directory where we do have permissions
|
||||
elif (source_dir := self.repository.paths.cache_for(source)).is_dir():
|
||||
package = Package.from_build(source_dir, self.architecture, username)
|
||||
@ -145,7 +145,7 @@ class ApplicationPackages(ApplicationProperties):
|
||||
username(str | None, optional): optional override of username for build process (Default value = None)
|
||||
"""
|
||||
for name in names:
|
||||
resolved_source = source.resolve(name)
|
||||
resolved_source = source.resolve(name, self.repository.paths)
|
||||
fn = getattr(self, f"_add_{resolved_source.value}")
|
||||
fn(name, username)
|
||||
|
||||
|
@ -123,7 +123,8 @@ class ApplicationRepository(ApplicationProperties):
|
||||
result.extend(unknown_aur(package)) # local package not found
|
||||
return result
|
||||
|
||||
def update(self, updates: Iterable[Package], packagers: Packagers | None = None) -> Result:
|
||||
def update(self, updates: Iterable[Package], packagers: Packagers | None = None, *,
|
||||
bump_pkgrel: bool = False) -> Result:
|
||||
"""
|
||||
run package updates
|
||||
|
||||
@ -131,6 +132,7 @@ class ApplicationRepository(ApplicationProperties):
|
||||
updates(Iterable[Package]): list of packages to update
|
||||
packagers(Packagers | None, optional): optional override of username for build process
|
||||
(Default value = None)
|
||||
bump_pkgrel(bool, optional): bump pkgrel in case of local version conflict (Default value = False)
|
||||
|
||||
Returns:
|
||||
Result: update result
|
||||
@ -150,7 +152,7 @@ class ApplicationRepository(ApplicationProperties):
|
||||
tree = Tree.resolve(updates)
|
||||
for num, level in enumerate(tree):
|
||||
self.logger.info("processing level #%i %s", num, [package.base for package in level])
|
||||
build_result = self.repository.process_build(level, packagers)
|
||||
build_result = self.repository.process_build(level, packagers, bump_pkgrel=bump_pkgrel)
|
||||
packages = self.repository.packages_built()
|
||||
process_update(packages, build_result)
|
||||
|
||||
|
@ -52,5 +52,5 @@ class Add(Handler):
|
||||
packagers = Packagers(args.username, {package.base: package.packager for package in packages})
|
||||
|
||||
application.print_updates(packages, log_fn=application.logger.info)
|
||||
result = application.update(packages, packagers)
|
||||
result = application.update(packages, packagers, bump_pkgrel=args.increment)
|
||||
Add.check_if_empty(args.exit_code, result.is_empty)
|
||||
|
@ -53,7 +53,7 @@ class Rebuild(Handler):
|
||||
application.print_updates(updates, log_fn=print)
|
||||
return
|
||||
|
||||
result = application.update(updates, args.username)
|
||||
result = application.update(updates, args.username, bump_pkgrel=args.increment)
|
||||
Rebuild.check_if_empty(args.exit_code, result.is_empty)
|
||||
|
||||
@staticmethod
|
||||
|
@ -19,7 +19,7 @@
|
||||
#
|
||||
import argparse
|
||||
|
||||
from ahriman import version
|
||||
from ahriman import __version__
|
||||
from ahriman.application.application import Application
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
@ -49,7 +49,7 @@ class ServiceUpdates(Handler):
|
||||
|
||||
remote = Package.from_aur("ahriman", application.repository.pacman, None)
|
||||
release = remote.version.rsplit("-", 1)[-1] # we don't store pkgrel locally, so we just append it
|
||||
local_version = f"{version.__version__}-{release}"
|
||||
local_version = f"{__version__}-{release}"
|
||||
|
||||
# technically we would like to compare versions, but it is fine to raise an exception in case if locally
|
||||
# installed package is newer than in AUR
|
||||
|
@ -54,7 +54,7 @@ class Update(Handler):
|
||||
packagers = Packagers(args.username, {package.base: package.packager for package in packages})
|
||||
|
||||
application.print_updates(packages, log_fn=application.logger.info)
|
||||
result = application.update(packages, packagers)
|
||||
result = application.update(packages, packagers, bump_pkgrel=args.increment)
|
||||
Update.check_if_empty(args.exit_code, result.is_empty)
|
||||
|
||||
@staticmethod
|
||||
|
@ -52,7 +52,7 @@ class Users(Handler):
|
||||
if args.action == Action.Update:
|
||||
user = Users.user_create(args)
|
||||
# if password is left blank we are not going to require salt to be set
|
||||
salt = configuration.get("auth", "salt") if user.password else ""
|
||||
salt = configuration.get("auth", "salt", fallback="") if user.password else ""
|
||||
database.user_update(user.hash_password(salt))
|
||||
elif args.action == Action.List:
|
||||
users = database.user_list(args.username, args.role)
|
||||
|
@ -24,7 +24,7 @@ import sys
|
||||
from collections.abc import Generator
|
||||
from importlib import metadata
|
||||
|
||||
from ahriman import version
|
||||
from ahriman import __version__
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.formatters import VersionPrinter
|
||||
@ -52,7 +52,7 @@ class Versions(Handler):
|
||||
configuration(Configuration): configuration instance
|
||||
report(bool): force enable or disable reporting
|
||||
"""
|
||||
VersionPrinter(f"Module version {version.__version__}",
|
||||
VersionPrinter(f"Module version {__version__}",
|
||||
{"Python": sys.version}).print(verbose=False, separator=" ")
|
||||
packages = Versions.package_dependencies("ahriman")
|
||||
VersionPrinter("Installed packages", dict(packages)).print(verbose=False, separator=" ")
|
||||
|
@ -22,7 +22,7 @@ import argparse
|
||||
from types import TracebackType
|
||||
from typing import Literal, Self
|
||||
|
||||
from ahriman import version
|
||||
from ahriman import __version__
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.exceptions import DuplicateRunError
|
||||
from ahriman.core.log import LazyLogging
|
||||
@ -77,9 +77,9 @@ class Lock(LazyLogging):
|
||||
check web server version
|
||||
"""
|
||||
status = self.reporter.get_internal()
|
||||
if status.version is not None and status.version != version.__version__:
|
||||
if status.version is not None and status.version != __version__:
|
||||
self.logger.warning("status watcher version mismatch, our %s, their %s",
|
||||
version.__version__, status.version)
|
||||
__version__, status.version)
|
||||
|
||||
def check_user(self) -> None:
|
||||
"""
|
||||
|
@ -17,7 +17,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from ahriman import version
|
||||
from ahriman import __version__
|
||||
from ahriman.core.alpm.pacman import Pacman
|
||||
from ahriman.core.log import LazyLogging
|
||||
from ahriman.models.aur_package import AURPackage
|
||||
@ -43,7 +43,7 @@ class Remote(LazyLogging):
|
||||
directly, whereas ``multisearch`` splits search one by one and finds intersection between search results.
|
||||
"""
|
||||
|
||||
DEFAULT_USER_AGENT = f"ahriman/{version.__version__}"
|
||||
DEFAULT_USER_AGENT = f"ahriman/{__version__}"
|
||||
|
||||
@classmethod
|
||||
def info(cls, package_name: str, *, pacman: Pacman) -> AURPackage:
|
||||
|
@ -46,7 +46,7 @@ class Mapping(Auth):
|
||||
"""
|
||||
Auth.__init__(self, configuration, provider)
|
||||
self.database = database
|
||||
self.salt = configuration.get("auth", "salt")
|
||||
self.salt = configuration.get("auth", "salt", fallback="")
|
||||
|
||||
async def check_credentials(self, username: str | None, password: str | None) -> bool:
|
||||
"""
|
||||
|
@ -36,9 +36,11 @@ class Sources(LazyLogging):
|
||||
Attributes:
|
||||
DEFAULT_BRANCH(str): (class attribute) default branch to process git repositories.
|
||||
Must be used only for local stored repositories, use RemoteSource descriptor instead for real packages
|
||||
DEFAULT_COMMIT_AUTHOR(tuple[str, str]): (class attribute) default commit author to be used if none set
|
||||
"""
|
||||
|
||||
DEFAULT_BRANCH = "master" # default fallback branch
|
||||
DEFAULT_COMMIT_AUTHOR = ("ahriman", "ahriman@localhost")
|
||||
|
||||
_check_output = check_output
|
||||
|
||||
@ -61,13 +63,13 @@ class Sources(LazyLogging):
|
||||
return [PkgbuildPatch("arch", list(architectures))]
|
||||
|
||||
@staticmethod
|
||||
def fetch(sources_dir: Path, remote: RemoteSource | None) -> None:
|
||||
def fetch(sources_dir: Path, remote: RemoteSource) -> None:
|
||||
"""
|
||||
either clone repository or update it to origin/``remote.branch``
|
||||
|
||||
Args:
|
||||
sources_dir(Path): local path to fetch
|
||||
remote(RemoteSource | None): remote target (from where to fetch)
|
||||
remote(RemoteSource): remote target (from where to fetch)
|
||||
"""
|
||||
instance = Sources()
|
||||
# local directory exists and there is .git directory
|
||||
@ -77,11 +79,11 @@ class Sources(LazyLogging):
|
||||
instance.logger.info("skip update at %s because there are no branches configured", sources_dir)
|
||||
return
|
||||
|
||||
branch = remote.branch if remote is not None else instance.DEFAULT_BRANCH
|
||||
branch = remote.branch or instance.DEFAULT_BRANCH
|
||||
if is_initialized_git:
|
||||
instance.logger.info("update HEAD to remote at %s using branch %s", sources_dir, branch)
|
||||
Sources._check_output("git", "fetch", "origin", branch, cwd=sources_dir, logger=instance.logger)
|
||||
elif remote is not None:
|
||||
elif remote.git_url is not None:
|
||||
instance.logger.info("clone remote %s to %s using branch %s", remote.git_url, sources_dir, branch)
|
||||
Sources._check_output("git", "clone", "--branch", branch, "--single-branch",
|
||||
remote.git_url, str(sources_dir), cwd=sources_dir.parent, logger=instance.logger)
|
||||
@ -95,7 +97,7 @@ class Sources(LazyLogging):
|
||||
|
||||
# move content if required
|
||||
# we are using full path to source directory in order to make append possible
|
||||
pkgbuild_dir = remote.pkgbuild_dir if remote is not None else sources_dir.resolve()
|
||||
pkgbuild_dir = remote.pkgbuild_dir or sources_dir.resolve()
|
||||
instance.move((sources_dir / pkgbuild_dir).resolve(), sources_dir)
|
||||
|
||||
@staticmethod
|
||||
@ -122,14 +124,16 @@ class Sources(LazyLogging):
|
||||
sources_dir(Path): local path to sources
|
||||
"""
|
||||
instance = Sources()
|
||||
Sources._check_output("git", "init", "--initial-branch", instance.DEFAULT_BRANCH,
|
||||
cwd=sources_dir, logger=instance.logger)
|
||||
if not (sources_dir / ".git").is_dir():
|
||||
# skip initializing in case if it was already
|
||||
Sources._check_output("git", "init", "--initial-branch", instance.DEFAULT_BRANCH,
|
||||
cwd=sources_dir, logger=instance.logger)
|
||||
|
||||
# extract local files...
|
||||
files = ["PKGBUILD", ".SRCINFO"] + [str(path) for path in Package.local_files(sources_dir)]
|
||||
instance.add(sources_dir, *files)
|
||||
# ...and commit them
|
||||
instance.commit(sources_dir, author="ahriman <ahriman@localhost>")
|
||||
instance.commit(sources_dir)
|
||||
|
||||
@staticmethod
|
||||
def load(sources_dir: Path, package: Package, patches: list[PkgbuildPatch], paths: RepositoryPaths) -> None:
|
||||
@ -170,7 +174,8 @@ class Sources(LazyLogging):
|
||||
return f"{diff}\n" # otherwise, patch will be broken
|
||||
|
||||
@staticmethod
|
||||
def push(sources_dir: Path, remote: RemoteSource, *pattern: str, commit_author: str | None = None) -> None:
|
||||
def push(sources_dir: Path, remote: RemoteSource, *pattern: str,
|
||||
commit_author: tuple[str, str] | None = None) -> None:
|
||||
"""
|
||||
commit selected changes and push files to the remote repository
|
||||
|
||||
@ -178,13 +183,15 @@ class Sources(LazyLogging):
|
||||
sources_dir(Path): local path to git repository
|
||||
remote(RemoteSource): remote target, branch and url
|
||||
*pattern(str): glob patterns
|
||||
commit_author(str | None, optional): commit author in form of git config (i.e. ``user <user@host>``)
|
||||
(Default value = None)
|
||||
commit_author(tuple[str, str] | None, optional): commit author if any (Default value = None)
|
||||
"""
|
||||
instance = Sources()
|
||||
instance.add(sources_dir, *pattern)
|
||||
instance.commit(sources_dir, author=commit_author)
|
||||
Sources._check_output("git", "push", remote.git_url, remote.branch, cwd=sources_dir, logger=instance.logger)
|
||||
if not instance.commit(sources_dir, commit_author=commit_author):
|
||||
return # no changes to push, just skip action
|
||||
|
||||
git_url, branch = remote.git_source()
|
||||
Sources._check_output("git", "push", git_url, branch, cwd=sources_dir, logger=instance.logger)
|
||||
|
||||
def add(self, sources_dir: Path, *pattern: str, intent_to_add: bool = False) -> None:
|
||||
"""
|
||||
@ -208,7 +215,8 @@ class Sources(LazyLogging):
|
||||
Sources._check_output("git", "add", *args, *[str(fn.relative_to(sources_dir)) for fn in found_files],
|
||||
cwd=sources_dir, logger=self.logger)
|
||||
|
||||
def commit(self, sources_dir: Path, message: str | None = None, author: str | None = None) -> None:
|
||||
def commit(self, sources_dir: Path, message: str | None = None,
|
||||
commit_author: tuple[str, str] | None = None) -> bool:
|
||||
"""
|
||||
commit changes
|
||||
|
||||
@ -216,14 +224,28 @@ class Sources(LazyLogging):
|
||||
sources_dir(Path): local path to git repository
|
||||
message(str | None, optional): optional commit message if any. If none set, message will be generated
|
||||
according to the current timestamp (Default value = None)
|
||||
author(str | None, optional): optional commit author if any (Default value = None)
|
||||
commit_author(tuple[str, str] | None, optional): optional commit author if any (Default value = None)
|
||||
|
||||
Returns:
|
||||
bool: True in case if changes have been committed and False otherwise
|
||||
"""
|
||||
if not self.has_changes(sources_dir):
|
||||
return False # nothing to commit
|
||||
|
||||
if message is None:
|
||||
message = f"Autogenerated commit at {utcnow()}"
|
||||
args = ["--allow-empty", "--message", message]
|
||||
if author is not None:
|
||||
args.extend(["--author", author])
|
||||
Sources._check_output("git", "commit", *args, cwd=sources_dir, logger=self.logger)
|
||||
args = ["--message", message]
|
||||
environment: dict[str, str] = {}
|
||||
|
||||
if commit_author is None:
|
||||
commit_author = self.DEFAULT_COMMIT_AUTHOR
|
||||
user, email = commit_author
|
||||
environment["GIT_AUTHOR_NAME"] = environment["GIT_COMMITTER_NAME"] = user
|
||||
environment["GIT_AUTHOR_EMAIL"] = environment["GIT_COMMITTER_EMAIL"] = email
|
||||
|
||||
Sources._check_output("git", "commit", *args, cwd=sources_dir, logger=self.logger, environment=environment)
|
||||
|
||||
return True
|
||||
|
||||
def diff(self, sources_dir: Path) -> str:
|
||||
"""
|
||||
@ -237,6 +259,20 @@ class Sources(LazyLogging):
|
||||
"""
|
||||
return Sources._check_output("git", "diff", cwd=sources_dir, logger=self.logger)
|
||||
|
||||
def has_changes(self, sources_dir: Path) -> bool:
|
||||
"""
|
||||
check if there are changes in current git tree
|
||||
|
||||
Args:
|
||||
sources_dir(Path): local path to git repository
|
||||
|
||||
Returns:
|
||||
bool: True if there are uncommitted changes and False otherwise
|
||||
"""
|
||||
# there is --exit-code argument to diff, however, there might be other process errors
|
||||
changes = Sources._check_output("git", "diff", "--cached", "--name-only", cwd=sources_dir, logger=self.logger)
|
||||
return bool(changes)
|
||||
|
||||
def move(self, pkgbuild_dir: Path, sources_dir: Path) -> None:
|
||||
"""
|
||||
move content from pkgbuild_dir to sources_dir
|
||||
|
@ -26,6 +26,7 @@ from ahriman.core.exceptions import BuildError
|
||||
from ahriman.core.log import LazyLogging
|
||||
from ahriman.core.util import check_output
|
||||
from ahriman.models.package import Package
|
||||
from ahriman.models.pkgbuild_patch import PkgbuildPatch
|
||||
from ahriman.models.repository_paths import RepositoryPaths
|
||||
|
||||
|
||||
@ -34,6 +35,11 @@ class Task(LazyLogging):
|
||||
base package build task
|
||||
|
||||
Attributes:
|
||||
archbuild_flags(list[str]): command flags for archbuild command
|
||||
architecture(str): repository architecture
|
||||
build_command(str): build command
|
||||
makechroootpkg_flags(list[str]): command flags for makechrootpkg command
|
||||
makepkg_flags(list[str]): command flags for makepkg command
|
||||
package(Package): package definitions
|
||||
paths(RepositoryPaths): repository paths instance
|
||||
uid(int): uid of the repository owner user
|
||||
@ -41,18 +47,21 @@ class Task(LazyLogging):
|
||||
|
||||
_check_output = check_output
|
||||
|
||||
def __init__(self, package: Package, configuration: Configuration, paths: RepositoryPaths) -> None:
|
||||
def __init__(self, package: Package, configuration: Configuration, architecture: str,
|
||||
paths: RepositoryPaths) -> None:
|
||||
"""
|
||||
default constructor
|
||||
|
||||
Args:
|
||||
package(Package): package definitions
|
||||
configuration(Configuration): configuration instance
|
||||
architecture(str): repository architecture
|
||||
paths(RepositoryPaths): repository paths instance
|
||||
"""
|
||||
self.package = package
|
||||
self.paths = paths
|
||||
self.uid, _ = paths.root_owner
|
||||
self.architecture = architecture
|
||||
|
||||
self.archbuild_flags = configuration.getlist("build", "archbuild_flags", fallback=[])
|
||||
self.build_command = configuration.get("build", "build_command")
|
||||
@ -98,12 +107,23 @@ class Task(LazyLogging):
|
||||
).splitlines()
|
||||
return [Path(package) for package in packages]
|
||||
|
||||
def init(self, sources_dir: Path, database: SQLite) -> None:
|
||||
def init(self, sources_dir: Path, database: SQLite, local_version: str | None) -> None:
|
||||
"""
|
||||
fetch package from git
|
||||
|
||||
Args:
|
||||
sources_dir(Path): local path to fetch
|
||||
database(SQLite): database instance
|
||||
local_version(str | None): local version of the package. If set and equal to current version, it will
|
||||
automatically bump pkgrel
|
||||
"""
|
||||
Sources.load(sources_dir, self.package, database.patches_get(self.package.base), self.paths)
|
||||
if local_version is None:
|
||||
return # there is no local package or pkgrel increment is disabled
|
||||
|
||||
# load fresh package
|
||||
loaded_package = Package.from_build(sources_dir, self.architecture, None)
|
||||
if (pkgrel := loaded_package.next_pkgrel(local_version)) is not None:
|
||||
self.logger.info("package %s is the same as in repo, bumping pkgrel to %s", self.package.base, pkgrel)
|
||||
patch = PkgbuildPatch("pkgrel", pkgrel)
|
||||
patch.write(sources_dir / "PKGBUILD")
|
||||
|
@ -25,6 +25,7 @@ from collections.abc import Callable
|
||||
from pathlib import Path
|
||||
from typing import Any, Self
|
||||
|
||||
from ahriman.core.configuration.shell_interpolator import ShellInterpolator
|
||||
from ahriman.core.exceptions import InitializeError
|
||||
from ahriman.models.repository_paths import RepositoryPaths
|
||||
|
||||
@ -48,7 +49,7 @@ class Configuration(configparser.RawConfigParser):
|
||||
|
||||
>>> from pathlib import Path
|
||||
>>>
|
||||
>>> configuration = Configuration.from_path(Path("/etc/ahriman.ini"), "x86_64", quiet=False)
|
||||
>>> configuration = Configuration.from_path(Path("/etc/ahriman.ini"), "x86_64")
|
||||
>>> repository_name = configuration.get("repository", "name")
|
||||
>>> makepkg_flags = configuration.getlist("build", "makepkg_flags")
|
||||
|
||||
@ -73,10 +74,16 @@ class Configuration(configparser.RawConfigParser):
|
||||
allow_no_value(bool, optional): copies ``configparser.RawConfigParser`` behaviour. In case if it is set
|
||||
to ``True``, the keys without values will be allowed (Default value = False)
|
||||
"""
|
||||
configparser.RawConfigParser.__init__(self, allow_no_value=allow_no_value, converters={
|
||||
"list": shlex.split,
|
||||
"path": self._convert_path,
|
||||
})
|
||||
configparser.RawConfigParser.__init__(
|
||||
self,
|
||||
allow_no_value=allow_no_value,
|
||||
interpolation=ShellInterpolator(),
|
||||
converters={
|
||||
"list": shlex.split,
|
||||
"path": self._convert_path,
|
||||
}
|
||||
)
|
||||
|
||||
self.architecture: str | None = None
|
||||
self.path: Path | None = None
|
||||
self.includes: list[Path] = []
|
||||
|
@ -93,9 +93,12 @@ CONFIGURATION_SCHEMA: ConfigurationSchema = {
|
||||
"type": "string",
|
||||
"oneof": [
|
||||
{"allowed": ["disabled"]},
|
||||
{"allowed": ["configuration", "mapping"], "dependencies": ["salt"]},
|
||||
{"allowed": ["configuration", "mapping"]},
|
||||
{"allowed": ["oauth"], "dependencies": [
|
||||
"client_id", "client_secret", "oauth_provider", "oauth_scopes", "salt"
|
||||
"client_id",
|
||||
"client_secret",
|
||||
"oauth_provider",
|
||||
"oauth_scopes",
|
||||
]},
|
||||
],
|
||||
},
|
||||
|
51
src/ahriman/core/configuration/shell_interpolator.py
Normal file
51
src/ahriman/core/configuration/shell_interpolator.py
Normal file
@ -0,0 +1,51 @@
|
||||
#
|
||||
# Copyright (c) 2021-2023 ahriman team.
|
||||
#
|
||||
# This file is part of ahriman
|
||||
# (see https://github.com/arcan1s/ahriman).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import configparser
|
||||
import os
|
||||
|
||||
from collections.abc import Mapping, MutableMapping
|
||||
from string import Template
|
||||
|
||||
|
||||
class ShellInterpolator(configparser.Interpolation):
|
||||
"""
|
||||
custom string interpolator, because we cannot use defaults argument due to config validation
|
||||
"""
|
||||
|
||||
def before_get(self, parser: MutableMapping[str, Mapping[str, str]], section: str, option: str, value: str,
|
||||
defaults: Mapping[str, str]) -> str:
|
||||
"""
|
||||
interpolate option value
|
||||
|
||||
Args:
|
||||
parser(MutableMapping[str, Mapping[str, str]]): option parser
|
||||
section(str): section name
|
||||
option(str): option name
|
||||
value(str): source (not-converted) value
|
||||
defaults(Mapping[str, str]): default values
|
||||
|
||||
Returns:
|
||||
str: substituted value
|
||||
"""
|
||||
# At the moment it seems that it is the most legit way to handle environment variables
|
||||
# Template behaviour is literally the same as shell
|
||||
# In addition, we are using shell-like variables in some cases (see ``alpm.mirror`` option), thus we would like
|
||||
# to keep them alive
|
||||
return Template(value).safe_substitute(os.environ)
|
@ -144,24 +144,6 @@ class Validator(RootValidator):
|
||||
if constraint and url.scheme not in constraint:
|
||||
self._error(field, f"Url {value} scheme must be one of {constraint}")
|
||||
|
||||
def _validate_path_is_absolute(self, constraint: bool, field: str, value: Path) -> None:
|
||||
"""
|
||||
check if path is absolute or not
|
||||
|
||||
Args:
|
||||
constraint(bool): True in case if path must be absolute and False if it must be relative
|
||||
field(str): field name to be checked
|
||||
value(Path): value to be checked
|
||||
|
||||
Examples:
|
||||
The rule's arguments are validated against this schema:
|
||||
{"type": "boolean"}
|
||||
"""
|
||||
if constraint and not value.is_absolute():
|
||||
self._error(field, f"Path {value} must be absolute")
|
||||
if not constraint and value.is_absolute():
|
||||
self._error(field, f"Path {value} must be relative")
|
||||
|
||||
def _validate_path_exists(self, constraint: bool, field: str, value: Path) -> None:
|
||||
"""
|
||||
check if paths exists
|
||||
|
@ -70,6 +70,7 @@ def migrate_package_remotes(connection: Connection, paths: RepositoryPaths) -> N
|
||||
connection(Connection): database connection
|
||||
paths(RepositoryPaths): repository paths instance
|
||||
"""
|
||||
from ahriman.core.alpm.remote import AUR
|
||||
from ahriman.core.database.operations import PackageOperations
|
||||
|
||||
def insert_remote(base: str, remote: RemoteSource) -> None:
|
||||
@ -92,7 +93,11 @@ def migrate_package_remotes(connection: Connection, paths: RepositoryPaths) -> N
|
||||
local_cache = paths.cache_for(package_base)
|
||||
if local_cache.exists() and not package.is_vcs:
|
||||
continue # skip packages which are not VCS and with local cache
|
||||
remote_source = RemoteSource.from_source(PackageSource.AUR, package_base, "aur")
|
||||
if remote_source is None:
|
||||
continue # should never happen
|
||||
remote_source = RemoteSource(
|
||||
source=PackageSource.AUR,
|
||||
git_url=AUR.remote_git_url(package_base, "aur"),
|
||||
web_url=AUR.remote_web_url(package_base),
|
||||
path=".",
|
||||
branch="master",
|
||||
)
|
||||
insert_remote(package_base, remote_source)
|
||||
|
@ -66,7 +66,7 @@ def migrate_package_depends(connection: Connection, configuration: Configuration
|
||||
|
||||
package_list = []
|
||||
for full_path in filter(package_like, configuration.repository_paths.repository.iterdir()):
|
||||
base = Package.from_archive(full_path, pacman, remote=None)
|
||||
base = Package.from_archive(full_path, pacman)
|
||||
for package, description in base.packages.items():
|
||||
package_list.append({
|
||||
"make_depends": description.make_depends,
|
||||
|
@ -63,7 +63,7 @@ def migrate_package_check_depends(connection: Connection, configuration: Configu
|
||||
|
||||
package_list = []
|
||||
for full_path in filter(package_like, configuration.repository_paths.repository.iterdir()):
|
||||
base = Package.from_archive(full_path, pacman, remote=None)
|
||||
base = Package.from_archive(full_path, pacman)
|
||||
for package, description in base.packages.items():
|
||||
package_list.append({
|
||||
"check_depends": description.check_depends,
|
||||
|
@ -69,7 +69,7 @@ def migrate_package_base_packager(connection: Connection, configuration: Configu
|
||||
|
||||
package_list = []
|
||||
for full_path in filter(package_like, configuration.repository_paths.repository.iterdir()):
|
||||
package = Package.from_archive(full_path, pacman, remote=None)
|
||||
package = Package.from_archive(full_path, pacman)
|
||||
package_list.append({
|
||||
"package_base": package.base,
|
||||
"packager": package.packager,
|
||||
|
@ -17,4 +17,11 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
__version__ = "2.10.1"
|
||||
__all__ = ["steps"]
|
||||
|
||||
|
||||
steps = [
|
||||
"""
|
||||
update package_bases set source = 'local' where source is null
|
||||
""",
|
||||
]
|
@ -86,11 +86,11 @@ class PackageOperations(Operations):
|
||||
{
|
||||
"package_base": package.base,
|
||||
"version": package.version,
|
||||
"branch": package.remote.branch if package.remote is not None else None,
|
||||
"git_url": package.remote.git_url if package.remote is not None else None,
|
||||
"path": package.remote.path if package.remote is not None else None,
|
||||
"web_url": package.remote.web_url if package.remote is not None else None,
|
||||
"source": package.remote.source.value if package.remote is not None else None,
|
||||
"branch": package.remote.branch,
|
||||
"git_url": package.remote.git_url,
|
||||
"path": package.remote.path,
|
||||
"web_url": package.remote.web_url,
|
||||
"source": package.remote.source.value,
|
||||
"packager": package.packager,
|
||||
}
|
||||
)
|
||||
@ -270,5 +270,4 @@ class PackageOperations(Operations):
|
||||
return {
|
||||
package_base: package.remote
|
||||
for package_base, package in packages.items()
|
||||
if package.remote is not None
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.exceptions import GitRemoteError
|
||||
from ahriman.core.log import LazyLogging
|
||||
from ahriman.core.util import walk
|
||||
from ahriman.models.package import Package
|
||||
from ahriman.models.package_source import PackageSource
|
||||
from ahriman.models.remote_source import RemoteSource
|
||||
|
||||
@ -36,16 +37,18 @@ class RemotePull(LazyLogging):
|
||||
fetch PKGBUILDs from remote repository and use them for following actions
|
||||
|
||||
Attributes:
|
||||
architecture(str): repository architecture
|
||||
remote_source(RemoteSource): repository remote source (remote pull url and branch)
|
||||
repository_paths(RepositoryPaths): repository paths instance
|
||||
"""
|
||||
|
||||
def __init__(self, configuration: Configuration, section: str) -> None:
|
||||
def __init__(self, configuration: Configuration, architecture: str, section: str) -> None:
|
||||
"""
|
||||
default constructor
|
||||
|
||||
Args:
|
||||
configuration(Configuration): configuration instance
|
||||
architecture(str): repository architecture
|
||||
section(str): settings section name
|
||||
"""
|
||||
self.remote_source = RemoteSource(
|
||||
@ -55,8 +58,30 @@ class RemotePull(LazyLogging):
|
||||
branch=configuration.get(section, "pull_branch", fallback="master"),
|
||||
source=PackageSource.Local,
|
||||
)
|
||||
self.architecture = architecture
|
||||
self.repository_paths = configuration.repository_paths
|
||||
|
||||
def package_copy(self, pkgbuild_path: Path) -> None:
|
||||
"""
|
||||
copy single PKGBUILD content to the repository tree
|
||||
|
||||
Args:
|
||||
pkgbuild_path(Path): path to PKGBUILD to copy
|
||||
"""
|
||||
cloned_pkgbuild_dir = pkgbuild_path.parent
|
||||
|
||||
# load package from the PKGBUILD, because it might be possible that name doesn't match
|
||||
# e.g. if we have just cloned repo with just one PKGBUILD
|
||||
package = Package.from_build(cloned_pkgbuild_dir, self.architecture, None)
|
||||
package_base = package.base
|
||||
local_pkgbuild_dir = self.repository_paths.cache_for(package_base)
|
||||
|
||||
# copy source ignoring the git files
|
||||
shutil.copytree(cloned_pkgbuild_dir, local_pkgbuild_dir,
|
||||
ignore=shutil.ignore_patterns(".git*"), dirs_exist_ok=True)
|
||||
# initialized git repository is required for local sources
|
||||
Sources.init(local_pkgbuild_dir)
|
||||
|
||||
def repo_clone(self) -> None:
|
||||
"""
|
||||
clone repository from remote source
|
||||
@ -74,11 +99,7 @@ class RemotePull(LazyLogging):
|
||||
clone_dir(Path): path to temporary cloned directory
|
||||
"""
|
||||
for pkgbuild_path in filter(lambda path: path.name == "PKGBUILD", walk(clone_dir)):
|
||||
cloned_pkgbuild_dir = pkgbuild_path.parent
|
||||
package_base = cloned_pkgbuild_dir.name
|
||||
local_pkgbuild_dir = self.repository_paths.cache_for(package_base)
|
||||
shutil.copytree(cloned_pkgbuild_dir, local_pkgbuild_dir, dirs_exist_ok=True)
|
||||
Sources.init(local_pkgbuild_dir) # initialized git repository is required for local sources
|
||||
self.package_copy(pkgbuild_path)
|
||||
|
||||
def run(self) -> None:
|
||||
"""
|
||||
|
@ -87,5 +87,5 @@ class RemotePullTrigger(Trigger):
|
||||
for target in self.targets:
|
||||
section, _ = self.configuration.gettype(
|
||||
target, self.architecture, fallback=self.CONFIGURATION_SCHEMA_FALLBACK)
|
||||
runner = RemotePull(self.configuration, section)
|
||||
runner = RemotePull(self.configuration, self.architecture, section)
|
||||
runner.run()
|
||||
|
@ -39,7 +39,7 @@ class RemotePush(LazyLogging):
|
||||
sync PKGBUILDs to remote repository after actions
|
||||
|
||||
Attributes:
|
||||
commit_author(str | None): optional commit author in form of git config (i.e. ``user <user@host>``)
|
||||
commit_author(tuple[str, str] | None): optional commit author in form of git config
|
||||
database(SQLite): database instance
|
||||
remote_source(RemoteSource): repository remote source (remote pull url and branch)
|
||||
"""
|
||||
@ -54,7 +54,11 @@ class RemotePush(LazyLogging):
|
||||
section(str): settings section name
|
||||
"""
|
||||
self.database = database
|
||||
self.commit_author = configuration.get(section, "commit_author", fallback=None)
|
||||
|
||||
commit_email = configuration.get(section, "commit_email", fallback="ahriman@localhost")
|
||||
commit_user = configuration.get(section, "commit_user", fallback="ahriman")
|
||||
self.commit_author = (commit_user, commit_email)
|
||||
|
||||
self.remote_source = RemoteSource(
|
||||
git_url=configuration.get(section, "push_url"),
|
||||
web_url="",
|
||||
@ -79,6 +83,7 @@ class RemotePush(LazyLogging):
|
||||
package_target_dir = target_dir / package.base
|
||||
shutil.rmtree(package_target_dir, ignore_errors=True)
|
||||
# ...secondly, we clone whole tree...
|
||||
# fetch is used intentionally here in order to avoid copying downloaded blobs
|
||||
Sources.fetch(package_target_dir, package.remote)
|
||||
# ...and last, but not least, we remove the dot-git directory...
|
||||
for git_file in package_target_dir.glob(".git*"):
|
||||
|
@ -49,7 +49,10 @@ class RemotePushTrigger(Trigger):
|
||||
"gitremote": {
|
||||
"type": "dict",
|
||||
"schema": {
|
||||
"commit_author": {
|
||||
"commit_email": {
|
||||
"type": "string",
|
||||
},
|
||||
"commit_user": {
|
||||
"type": "string",
|
||||
},
|
||||
"push_url": {
|
||||
|
@ -64,7 +64,8 @@ class Executor(Cleaner):
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def process_build(self, updates: Iterable[Package], packagers: Packagers | None = None) -> Result:
|
||||
def process_build(self, updates: Iterable[Package], packagers: Packagers | None = None, *,
|
||||
bump_pkgrel: bool = False) -> Result:
|
||||
"""
|
||||
build packages
|
||||
|
||||
@ -72,20 +73,23 @@ class Executor(Cleaner):
|
||||
updates(Iterable[Package]): list of packages properties to build
|
||||
packagers(Packagers | None, optional): optional override of username for build process
|
||||
(Default value = None)
|
||||
bump_pkgrel(bool, optional): bump pkgrel in case of local version conflict (Default value = False)
|
||||
|
||||
Returns:
|
||||
Result: build result
|
||||
"""
|
||||
def build_single(package: Package, local_path: Path, packager_id: str | None) -> None:
|
||||
self.reporter.set_building(package.base)
|
||||
task = Task(package, self.configuration, self.paths)
|
||||
task.init(local_path, self.database)
|
||||
task = Task(package, self.configuration, self.architecture, self.paths)
|
||||
local_version = local_versions.get(package.base) if bump_pkgrel else None
|
||||
task.init(local_path, self.database, local_version)
|
||||
built = task.build(local_path, packager_id)
|
||||
for src in built:
|
||||
dst = self.paths.packages / src.name
|
||||
shutil.move(src, dst)
|
||||
|
||||
packagers = packagers or Packagers()
|
||||
local_versions = {package.base: package.version for package in self.packages()}
|
||||
|
||||
result = Result()
|
||||
for single in updates:
|
||||
|
@ -117,8 +117,9 @@ class Repository(Executor, UpdateHandler):
|
||||
# we are iterating over bases, not single packages
|
||||
for full_path in packages:
|
||||
try:
|
||||
local = Package.from_archive(full_path, self.pacman, None)
|
||||
local.remote = sources.get(local.base)
|
||||
local = Package.from_archive(full_path, self.pacman)
|
||||
if (source := sources.get(local.base)) is not None:
|
||||
local.remote = source
|
||||
|
||||
current = result.setdefault(local.base, local)
|
||||
if current.version != local.version:
|
||||
|
@ -24,6 +24,7 @@ from ahriman.core.exceptions import UnknownPackageError
|
||||
from ahriman.core.repository.cleaner import Cleaner
|
||||
from ahriman.models.package import Package
|
||||
from ahriman.models.package_source import PackageSource
|
||||
from ahriman.models.remote_source import RemoteSource
|
||||
|
||||
|
||||
class UpdateHandler(Cleaner):
|
||||
@ -55,12 +56,10 @@ class UpdateHandler(Cleaner):
|
||||
list[Package]: list of packages which are out-of-dated
|
||||
"""
|
||||
def load_remote(package: Package) -> Package:
|
||||
source = package.remote.source if package.remote is not None else None
|
||||
|
||||
# try to load package from base and if none found try to load by separated packages
|
||||
for probe in [package.base] + sorted(package.packages.keys()):
|
||||
try:
|
||||
if source == PackageSource.Repository:
|
||||
if package.remote.source == PackageSource.Repository:
|
||||
return Package.from_official(probe, self.pacman, None)
|
||||
return Package.from_aur(probe, self.pacman, None)
|
||||
except UnknownPackageError:
|
||||
@ -71,6 +70,8 @@ class UpdateHandler(Cleaner):
|
||||
|
||||
for local in self.packages():
|
||||
with self.in_package_context(local.base):
|
||||
if not local.remote.is_remote:
|
||||
continue # avoid checking local packages
|
||||
if local.base in self.ignore_list:
|
||||
continue
|
||||
if filter_packages and local.base not in filter_packages:
|
||||
@ -107,7 +108,15 @@ class UpdateHandler(Cleaner):
|
||||
for cache_dir in self.paths.cache.iterdir():
|
||||
with self.in_package_context(cache_dir.name):
|
||||
try:
|
||||
Sources.fetch(cache_dir, remote=None)
|
||||
source = RemoteSource(
|
||||
source=PackageSource.Local,
|
||||
git_url=cache_dir.absolute().as_uri(),
|
||||
web_url="",
|
||||
path=".",
|
||||
branch="master",
|
||||
)
|
||||
|
||||
Sources.fetch(cache_dir, source)
|
||||
remote = Package.from_build(cache_dir, self.architecture, None)
|
||||
|
||||
local = packages.get(remote.base)
|
||||
|
@ -27,7 +27,6 @@ from multiprocessing import Process, Queue
|
||||
from threading import Lock, Thread
|
||||
|
||||
from ahriman.core.log import LazyLogging
|
||||
from ahriman.models.package_source import PackageSource
|
||||
|
||||
|
||||
class Spawn(Thread, LazyLogging):
|
||||
@ -133,8 +132,7 @@ class Spawn(Thread, LazyLogging):
|
||||
username(str | None): optional override of username for build process
|
||||
now(bool): build packages now
|
||||
"""
|
||||
# avoid abusing by building non-aur packages
|
||||
kwargs = {"source": PackageSource.AUR.value, "username": username}
|
||||
kwargs = {"username": username}
|
||||
if now:
|
||||
kwargs["now"] = ""
|
||||
self._spawn_process("package-add", *packages, **kwargs)
|
||||
|
@ -24,7 +24,7 @@ import requests
|
||||
from collections.abc import Generator
|
||||
from urllib.parse import quote_plus as urlencode
|
||||
|
||||
from ahriman import version
|
||||
from ahriman import __version__
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.log import LazyLogging
|
||||
from ahriman.core.status.client import Client
|
||||
@ -141,11 +141,11 @@ class WebClient(Client, LazyLogging):
|
||||
if use_unix_socket:
|
||||
import requests_unixsocket # type: ignore[import]
|
||||
session: requests.Session = requests_unixsocket.Session()
|
||||
session.headers["User-Agent"] = f"ahriman/{version.__version__}"
|
||||
session.headers["User-Agent"] = f"ahriman/{__version__}"
|
||||
return session
|
||||
|
||||
session = requests.Session()
|
||||
session.headers["User-Agent"] = f"ahriman/{version.__version__}"
|
||||
session.headers["User-Agent"] = f"ahriman/{__version__}"
|
||||
self._login(session)
|
||||
|
||||
return session
|
||||
|
@ -59,8 +59,8 @@ class MirrorlistTrigger(Trigger):
|
||||
"type": "string",
|
||||
},
|
||||
"path": {
|
||||
"type": "string",
|
||||
"path_is_absolute": True,
|
||||
"type": "path",
|
||||
"coerce": "absolute_path",
|
||||
},
|
||||
"servers": {
|
||||
"type": "list",
|
||||
|
@ -79,7 +79,9 @@ class Github(HttpUpload):
|
||||
(url, _) = release["upload_url"].split("{") # it is parametrized url
|
||||
(mime, _) = mimetypes.guess_type(path)
|
||||
headers = {"Content-Type": mime} if mime is not None else {"Content-Type": "application/octet-stream"}
|
||||
self._request("POST", url, params={"name": path.name}, data=path.open("rb"), headers=headers)
|
||||
|
||||
with path.open("rb") as archive:
|
||||
self._request("POST", url, params={"name": path.name}, data=archive, headers=headers)
|
||||
|
||||
def get_local_files(self, path: Path) -> dict[Path, str]:
|
||||
"""
|
||||
|
@ -25,6 +25,7 @@ import logging
|
||||
import os
|
||||
import re
|
||||
import requests
|
||||
import selectors
|
||||
import subprocess
|
||||
|
||||
from collections.abc import Callable, Generator, Iterable
|
||||
@ -48,6 +49,7 @@ __all__ = [
|
||||
"filter_json",
|
||||
"full_version",
|
||||
"package_like",
|
||||
"parse_version",
|
||||
"partition",
|
||||
"pretty_datetime",
|
||||
"pretty_size",
|
||||
@ -107,15 +109,24 @@ def check_output(*args: str, exception: Exception | None = None, cwd: Path | Non
|
||||
channel: IO[str] | None = getattr(proc, channel_name, None)
|
||||
return channel if channel is not None else io.StringIO()
|
||||
|
||||
def log(single: str) -> None:
|
||||
if logger is not None:
|
||||
logger.debug(single)
|
||||
# wrapper around selectors polling
|
||||
def poll(sel: selectors.BaseSelector) -> Generator[str, None, None]:
|
||||
for key, _ in sel.select(): # we don't need to check mask here because we have only subscribed on reading
|
||||
line = key.fileobj.readline() # type: ignore[union-attr]
|
||||
if not line: # in case of empty line we remove selector as there is no data here anymore
|
||||
sel.unregister(key.fileobj)
|
||||
continue
|
||||
line = line.rstrip()
|
||||
|
||||
if logger is not None:
|
||||
logger.debug(line)
|
||||
|
||||
if key.data == "stdout":
|
||||
yield line # yield only stdout data
|
||||
|
||||
environment = environment or {}
|
||||
if user is not None:
|
||||
environment["HOME"] = getpwuid(user).pw_dir
|
||||
# FIXME additional workaround for linter and type check which do not know that user arg is supported
|
||||
# pylint: disable=unexpected-keyword-arg
|
||||
with subprocess.Popen(args, cwd=cwd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||
user=user, env=environment, text=True, encoding="utf8", bufsize=1) as process:
|
||||
if input_data is not None:
|
||||
@ -123,16 +134,13 @@ def check_output(*args: str, exception: Exception | None = None, cwd: Path | Non
|
||||
input_channel.write(input_data)
|
||||
input_channel.close()
|
||||
|
||||
# read stdout and append to output result
|
||||
result: list[str] = []
|
||||
for line in iter(get_io(process, "stdout").readline, ""):
|
||||
line = line.strip()
|
||||
result.append(line)
|
||||
log(line)
|
||||
selector = selectors.DefaultSelector()
|
||||
selector.register(get_io(process, "stdout"), selectors.EVENT_READ, data="stdout")
|
||||
selector.register(get_io(process, "stderr"), selectors.EVENT_READ, data="stderr")
|
||||
|
||||
# read stderr and write info to logs
|
||||
for line in iter(get_io(process, "stderr").readline, ""):
|
||||
log(line.strip())
|
||||
result: list[str] = []
|
||||
while selector.get_map(): # while there are unread selectors, keep reading
|
||||
result.extend(poll(selector))
|
||||
|
||||
process.terminate() # make sure that process is terminated
|
||||
status_code = process.wait()
|
||||
@ -275,9 +283,28 @@ def package_like(filename: Path) -> bool:
|
||||
return ".pkg." in name and not name.endswith(".sig")
|
||||
|
||||
|
||||
def parse_version(version: str) -> tuple[str | None, str, str]:
|
||||
"""
|
||||
parse version and returns its components
|
||||
|
||||
Args:
|
||||
version(str): full version string
|
||||
|
||||
Returns:
|
||||
tuple[str | None, str, str]: epoch if any, pkgver and pkgrel variables
|
||||
"""
|
||||
if ":" in version:
|
||||
epoch, version = version.split(":", maxsplit=1)
|
||||
else:
|
||||
epoch = None
|
||||
pkgver, pkgrel = version.rsplit("-", maxsplit=1)
|
||||
|
||||
return epoch, pkgver, pkgrel
|
||||
|
||||
|
||||
def partition(source: list[T], predicate: Callable[[T], bool]) -> tuple[list[T], list[T]]:
|
||||
"""
|
||||
partition list into two based on predicate, based on # https://docs.python.org/dev/library/itertools.html#itertools-recipes
|
||||
partition list into two based on predicate, based on https://docs.python.org/dev/library/itertools.html#itertools-recipes
|
||||
|
||||
Args:
|
||||
source(list[T]): source list to be partitioned
|
||||
|
@ -66,13 +66,12 @@ class AURPackage:
|
||||
>>> package = AURPackage.from_repo(metadata) # load package from official repository RPC
|
||||
>>> # properties of the class are built based on ones from AUR RPC, thus additional method is required
|
||||
>>>
|
||||
>>>
|
||||
>>> from ahriman.core.alpm.pacman import Pacman
|
||||
>>> from ahriman.core.configuration import Configuration
|
||||
>>>
|
||||
>>> configuration = Configuration()
|
||||
>>> pacman = Pacman("x86_64", configuration)
|
||||
>>> metadata = pacman.get("pacman")
|
||||
>>> metadata = pacman.package_get("pacman")
|
||||
>>> package = AURPackage.from_pacman(next(metadata)) # load package from pyalpm wrapper
|
||||
"""
|
||||
|
||||
|
@ -34,7 +34,7 @@ from ahriman.core.alpm.pacman import Pacman
|
||||
from ahriman.core.alpm.remote import AUR, Official, OfficialSyncdb
|
||||
from ahriman.core.exceptions import PackageInfoError
|
||||
from ahriman.core.log import LazyLogging
|
||||
from ahriman.core.util import check_output, dataclass_view, full_version, srcinfo_property_list, utcnow
|
||||
from ahriman.core.util import check_output, dataclass_view, full_version, parse_version, srcinfo_property_list, utcnow
|
||||
from ahriman.models.package_description import PackageDescription
|
||||
from ahriman.models.package_source import PackageSource
|
||||
from ahriman.models.remote_source import RemoteSource
|
||||
@ -51,7 +51,7 @@ class Package(LazyLogging):
|
||||
packager(str | None): package packager if available
|
||||
packages(dict[str, PackageDescription): map of package names to their properties.
|
||||
Filled only on load from archive
|
||||
remote(RemoteSource | None): package remote source if applicable
|
||||
remote(RemoteSource): package remote source if applicable
|
||||
version(str): package full version
|
||||
|
||||
Examples:
|
||||
@ -61,7 +61,7 @@ class Package(LazyLogging):
|
||||
|
||||
it will contain every data available in the json body. Otherwise, if generate package from local archive::
|
||||
|
||||
>>> package = Package.from_archive(local_path, pacman, remote=None)
|
||||
>>> package = Package.from_archive(local_path, pacman)
|
||||
|
||||
it will probably miss file descriptions (in case if there are multiple packages which belong to the base).
|
||||
|
||||
@ -76,7 +76,7 @@ class Package(LazyLogging):
|
||||
|
||||
base: str
|
||||
version: str
|
||||
remote: RemoteSource | None
|
||||
remote: RemoteSource
|
||||
packages: dict[str, PackageDescription]
|
||||
packager: str | None = None
|
||||
|
||||
@ -192,22 +192,26 @@ class Package(LazyLogging):
|
||||
return sorted(packages)
|
||||
|
||||
@classmethod
|
||||
def from_archive(cls, path: Path, pacman: Pacman, remote: RemoteSource | None) -> Self:
|
||||
def from_archive(cls, path: Path, pacman: Pacman) -> Self:
|
||||
"""
|
||||
construct package properties from package archive
|
||||
|
||||
Args:
|
||||
path(Path): path to package archive
|
||||
pacman(Pacman): alpm wrapper instance
|
||||
remote(RemoteSource): package remote source if applicable
|
||||
|
||||
Returns:
|
||||
Self: package properties
|
||||
"""
|
||||
package = pacman.handle.load_pkg(str(path))
|
||||
description = PackageDescription.from_package(package, path)
|
||||
return cls(base=package.base, version=package.version, remote=remote, packages={package.name: description},
|
||||
packager=package.packager)
|
||||
return cls(
|
||||
base=package.base,
|
||||
version=package.version,
|
||||
remote=RemoteSource(source=PackageSource.Archive),
|
||||
packages={package.name: description},
|
||||
packager=package.packager,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_aur(cls, name: str, pacman: Pacman, packager: str | None = None) -> Self:
|
||||
@ -223,7 +227,15 @@ class Package(LazyLogging):
|
||||
Self: package properties
|
||||
"""
|
||||
package = AUR.info(name, pacman=pacman)
|
||||
remote = RemoteSource.from_source(PackageSource.AUR, package.package_base, package.repository)
|
||||
|
||||
remote = RemoteSource(
|
||||
source=PackageSource.AUR,
|
||||
git_url=AUR.remote_git_url(package.package_base, package.repository),
|
||||
web_url=AUR.remote_web_url(package.package_base),
|
||||
path=".",
|
||||
branch="master",
|
||||
)
|
||||
|
||||
return cls(
|
||||
base=package.package_base,
|
||||
version=package.version,
|
||||
@ -265,14 +277,20 @@ class Package(LazyLogging):
|
||||
version = full_version(srcinfo.get("epoch"), srcinfo["pkgver"], srcinfo["pkgrel"])
|
||||
|
||||
remote = RemoteSource(
|
||||
source=PackageSource.Local,
|
||||
git_url=path.absolute().as_uri(),
|
||||
web_url="",
|
||||
web_url=None,
|
||||
path=".",
|
||||
branch="master",
|
||||
source=PackageSource.Local,
|
||||
)
|
||||
|
||||
return cls(base=srcinfo["pkgbase"], version=version, remote=remote, packages=packages, packager=packager)
|
||||
return cls(
|
||||
base=srcinfo["pkgbase"],
|
||||
version=version,
|
||||
remote=remote,
|
||||
packages=packages,
|
||||
packager=packager,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, dump: dict[str, Any]) -> Self:
|
||||
@ -291,8 +309,13 @@ class Package(LazyLogging):
|
||||
for key, value in packages_json.items()
|
||||
}
|
||||
remote = dump.get("remote") or {}
|
||||
return cls(base=dump["base"], version=dump["version"], remote=RemoteSource.from_json(remote), packages=packages,
|
||||
packager=dump.get("packager"))
|
||||
return cls(
|
||||
base=dump["base"],
|
||||
version=dump["version"],
|
||||
remote=RemoteSource.from_json(remote),
|
||||
packages=packages,
|
||||
packager=dump.get("packager"),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_official(cls, name: str, pacman: Pacman, packager: str | None = None, *, use_syncdb: bool = True) -> Self:
|
||||
@ -309,7 +332,15 @@ class Package(LazyLogging):
|
||||
Self: package properties
|
||||
"""
|
||||
package = OfficialSyncdb.info(name, pacman=pacman) if use_syncdb else Official.info(name, pacman=pacman)
|
||||
remote = RemoteSource.from_source(PackageSource.Repository, package.package_base, package.repository)
|
||||
|
||||
remote = RemoteSource(
|
||||
source=PackageSource.Repository,
|
||||
git_url=Official.remote_git_url(package.package_base, package.repository),
|
||||
web_url=Official.remote_web_url(package.package_base),
|
||||
path=".",
|
||||
branch="main",
|
||||
)
|
||||
|
||||
return cls(
|
||||
base=package.package_base,
|
||||
version=package.version,
|
||||
@ -507,6 +538,35 @@ class Package(LazyLogging):
|
||||
result: int = vercmp(self.version, remote_version)
|
||||
return result < 0
|
||||
|
||||
def next_pkgrel(self, local_version: str) -> str | None:
|
||||
"""
|
||||
generate next pkgrel variable. The package release will be incremented if ``local_version`` is more or equal to
|
||||
the ``Package.version``; in this case the function will return new pkgrel value, otherwise ``None`` will be
|
||||
returned
|
||||
|
||||
Args:
|
||||
local_version(str): locally stored package version
|
||||
|
||||
Returns:
|
||||
str | None: new generated package release version if any. In case if the release contains dot (e.g. 1.2),
|
||||
the minor part will be incremented by 1. If the release does not contain major.minor notation, the minor version
|
||||
equals to 1 will be appended
|
||||
"""
|
||||
epoch, pkgver, _ = parse_version(self.version)
|
||||
local_epoch, local_pkgver, local_pkgrel = parse_version(local_version)
|
||||
|
||||
if epoch != local_epoch or pkgver != local_pkgver:
|
||||
return None # epoch or pkgver are different, keep upstream pkgrel
|
||||
if vercmp(self.version, local_version) > 0:
|
||||
return None # upstream version is newer than local one, keep upstream pkgrel
|
||||
|
||||
if "." in local_pkgrel:
|
||||
major, minor = local_pkgrel.rsplit(".", maxsplit=1)
|
||||
else:
|
||||
major, minor = local_pkgrel, "0"
|
||||
|
||||
return f"{major}.{int(minor) + 1}"
|
||||
|
||||
def pretty_print(self) -> str:
|
||||
"""
|
||||
generate pretty string representation
|
||||
|
@ -53,14 +53,13 @@ class PackageDescription:
|
||||
|
||||
>>> description = PackageDescription.from_json(dump)
|
||||
>>>
|
||||
>>>
|
||||
>>> from pathlib import Path
|
||||
>>> from ahriman.core.alpm.pacman import Pacman
|
||||
>>> from ahriman.core.configuration import Configuration
|
||||
>>>
|
||||
>>> configuration = Configuration()
|
||||
>>> pacman = Pacman("x86_64", configuration)
|
||||
>>> pyalpm_description = next(package for package in pacman.get("pacman"))
|
||||
>>> pyalpm_description = next(package for package in pacman.package_get("pacman"))
|
||||
>>> description = PackageDescription.from_package(
|
||||
>>> pyalpm_description, Path("/var/cache/pacman/pkg/pacman-6.0.1-4-x86_64.pkg.tar.zst"))
|
||||
"""
|
||||
|
@ -24,6 +24,7 @@ from pathlib import Path
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from ahriman.core.util import package_like
|
||||
from ahriman.models.repository_paths import RepositoryPaths
|
||||
|
||||
|
||||
class PackageSource(str, Enum):
|
||||
@ -42,7 +43,7 @@ class PackageSource(str, Enum):
|
||||
Examples:
|
||||
In case if source is unknown the ``resolve()`` and the source descriptor is available method must be used::
|
||||
|
||||
>>> real_source = PackageSource.Auto.resolve("ahriman")
|
||||
>>> real_source = PackageSource.Auto.resolve("ahriman", configuration.repository_paths)
|
||||
|
||||
the code above will ensure that the presudo-source ``PackageSource.Auto`` will not be processed later.
|
||||
"""
|
||||
@ -55,12 +56,13 @@ class PackageSource(str, Enum):
|
||||
Remote = "remote"
|
||||
Repository = "repository"
|
||||
|
||||
def resolve(self, source: str) -> PackageSource:
|
||||
def resolve(self, source: str, paths: RepositoryPaths) -> PackageSource:
|
||||
"""
|
||||
resolve auto into the correct type
|
||||
|
||||
Args:
|
||||
source(str): source of the package
|
||||
paths(RepositoryPaths): repository paths instance
|
||||
|
||||
Returns:
|
||||
PackageSource: non-auto type of the package source
|
||||
@ -74,7 +76,7 @@ class PackageSource(str, Enum):
|
||||
if maybe_url.scheme and maybe_url.scheme not in ("data", "file") and package_like(maybe_path):
|
||||
return PackageSource.Remote
|
||||
try:
|
||||
if (maybe_path / "PKGBUILD").is_file():
|
||||
if (maybe_path / "PKGBUILD").is_file() or paths.cache_for(source).is_dir():
|
||||
return PackageSource.Local
|
||||
if maybe_path.is_dir():
|
||||
return PackageSource.Directory
|
||||
|
@ -21,6 +21,7 @@ from dataclasses import dataclass, fields
|
||||
from pathlib import Path
|
||||
from typing import Any, Self
|
||||
|
||||
from ahriman.core.exceptions import InitializeError
|
||||
from ahriman.core.util import dataclass_view, filter_json
|
||||
from ahriman.models.package_source import PackageSource
|
||||
|
||||
@ -31,18 +32,18 @@ class RemoteSource:
|
||||
remote package source properties
|
||||
|
||||
Attributes:
|
||||
branch(str): branch of the git repository
|
||||
git_url(str): url of the git repository
|
||||
path(str): path to directory with PKGBUILD inside the git repository
|
||||
branch(str | None): branch of the git repository
|
||||
git_url(str | None): url of the git repository
|
||||
path(str | None): path to directory with PKGBUILD inside the git repository
|
||||
source(PackageSource): package source pointer used by some parsers
|
||||
web_url(str): url of the package in the web interface
|
||||
web_url(str | None): url of the package in the web interface
|
||||
"""
|
||||
|
||||
git_url: str
|
||||
web_url: str
|
||||
path: str
|
||||
branch: str
|
||||
source: PackageSource
|
||||
git_url: str | None = None
|
||||
web_url: str | None = None
|
||||
path: str | None = None
|
||||
branch: str | None = None
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
"""
|
||||
@ -51,17 +52,27 @@ class RemoteSource:
|
||||
object.__setattr__(self, "source", PackageSource(self.source))
|
||||
|
||||
@property
|
||||
def pkgbuild_dir(self) -> Path:
|
||||
def is_remote(self) -> bool:
|
||||
"""
|
||||
check if source is remote
|
||||
|
||||
Returns:
|
||||
bool: True in case if package is well-known remote source (e.g. AUR) and False otherwise
|
||||
"""
|
||||
return self.source in (PackageSource.AUR, PackageSource.Repository)
|
||||
|
||||
@property
|
||||
def pkgbuild_dir(self) -> Path | None:
|
||||
"""
|
||||
get path to directory with package sources (PKGBUILD etc)
|
||||
|
||||
Returns:
|
||||
Path: path to directory with package sources based on settings
|
||||
Path | None: path to directory with package sources based on settings if available
|
||||
"""
|
||||
return Path(self.path)
|
||||
return Path(self.path) if self.path is not None else None
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, dump: dict[str, Any]) -> Self | None:
|
||||
def from_json(cls, dump: dict[str, Any]) -> Self:
|
||||
"""
|
||||
construct remote source from the json dump (or database row)
|
||||
|
||||
@ -69,47 +80,25 @@ class RemoteSource:
|
||||
dump(dict[str, Any]): json dump body
|
||||
|
||||
Returns:
|
||||
Self | None: remote source
|
||||
Self: remote source
|
||||
"""
|
||||
# filter to only known fields
|
||||
known_fields = [pair.name for pair in fields(cls)]
|
||||
dump = filter_json(dump, known_fields)
|
||||
if dump:
|
||||
return cls(**dump)
|
||||
return None
|
||||
return cls(**filter_json(dump, known_fields))
|
||||
|
||||
@classmethod
|
||||
def from_source(cls, source: PackageSource, package_base: str, repository: str) -> Self | None:
|
||||
def git_source(self) -> tuple[str, str]:
|
||||
"""
|
||||
generate remote source from the package base
|
||||
|
||||
Args:
|
||||
source(PackageSource): source of the package
|
||||
package_base(str): package base
|
||||
repository(str): repository name
|
||||
get git source if available
|
||||
|
||||
Returns:
|
||||
Self | None: generated remote source if any, None otherwise
|
||||
tuple[str, str]: git url and branch
|
||||
|
||||
Raises:
|
||||
InitializeError: in case if git url and/or branch are not set
|
||||
"""
|
||||
if source == PackageSource.AUR:
|
||||
from ahriman.core.alpm.remote import AUR
|
||||
return cls(
|
||||
git_url=AUR.remote_git_url(package_base, repository),
|
||||
web_url=AUR.remote_web_url(package_base),
|
||||
path=".",
|
||||
branch="master",
|
||||
source=source,
|
||||
)
|
||||
if source == PackageSource.Repository:
|
||||
from ahriman.core.alpm.remote import Official
|
||||
return cls(
|
||||
git_url=Official.remote_git_url(package_base, repository),
|
||||
web_url=Official.remote_web_url(package_base),
|
||||
path=".",
|
||||
branch="main",
|
||||
source=source,
|
||||
)
|
||||
return None
|
||||
if self.git_url is None or self.branch is None:
|
||||
raise InitializeError("Remote source is empty")
|
||||
return self.git_url, self.branch
|
||||
|
||||
def view(self) -> dict[str, Any]:
|
||||
"""
|
||||
|
@ -17,9 +17,9 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from secrets import token_urlsafe as generate_password
|
||||
from dataclasses import dataclass, replace
|
||||
from passlib.hash import sha512_crypt
|
||||
from passlib.pwd import genword as generate_password
|
||||
from typing import Self
|
||||
|
||||
from ahriman.models.user_access import UserAccess
|
||||
@ -41,7 +41,7 @@ class User:
|
||||
Simply create user from database data and perform required validation::
|
||||
|
||||
>>> password = User.generate_password(24)
|
||||
>>> user = User(username="ahriman", password=password, access=UserAccess.Full, packager_id=None, key=None)
|
||||
>>> user = User(username="ahriman", password=password, access=UserAccess.Full)
|
||||
|
||||
Since the password supplied may be plain text, the ``hash_password`` method can be used to hash the password::
|
||||
|
||||
@ -63,8 +63,8 @@ class User:
|
||||
username: str
|
||||
password: str
|
||||
access: UserAccess
|
||||
packager_id: str | None
|
||||
key: str | None
|
||||
packager_id: str | None = None
|
||||
key: str | None = None
|
||||
|
||||
_HASHER = sha512_crypt
|
||||
|
||||
@ -104,8 +104,7 @@ class User:
|
||||
Returns:
|
||||
str: random string which contains letters and numbers
|
||||
"""
|
||||
password: str = generate_password(length=length)
|
||||
return password
|
||||
return generate_password(length)[:length]
|
||||
|
||||
def check_credentials(self, password: str, salt: str) -> bool:
|
||||
"""
|
||||
|
@ -22,7 +22,7 @@ import aiohttp_apispec # type: ignore[import]
|
||||
from aiohttp.web import Application
|
||||
from typing import Any
|
||||
|
||||
from ahriman import version
|
||||
from ahriman import __version__
|
||||
from ahriman.core.configuration import Configuration
|
||||
|
||||
|
||||
@ -48,6 +48,7 @@ def _info() -> dict[str, Any]:
|
||||
* VCS packages support.
|
||||
* Official repository support.
|
||||
* Ability to patch AUR packages and even create package from local PKGBUILDs.
|
||||
* Various rebuild options with ability to automatically bump package version.
|
||||
* Sign support with gpg (repository, package), multiple packagers support.
|
||||
* Triggers for repository updates, e.g. synchronization to remote services (rsync, s3 and github) and report generation (email, html, telegram).
|
||||
* Repository status interface with optional authorization and control options.
|
||||
@ -58,7 +59,7 @@ def _info() -> dict[str, Any]:
|
||||
"name": "GPL3",
|
||||
"url": "https://raw.githubusercontent.com/arcan1s/ahriman/master/COPYING",
|
||||
},
|
||||
"version": version.__version__,
|
||||
"version": __version__,
|
||||
}
|
||||
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
#
|
||||
from marshmallow import Schema, fields
|
||||
|
||||
from ahriman import version
|
||||
from ahriman import __version__
|
||||
from ahriman.web.schemas.counters_schema import CountersSchema
|
||||
from ahriman.web.schemas.status_schema import StatusSchema
|
||||
|
||||
@ -45,5 +45,5 @@ class InternalStatusSchema(Schema):
|
||||
})
|
||||
version = fields.String(required=True, metadata={
|
||||
"description": "Repository version",
|
||||
"example": version.__version__,
|
||||
"example": __version__,
|
||||
})
|
||||
|
@ -19,7 +19,7 @@
|
||||
#
|
||||
from marshmallow import Schema, fields
|
||||
|
||||
from ahriman import version
|
||||
from ahriman import __version__
|
||||
from ahriman.web.schemas.package_properties_schema import PackagePropertiesSchema
|
||||
from ahriman.web.schemas.remote_schema import RemoteSchema
|
||||
|
||||
@ -35,7 +35,7 @@ class PackageSchema(Schema):
|
||||
})
|
||||
version = fields.String(required=True, metadata={
|
||||
"description": "Package version",
|
||||
"example": version.__version__,
|
||||
"example": __version__,
|
||||
})
|
||||
remote = fields.Nested(RemoteSchema(), required=True, metadata={
|
||||
"description": "Package remote properties",
|
||||
|
@ -27,22 +27,22 @@ class RemoteSchema(Schema):
|
||||
request and response package remote schema
|
||||
"""
|
||||
|
||||
branch = fields.String(required=True, metadata={
|
||||
branch = fields.String(metadata={
|
||||
"description": "Repository branch",
|
||||
"example": "master",
|
||||
})
|
||||
git_url = fields.String(required=True, metadata={
|
||||
git_url = fields.String(metadata={
|
||||
"description": "Package git url",
|
||||
"example": "https://aur.archlinux.org/ahriman.git",
|
||||
})
|
||||
path = fields.String(required=True, metadata={
|
||||
path = fields.String(metadata={
|
||||
"description": "Path to package sources in git repository",
|
||||
"example": ".",
|
||||
})
|
||||
source = fields.Enum(PackageSource, by_value=True, required=True, metadata={
|
||||
"description": "Pacakge source",
|
||||
})
|
||||
web_url = fields.String(required=True, metadata={
|
||||
web_url = fields.String(metadata={
|
||||
"description": "Package repository page",
|
||||
"example": "https://aur.archlinux.org/packages/ahriman",
|
||||
})
|
||||
|
@ -21,7 +21,7 @@ import aiohttp_apispec # type: ignore[import]
|
||||
|
||||
from aiohttp.web import HTTPBadRequest, HTTPNoContent, Response, json_response
|
||||
|
||||
from ahriman import version
|
||||
from ahriman import __version__
|
||||
from ahriman.models.build_status import BuildStatusEnum
|
||||
from ahriman.models.counters import Counters
|
||||
from ahriman.models.internal_status import InternalStatus
|
||||
@ -68,7 +68,8 @@ class StatusView(BaseView):
|
||||
architecture=self.service.architecture,
|
||||
packages=counters,
|
||||
repository=self.service.repository.name,
|
||||
version=version.__version__)
|
||||
version=__version__,
|
||||
)
|
||||
|
||||
return json_response(status.view())
|
||||
|
||||
|
@ -86,7 +86,11 @@ def test_with_dependencies(application: Application, package_ahriman: Package, p
|
||||
"python-installer": create_package_mock("python-installer"),
|
||||
}
|
||||
|
||||
package_mock = mocker.patch("ahriman.models.package.Package.from_aur", side_effect=lambda *args: packages[args[0]])
|
||||
mocker.patch("pathlib.Path.is_dir", autospec=True, side_effect=lambda p: p.name == "python")
|
||||
package_aur_mock = mocker.patch("ahriman.models.package.Package.from_aur",
|
||||
side_effect=lambda *args: packages[args[0]])
|
||||
package_local_mock = mocker.patch("ahriman.models.package.Package.from_build",
|
||||
side_effect=lambda *args: packages[args[0].name])
|
||||
packages_mock = mocker.patch("ahriman.application.application.Application._known_packages",
|
||||
return_value={"devtools", "python-build", "python-pytest"})
|
||||
update_remote_mock = mocker.patch("ahriman.core.database.SQLite.remote_update")
|
||||
@ -94,11 +98,13 @@ def test_with_dependencies(application: Application, package_ahriman: Package, p
|
||||
|
||||
result = application.with_dependencies([package_ahriman], process_dependencies=True)
|
||||
assert {package.base: package for package in result} == packages
|
||||
package_mock.assert_has_calls([
|
||||
package_aur_mock.assert_has_calls([
|
||||
MockCall(package_python_schedule.base, application.repository.pacman, package_ahriman.packager),
|
||||
MockCall("python", application.repository.pacman, package_ahriman.packager),
|
||||
MockCall("python-installer", application.repository.pacman, package_ahriman.packager),
|
||||
], any_order=True)
|
||||
package_local_mock.assert_has_calls([
|
||||
MockCall(application.repository.paths.cache_for("python"), "x86_64", package_ahriman.packager),
|
||||
], any_order=True)
|
||||
packages_mock.assert_called_once_with()
|
||||
|
||||
update_remote_mock.assert_has_calls([
|
||||
|
@ -86,7 +86,9 @@ def test_add_local(application_packages: ApplicationPackages, package_ahriman: P
|
||||
application_packages._add_local(package_ahriman.base, "packager")
|
||||
is_dir_mock.assert_called_once_with()
|
||||
copytree_mock.assert_called_once_with(
|
||||
Path(package_ahriman.base), application_packages.repository.paths.cache_for(package_ahriman.base))
|
||||
Path(package_ahriman.base),
|
||||
application_packages.repository.paths.cache_for(package_ahriman.base),
|
||||
dirs_exist_ok=True)
|
||||
init_mock.assert_called_once_with(application_packages.repository.paths.cache_for(package_ahriman.base))
|
||||
build_queue_mock.assert_called_once_with(package_ahriman)
|
||||
|
||||
|
@ -6,6 +6,7 @@ from unittest.mock import call as MockCall
|
||||
from ahriman.application.application.application_repository import ApplicationRepository
|
||||
from ahriman.core.tree import Leaf, Tree
|
||||
from ahriman.models.package import Package
|
||||
from ahriman.models.packagers import Packagers
|
||||
from ahriman.models.result import Result
|
||||
|
||||
|
||||
@ -170,9 +171,12 @@ def test_update(application_repository: ApplicationRepository, package_ahriman:
|
||||
on_result_mock = mocker.patch(
|
||||
"ahriman.application.application.application_repository.ApplicationRepository.on_result")
|
||||
|
||||
application_repository.update([package_ahriman], "username")
|
||||
build_mock.assert_called_once_with([package_ahriman], "username")
|
||||
update_mock.assert_has_calls([MockCall(paths, "username"), MockCall(paths, "username")])
|
||||
application_repository.update([package_ahriman], Packagers("username"), bump_pkgrel=True)
|
||||
build_mock.assert_called_once_with([package_ahriman], Packagers("username"), bump_pkgrel=True)
|
||||
update_mock.assert_has_calls([
|
||||
MockCall(paths, Packagers("username")),
|
||||
MockCall(paths, Packagers("username")),
|
||||
])
|
||||
on_result_mock.assert_has_calls([MockCall(result), MockCall(result)])
|
||||
|
||||
|
||||
|
@ -24,6 +24,7 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace:
|
||||
"""
|
||||
args.package = []
|
||||
args.exit_code = False
|
||||
args.increment = True
|
||||
args.now = False
|
||||
args.refresh = 0
|
||||
args.source = PackageSource.Auto
|
||||
@ -70,7 +71,8 @@ def test_run_with_updates(args: argparse.Namespace, configuration: Configuration
|
||||
Add.run(args, "x86_64", configuration, report=False)
|
||||
updates_mock.assert_called_once_with(args.package, aur=False, local=False, manual=True, vcs=False)
|
||||
application_mock.assert_called_once_with([package_ahriman],
|
||||
Packagers(args.username, {package_ahriman.base: "packager"}))
|
||||
Packagers(args.username, {package_ahriman.base: "packager"}),
|
||||
bump_pkgrel=args.increment)
|
||||
dependencies_mock.assert_called_once_with([package_ahriman], process_dependencies=args.dependencies)
|
||||
check_mock.assert_called_once_with(False, False)
|
||||
print_mock.assert_called_once_with([package_ahriman], log_fn=pytest.helpers.anyvar(int))
|
||||
|
@ -27,6 +27,7 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace:
|
||||
args.dry_run = False
|
||||
args.from_database = False
|
||||
args.exit_code = False
|
||||
args.increment = True
|
||||
args.status = None
|
||||
args.username = "username"
|
||||
return args
|
||||
@ -51,7 +52,7 @@ def test_run(args: argparse.Namespace, package_ahriman: Package, configuration:
|
||||
Rebuild.run(args, "x86_64", configuration, report=False)
|
||||
extract_mock.assert_called_once_with(pytest.helpers.anyvar(int), args.status, from_database=args.from_database)
|
||||
application_packages_mock.assert_called_once_with([package_ahriman], None)
|
||||
application_mock.assert_called_once_with([package_ahriman], args.username)
|
||||
application_mock.assert_called_once_with([package_ahriman], args.username, bump_pkgrel=args.increment)
|
||||
check_mock.assert_has_calls([MockCall(False, False), MockCall(False, False)])
|
||||
on_start_mock.assert_called_once_with()
|
||||
|
||||
|
@ -2,7 +2,7 @@ import argparse
|
||||
|
||||
from pytest_mock import MockerFixture
|
||||
|
||||
from ahriman import version
|
||||
from ahriman import __version__
|
||||
from ahriman.application.handlers import ServiceUpdates
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.repository import Repository
|
||||
@ -46,7 +46,7 @@ def test_run_skip(args: argparse.Namespace, configuration: Configuration, reposi
|
||||
"""
|
||||
must do not perform any actions if package is up-to-date
|
||||
"""
|
||||
package_ahriman.version = f"{version.__version__}-1"
|
||||
package_ahriman.version = f"{__version__}-1"
|
||||
args = _default_args(args)
|
||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||
mocker.patch("ahriman.models.package.Package.from_aur", return_value=package_ahriman)
|
||||
|
@ -58,9 +58,11 @@ def test_run_verbose(args: argparse.Namespace, configuration: Configuration, rep
|
||||
args = _default_args(args)
|
||||
args.verbose = True
|
||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
||||
read_mock = mocker.patch("pathlib.Path.read_text", return_value="")
|
||||
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
||||
application_mock = mocker.patch("code.interact")
|
||||
|
||||
Shell.run(args, "x86_64", configuration, report=False)
|
||||
application_mock.assert_called_once_with(local=pytest.helpers.anyvar(int))
|
||||
read_mock.assert_called_once_with(encoding="utf8")
|
||||
print_mock.assert_called_once_with(verbose=False)
|
||||
|
@ -27,6 +27,7 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace:
|
||||
args.dependencies = True
|
||||
args.dry_run = False
|
||||
args.exit_code = False
|
||||
args.increment = True
|
||||
args.aur = True
|
||||
args.local = True
|
||||
args.manual = True
|
||||
@ -55,7 +56,8 @@ def test_run(args: argparse.Namespace, package_ahriman: Package, configuration:
|
||||
|
||||
Update.run(args, "x86_64", configuration, report=False)
|
||||
application_mock.assert_called_once_with([package_ahriman],
|
||||
Packagers(args.username, {package_ahriman.base: "packager"}))
|
||||
Packagers(args.username, {package_ahriman.base: "packager"}),
|
||||
bump_pkgrel=args.increment)
|
||||
updates_mock.assert_called_once_with(args.package, aur=args.aur, local=args.local, manual=args.manual, vcs=args.vcs)
|
||||
dependencies_mock.assert_called_once_with([package_ahriman], process_dependencies=args.dependencies)
|
||||
check_mock.assert_has_calls([MockCall(False, False), MockCall(False, False)])
|
||||
|
@ -54,16 +54,19 @@ def test_run(args: argparse.Namespace, configuration: Configuration, database: S
|
||||
|
||||
def test_run_empty_salt(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must raise exception if salt is required, but not set
|
||||
must process users with empty password salt
|
||||
"""
|
||||
configuration.remove_option("auth", "salt")
|
||||
args = _default_args(args)
|
||||
user = User(username=args.username, password=args.password, access=args.role,
|
||||
packager_id=args.packager, key=args.key)
|
||||
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)
|
||||
update_mock = mocker.patch("ahriman.core.database.SQLite.user_update")
|
||||
|
||||
with pytest.raises(configparser.NoOptionError):
|
||||
Users.run(args, "x86_64", configuration, report=False)
|
||||
Users.run(args, "x86_64", configuration, report=False)
|
||||
create_user_mock.assert_called_once_with(args)
|
||||
update_mock.assert_called_once_with(user)
|
||||
|
||||
|
||||
def test_run_empty_salt_without_password(args: argparse.Namespace, configuration: Configuration, database: SQLite,
|
||||
|
@ -3,6 +3,7 @@ import argparse
|
||||
from pathlib import Path
|
||||
from pytest_mock import MockerFixture
|
||||
|
||||
from ahriman.application import ahriman
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.models.action import Action
|
||||
from ahriman.models.build_status import BuildStatusEnum
|
||||
@ -822,10 +823,6 @@ def test_run(args: argparse.Namespace, mocker: MockerFixture) -> None:
|
||||
args.architecture = "x86_64"
|
||||
args.handler = Handler
|
||||
|
||||
from ahriman.application import ahriman
|
||||
mocker.patch.object(ahriman, "__name__", "__main__")
|
||||
mocker.patch("argparse.ArgumentParser.parse_args", return_value=args)
|
||||
exit_mock = mocker.patch("sys.exit")
|
||||
|
||||
ahriman.run()
|
||||
exit_mock.assert_called_once_with(1)
|
||||
assert ahriman.run() == 1
|
||||
|
@ -6,7 +6,7 @@ from pathlib import Path
|
||||
from pytest_mock import MockerFixture
|
||||
from unittest.mock import call as MockCall
|
||||
|
||||
from ahriman import version
|
||||
from ahriman import __version__
|
||||
from ahriman.application.lock import Lock
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.exceptions import DuplicateRunError, UnsafeRunError
|
||||
@ -33,7 +33,7 @@ def test_check_version(lock: Lock, mocker: MockerFixture) -> None:
|
||||
must check version correctly
|
||||
"""
|
||||
mocker.patch("ahriman.core.status.client.Client.get_internal",
|
||||
return_value=InternalStatus(status=BuildStatus(), version=version.__version__))
|
||||
return_value=InternalStatus(status=BuildStatus(), version=__version__))
|
||||
logging_mock = mocker.patch("logging.Logger.warning")
|
||||
|
||||
lock.check_version()
|
||||
|
@ -7,6 +7,7 @@ from typing import Any, TypeVar
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from ahriman.core.alpm.pacman import Pacman
|
||||
from ahriman.core.alpm.remote import AUR
|
||||
from ahriman.core.auth import Auth
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.database import SQLite
|
||||
@ -314,7 +315,13 @@ def package_python_schedule(
|
||||
return Package(
|
||||
base="python-schedule",
|
||||
version="1.0.0-2",
|
||||
remote=RemoteSource.from_source(PackageSource.AUR, "python-schedule", "aur"),
|
||||
remote=RemoteSource(
|
||||
source=PackageSource.AUR,
|
||||
git_url=AUR.remote_git_url("python-schedule", "aur"),
|
||||
web_url=AUR.remote_web_url("python-schedule"),
|
||||
path=".",
|
||||
branch="master",
|
||||
),
|
||||
packages=packages)
|
||||
|
||||
|
||||
@ -451,7 +458,13 @@ def remote_source() -> RemoteSource:
|
||||
Returns:
|
||||
RemoteSource: remote source test instance
|
||||
"""
|
||||
return RemoteSource.from_source(PackageSource.AUR, "ahriman", "aur")
|
||||
return RemoteSource(
|
||||
source=PackageSource.AUR,
|
||||
git_url=AUR.remote_git_url("ahriman", "aur"),
|
||||
web_url=AUR.remote_web_url("ahriman"),
|
||||
path=".",
|
||||
branch="master",
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
@ -8,6 +8,7 @@ from unittest.mock import MagicMock
|
||||
|
||||
from ahriman.core.alpm.pacman import Pacman
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.models.pacman_synchronization import PacmanSynchronization
|
||||
from ahriman.models.repository_paths import RepositoryPaths
|
||||
|
||||
|
||||
@ -23,7 +24,7 @@ def test_init_with_local_cache(configuration: Configuration, mocker: MockerFixtu
|
||||
with TemporaryDirectory(ignore_cleanup_errors=True) as pacman_root:
|
||||
mocker.patch.object(RepositoryPaths, "pacman", Path(pacman_root))
|
||||
# during the creation pyalpm.Handle will create also version file which we would like to remove later
|
||||
pacman = Pacman("x86_64", configuration, refresh_database=1)
|
||||
pacman = Pacman("x86_64", configuration, refresh_database=PacmanSynchronization.Enabled)
|
||||
assert pacman.handle
|
||||
sync_mock.assert_called_once_with(pytest.helpers.anyvar(int), force=False)
|
||||
|
||||
@ -40,7 +41,7 @@ def test_init_with_local_cache_forced(configuration: Configuration, mocker: Mock
|
||||
with TemporaryDirectory(ignore_cleanup_errors=True) as pacman_root:
|
||||
mocker.patch.object(RepositoryPaths, "pacman", Path(pacman_root))
|
||||
# during the creation pyalpm.Handle will create also version file which we would like to remove later
|
||||
pacman = Pacman("x86_64", configuration, refresh_database=2)
|
||||
pacman = Pacman("x86_64", configuration, refresh_database=PacmanSynchronization.Force)
|
||||
assert pacman.handle
|
||||
sync_mock.assert_called_once_with(pytest.helpers.anyvar(int), force=True)
|
||||
|
||||
@ -54,7 +55,7 @@ def test_database_copy(pacman: Pacman, repository_paths: RepositoryPaths, mocker
|
||||
dst_path = Path("/var/lib/pacman/sync/core.db")
|
||||
mocker.patch("pathlib.Path.is_dir", return_value=True)
|
||||
# root database exists, local database does not
|
||||
mocker.patch("pathlib.Path.is_file", autospec=True, side_effect=lambda p: True if p.is_relative_to(path) else False)
|
||||
mocker.patch("pathlib.Path.is_file", autospec=True, side_effect=lambda p: p.is_relative_to(path))
|
||||
copy_mock = mocker.patch("shutil.copy")
|
||||
chown_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.chown")
|
||||
|
||||
@ -71,7 +72,7 @@ def test_database_copy_skip(pacman: Pacman, repository_paths: RepositoryPaths, m
|
||||
path = Path("randomname")
|
||||
mocker.patch("pathlib.Path.is_dir", return_value=True)
|
||||
# root database exists, local database does not
|
||||
mocker.patch("pathlib.Path.is_file", autospec=True, side_effect=lambda p: True if p.is_relative_to(path) else False)
|
||||
mocker.patch("pathlib.Path.is_file", autospec=True, side_effect=lambda p: p.is_relative_to(path))
|
||||
copy_mock = mocker.patch("shutil.copy")
|
||||
|
||||
pacman.database_copy(pacman.handle, database, path, repository_paths, use_ahriman_cache=False)
|
||||
@ -86,7 +87,7 @@ def test_database_copy_no_directory(pacman: Pacman, repository_paths: Repository
|
||||
path = Path("randomname")
|
||||
mocker.patch("pathlib.Path.is_dir", return_value=False)
|
||||
# root database exists, local database does not
|
||||
mocker.patch("pathlib.Path.is_file", autospec=True, side_effect=lambda p: True if p.is_relative_to(path) else False)
|
||||
mocker.patch("pathlib.Path.is_file", autospec=True, side_effect=lambda p: p.is_relative_to(path))
|
||||
copy_mock = mocker.patch("shutil.copy")
|
||||
|
||||
pacman.database_copy(pacman.handle, database, path, repository_paths, use_ahriman_cache=True)
|
||||
|
@ -6,6 +6,7 @@ from unittest.mock import call as MockCall
|
||||
|
||||
from ahriman.core.build_tools.sources import Sources
|
||||
from ahriman.models.package import Package
|
||||
from ahriman.models.package_source import PackageSource
|
||||
from ahriman.models.pkgbuild_patch import PkgbuildPatch
|
||||
from ahriman.models.remote_source import RemoteSource
|
||||
from ahriman.models.repository_paths import RepositoryPaths
|
||||
@ -92,7 +93,7 @@ def test_fetch_new_without_remote(mocker: MockerFixture) -> None:
|
||||
move_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.move")
|
||||
|
||||
local = Path("local")
|
||||
Sources.fetch(local, None)
|
||||
Sources.fetch(local, RemoteSource(source=PackageSource.Archive))
|
||||
check_output_mock.assert_has_calls([
|
||||
MockCall("git", "checkout", "--force", Sources.DEFAULT_BRANCH, cwd=local, logger=pytest.helpers.anyvar(int)),
|
||||
MockCall("git", "reset", "--hard", f"origin/{Sources.DEFAULT_BRANCH}",
|
||||
@ -136,6 +137,7 @@ def test_init(mocker: MockerFixture) -> None:
|
||||
must create empty repository at the specified path
|
||||
"""
|
||||
mocker.patch("ahriman.models.package.Package.local_files", return_value=[Path("local")])
|
||||
mocker.patch("pathlib.Path.is_dir", return_value=False)
|
||||
add_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.add")
|
||||
check_output_mock = mocker.patch("ahriman.core.build_tools.sources.Sources._check_output")
|
||||
commit_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.commit")
|
||||
@ -145,7 +147,21 @@ def test_init(mocker: MockerFixture) -> None:
|
||||
check_output_mock.assert_called_once_with("git", "init", "--initial-branch", Sources.DEFAULT_BRANCH,
|
||||
cwd=local, logger=pytest.helpers.anyvar(int))
|
||||
add_mock.assert_called_once_with(local, "PKGBUILD", ".SRCINFO", "local")
|
||||
commit_mock.assert_called_once_with(local, author="ahriman <ahriman@localhost>")
|
||||
commit_mock.assert_called_once_with(local)
|
||||
|
||||
|
||||
def test_init_skip(mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must skip git init if it was already
|
||||
"""
|
||||
mocker.patch("ahriman.models.package.Package.local_files", return_value=[Path("local")])
|
||||
mocker.patch("pathlib.Path.is_dir", return_value=True)
|
||||
mocker.patch("ahriman.core.build_tools.sources.Sources.add")
|
||||
mocker.patch("ahriman.core.build_tools.sources.Sources.commit")
|
||||
check_output_mock = mocker.patch("ahriman.core.build_tools.sources.Sources._check_output")
|
||||
|
||||
Sources.init(Path("local"))
|
||||
check_output_mock.assert_not_called()
|
||||
|
||||
|
||||
def test_load(package_ahriman: Package, repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
|
||||
@ -216,19 +232,31 @@ def test_push(package_ahriman: Package, mocker: MockerFixture) -> None:
|
||||
must correctly push files to remote repository
|
||||
"""
|
||||
add_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.add")
|
||||
commit_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.commit")
|
||||
commit_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.commit", return_value=True)
|
||||
check_output_mock = mocker.patch("ahriman.core.build_tools.sources.Sources._check_output")
|
||||
|
||||
author = "commit author <user@host>"
|
||||
commit_author = ("commit author", "user@host")
|
||||
local = Path("local")
|
||||
Sources.push(Path("local"), package_ahriman.remote, "glob", commit_author=author)
|
||||
Sources.push(local, package_ahriman.remote, "glob", commit_author=commit_author)
|
||||
add_mock.assert_called_once_with(local, "glob")
|
||||
commit_mock.assert_called_once_with(local, author=author)
|
||||
commit_mock.assert_called_once_with(local, commit_author=commit_author)
|
||||
check_output_mock.assert_called_once_with(
|
||||
"git", "push", package_ahriman.remote.git_url, package_ahriman.remote.branch,
|
||||
cwd=local, logger=pytest.helpers.anyvar(int))
|
||||
|
||||
|
||||
def test_push_skipped(package_ahriman: Package, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must skip push if no changes were committed
|
||||
"""
|
||||
mocker.patch("ahriman.core.build_tools.sources.Sources.add")
|
||||
mocker.patch("ahriman.core.build_tools.sources.Sources.commit", return_value=False)
|
||||
check_output_mock = mocker.patch("ahriman.core.build_tools.sources.Sources._check_output")
|
||||
|
||||
Sources.push(Path("local"), package_ahriman.remote)
|
||||
check_output_mock.assert_not_called()
|
||||
|
||||
|
||||
def test_add(sources: Sources, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must add files to git
|
||||
@ -274,29 +302,54 @@ def test_commit(sources: Sources, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must commit changes
|
||||
"""
|
||||
mocker.patch("ahriman.core.build_tools.sources.Sources.has_changes", return_value=True)
|
||||
check_output_mock = mocker.patch("ahriman.core.build_tools.sources.Sources._check_output")
|
||||
|
||||
local = Path("local")
|
||||
message = "Commit message"
|
||||
sources.commit(local, message=message)
|
||||
user, email = sources.DEFAULT_COMMIT_AUTHOR
|
||||
assert sources.commit(local, message=message)
|
||||
check_output_mock.assert_called_once_with(
|
||||
"git", "commit", "--allow-empty", "--message", message, cwd=local, logger=pytest.helpers.anyvar(int)
|
||||
"git", "commit", "--message", message,
|
||||
cwd=local, logger=pytest.helpers.anyvar(int), environment={
|
||||
"GIT_AUTHOR_NAME": user,
|
||||
"GIT_AUTHOR_EMAIL": email,
|
||||
"GIT_COMMITTER_NAME": user,
|
||||
"GIT_COMMITTER_EMAIL": email,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def test_commit_no_changes(sources: Sources, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must skip commit if there are no changes
|
||||
"""
|
||||
mocker.patch("ahriman.core.build_tools.sources.Sources.has_changes", return_value=False)
|
||||
check_output_mock = mocker.patch("ahriman.core.build_tools.sources.Sources._check_output")
|
||||
|
||||
assert not sources.commit(Path("local"))
|
||||
check_output_mock.assert_not_called()
|
||||
|
||||
|
||||
def test_commit_author(sources: Sources, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must commit changes with commit author
|
||||
"""
|
||||
mocker.patch("ahriman.core.build_tools.sources.Sources.has_changes", return_value=True)
|
||||
check_output_mock = mocker.patch("ahriman.core.build_tools.sources.Sources._check_output")
|
||||
|
||||
local = Path("local")
|
||||
message = "Commit message"
|
||||
author = "commit author <user@host>"
|
||||
sources.commit(Path("local"), message=message, author=author)
|
||||
user, email = author = ("commit author", "user@host")
|
||||
assert sources.commit(Path("local"), message=message, commit_author=author)
|
||||
check_output_mock.assert_called_once_with(
|
||||
"git", "commit", "--allow-empty", "--message", message, "--author", author,
|
||||
cwd=local, logger=pytest.helpers.anyvar(int)
|
||||
"git", "commit", "--message", message,
|
||||
cwd=local, logger=pytest.helpers.anyvar(int), environment={
|
||||
"GIT_AUTHOR_NAME": user,
|
||||
"GIT_AUTHOR_EMAIL": email,
|
||||
"GIT_COMMITTER_NAME": user,
|
||||
"GIT_COMMITTER_EMAIL": email,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@ -304,13 +357,20 @@ def test_commit_autogenerated_message(sources: Sources, mocker: MockerFixture) -
|
||||
"""
|
||||
must commit changes with autogenerated commit message
|
||||
"""
|
||||
mocker.patch("ahriman.core.build_tools.sources.Sources.has_changes", return_value=True)
|
||||
check_output_mock = mocker.patch("ahriman.core.build_tools.sources.Sources._check_output")
|
||||
|
||||
local = Path("local")
|
||||
sources.commit(Path("local"))
|
||||
assert sources.commit(Path("local"))
|
||||
user, email = sources.DEFAULT_COMMIT_AUTHOR
|
||||
check_output_mock.assert_called_once_with(
|
||||
"git", "commit", "--allow-empty", "--message", pytest.helpers.anyvar(str, strict=True),
|
||||
cwd=local, logger=pytest.helpers.anyvar(int)
|
||||
"git", "commit", "--message", pytest.helpers.anyvar(str, strict=True),
|
||||
cwd=local, logger=pytest.helpers.anyvar(int), environment={
|
||||
"GIT_AUTHOR_NAME": user,
|
||||
"GIT_AUTHOR_EMAIL": email,
|
||||
"GIT_COMMITTER_NAME": user,
|
||||
"GIT_COMMITTER_EMAIL": email,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@ -325,6 +385,23 @@ def test_diff(sources: Sources, mocker: MockerFixture) -> None:
|
||||
check_output_mock.assert_called_once_with("git", "diff", cwd=local, logger=pytest.helpers.anyvar(int))
|
||||
|
||||
|
||||
def test_has_changes(sources: Sources, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must correctly identify if there are changes
|
||||
"""
|
||||
local = Path("local")
|
||||
|
||||
check_output_mock = mocker.patch("ahriman.core.build_tools.sources.Sources._check_output", return_value="M a.txt")
|
||||
assert sources.has_changes(local)
|
||||
check_output_mock.assert_called_once_with("git", "diff", "--cached", "--name-only",
|
||||
cwd=local, logger=pytest.helpers.anyvar(int))
|
||||
|
||||
check_output_mock = mocker.patch("ahriman.core.build_tools.sources.Sources._check_output", return_value="")
|
||||
assert not sources.has_changes(local)
|
||||
check_output_mock.assert_called_once_with("git", "diff", "--cached", "--name-only",
|
||||
cwd=local, logger=pytest.helpers.anyvar(int))
|
||||
|
||||
|
||||
def test_move(sources: Sources, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must move content between directories
|
||||
|
@ -18,6 +18,32 @@ def test_init(task_ahriman: Task, database: SQLite, mocker: MockerFixture) -> No
|
||||
"""
|
||||
must copy tree instead of fetch
|
||||
"""
|
||||
mocker.patch("ahriman.models.package.Package.from_build", return_value=task_ahriman.package)
|
||||
load_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.load")
|
||||
task_ahriman.init(Path("ahriman"), database)
|
||||
task_ahriman.init(Path("ahriman"), database, None)
|
||||
load_mock.assert_called_once_with(Path("ahriman"), task_ahriman.package, [], task_ahriman.paths)
|
||||
|
||||
|
||||
def test_init_bump_pkgrel(task_ahriman: Task, database: SQLite, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must bump pkgrel if it is same as provided
|
||||
"""
|
||||
mocker.patch("ahriman.models.package.Package.from_build", return_value=task_ahriman.package)
|
||||
mocker.patch("ahriman.core.build_tools.sources.Sources.load")
|
||||
write_mock = mocker.patch("ahriman.models.pkgbuild_patch.PkgbuildPatch.write")
|
||||
|
||||
local = Path("ahriman")
|
||||
task_ahriman.init(local, database, task_ahriman.package.version)
|
||||
write_mock.assert_called_once_with(local / "PKGBUILD")
|
||||
|
||||
|
||||
def test_init_bump_pkgrel_skip(task_ahriman: Task, database: SQLite, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must keep pkgrel if version is different from provided
|
||||
"""
|
||||
mocker.patch("ahriman.models.package.Package.from_build", return_value=task_ahriman.package)
|
||||
mocker.patch("ahriman.core.build_tools.sources.Sources.load")
|
||||
write_mock = mocker.patch("ahriman.models.pkgbuild_patch.PkgbuildPatch.write")
|
||||
|
||||
task_ahriman.init(Path("ahriman"), database, f"2:{task_ahriman.package.version}")
|
||||
write_mock.assert_not_called()
|
||||
|
15
tests/ahriman/core/configuration/test_shell_interpolator.py
Normal file
15
tests/ahriman/core/configuration/test_shell_interpolator.py
Normal file
@ -0,0 +1,15 @@
|
||||
import os
|
||||
|
||||
from ahriman.core.configuration.shell_interpolator import ShellInterpolator
|
||||
|
||||
|
||||
def test_before_get() -> None:
|
||||
"""
|
||||
must correctly extract environment variables
|
||||
"""
|
||||
interpolator = ShellInterpolator()
|
||||
|
||||
assert interpolator.before_get({}, "", "", "value", {}) == "value"
|
||||
assert interpolator.before_get({}, "", "", "$value", {}) == "$value"
|
||||
assert interpolator.before_get({}, "", "", "$HOME", {}) == os.environ["HOME"]
|
||||
assert interpolator.before_get({}, "", "", "$$HOME", {}) == "$HOME"
|
@ -73,30 +73,6 @@ def test_validate_is_ip_address(validator: Validator, mocker: MockerFixture) ->
|
||||
])
|
||||
|
||||
|
||||
def test_validate_path_is_absolute(validator: Validator, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must validate that path is absolute
|
||||
"""
|
||||
error_mock = mocker.patch("ahriman.core.configuration.validator.Validator._error")
|
||||
|
||||
mocker.patch("pathlib.Path.is_absolute", return_value=False)
|
||||
validator._validate_path_is_absolute(False, "field", Path("1"))
|
||||
|
||||
mocker.patch("pathlib.Path.is_absolute", return_value=True)
|
||||
validator._validate_path_is_absolute(False, "field", Path("2"))
|
||||
|
||||
mocker.patch("pathlib.Path.is_absolute", return_value=False)
|
||||
validator._validate_path_is_absolute(True, "field", Path("3"))
|
||||
|
||||
mocker.patch("pathlib.Path.is_absolute", return_value=True)
|
||||
validator._validate_path_is_absolute(True, "field", Path("4"))
|
||||
|
||||
error_mock.assert_has_calls([
|
||||
MockCall("field", "Path 2 must be relative"),
|
||||
MockCall("field", "Path 3 must be absolute"),
|
||||
])
|
||||
|
||||
|
||||
def test_validate_is_url(validator: Validator, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must validate url correctly
|
||||
|
@ -91,4 +91,4 @@ def task_ahriman(package_ahriman: Package, configuration: Configuration, reposit
|
||||
Returns:
|
||||
Task: built task test instance
|
||||
"""
|
||||
return Task(package_ahriman, configuration, repository_paths)
|
||||
return Task(package_ahriman, configuration, "x86_64", repository_paths)
|
||||
|
@ -66,18 +66,3 @@ def test_migrate_package_remotes_vcs(package_ahriman: Package, connection: Conne
|
||||
|
||||
migrate_package_remotes(connection, repository_paths)
|
||||
connection.execute.assert_called_once_with(pytest.helpers.anyvar(str, strict=True), pytest.helpers.anyvar(int))
|
||||
|
||||
|
||||
def test_migrate_package_remotes_no_remotes(package_ahriman: Package, connection: Connection,
|
||||
repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must skip processing in case if no remotes generated (should never happen)
|
||||
"""
|
||||
mocker.patch(
|
||||
"ahriman.core.database.operations.PackageOperations._packages_get_select_package_bases",
|
||||
return_value={package_ahriman.base: package_ahriman})
|
||||
mocker.patch("pathlib.Path.exists", return_value=False)
|
||||
mocker.patch("ahriman.models.remote_source.RemoteSource.from_source", return_value=None)
|
||||
|
||||
migrate_package_remotes(connection, repository_paths)
|
||||
connection.execute.assert_not_called()
|
||||
|
@ -35,7 +35,7 @@ def test_migrate_package_depends(connection: Connection, configuration: Configur
|
||||
|
||||
migrate_package_depends(connection, configuration)
|
||||
package_mock.assert_called_once_with(
|
||||
package_ahriman.packages[package_ahriman.base].filepath, pytest.helpers.anyvar(int), remote=None)
|
||||
package_ahriman.packages[package_ahriman.base].filepath, pytest.helpers.anyvar(int))
|
||||
connection.executemany.assert_called_once_with(pytest.helpers.anyvar(str, strict=True), [{
|
||||
"make_depends": package_ahriman.packages[package_ahriman.base].make_depends,
|
||||
"opt_depends": package_ahriman.packages[package_ahriman.base].opt_depends,
|
||||
|
@ -35,7 +35,7 @@ def test_migrate_package_depends(connection: Connection, configuration: Configur
|
||||
|
||||
migrate_package_check_depends(connection, configuration)
|
||||
package_mock.assert_called_once_with(
|
||||
package_ahriman.packages[package_ahriman.base].filepath, pytest.helpers.anyvar(int), remote=None)
|
||||
package_ahriman.packages[package_ahriman.base].filepath, pytest.helpers.anyvar(int))
|
||||
connection.executemany.assert_called_once_with(pytest.helpers.anyvar(str, strict=True), [{
|
||||
"check_depends": package_ahriman.packages[package_ahriman.base].check_depends,
|
||||
"package": package_ahriman.base,
|
||||
|
@ -35,7 +35,7 @@ def test_migrate_package_base_packager(connection: Connection, configuration: Co
|
||||
|
||||
migrate_package_base_packager(connection, configuration)
|
||||
package_mock.assert_called_once_with(
|
||||
package_ahriman.packages[package_ahriman.base].filepath, pytest.helpers.anyvar(int), remote=None)
|
||||
package_ahriman.packages[package_ahriman.base].filepath, pytest.helpers.anyvar(int))
|
||||
connection.executemany.assert_called_once_with(pytest.helpers.anyvar(str, strict=True), [{
|
||||
"package_base": package_ahriman.base,
|
||||
"packager": package_ahriman.packager,
|
||||
|
@ -0,0 +1,8 @@
|
||||
from ahriman.core.database.migrations.m009_local_source import steps
|
||||
|
||||
|
||||
def test_migration_packagers() -> None:
|
||||
"""
|
||||
migration must not be empty
|
||||
"""
|
||||
assert steps
|
@ -193,7 +193,7 @@ def test_remote_update_update(database: SQLite, package_ahriman: Package) -> Non
|
||||
must perform package remote update for existing package
|
||||
"""
|
||||
database.remote_update(package_ahriman)
|
||||
remote_source = RemoteSource.from_source(PackageSource.Repository, package_ahriman.base, "community")
|
||||
remote_source = RemoteSource(source=PackageSource.Repository)
|
||||
package_ahriman.remote = remote_source
|
||||
|
||||
database.remote_update(package_ahriman)
|
||||
|
@ -2,7 +2,7 @@ import pytest
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from ahriman.core.formatters import AurPrinter, ConfigurationPrinter, ConfigurationPathsPrinter, PackagePrinter,\
|
||||
from ahriman.core.formatters import AurPrinter, ConfigurationPrinter, ConfigurationPathsPrinter, PackagePrinter, \
|
||||
PatchPrinter, StatusPrinter, StringPrinter, TreePrinter, UpdatePrinter, UserPrinter, ValidationPrinter, \
|
||||
VersionPrinter
|
||||
from ahriman.models.aur_package import AURPackage
|
||||
|
@ -7,6 +7,7 @@ from unittest.mock import call as MockCall
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.exceptions import GitRemoteError
|
||||
from ahriman.core.gitremote.remote_pull import RemotePull
|
||||
from ahriman.models.package import Package
|
||||
|
||||
|
||||
def test_repo_clone(configuration: Configuration, mocker: MockerFixture) -> None:
|
||||
@ -15,36 +16,53 @@ def test_repo_clone(configuration: Configuration, mocker: MockerFixture) -> None
|
||||
"""
|
||||
fetch_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.fetch")
|
||||
copy_mock = mocker.patch("ahriman.core.gitremote.remote_pull.RemotePull.repo_copy")
|
||||
runner = RemotePull(configuration, "gitremote")
|
||||
runner = RemotePull(configuration, "x86_64", "gitremote")
|
||||
|
||||
runner.repo_clone()
|
||||
fetch_mock.assert_called_once_with(pytest.helpers.anyvar(int), runner.remote_source)
|
||||
copy_mock.assert_called_once_with(pytest.helpers.anyvar(int))
|
||||
|
||||
|
||||
def test_package_copy(configuration: Configuration, package_ahriman: Package, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must copy single package
|
||||
"""
|
||||
package_mock = mocker.patch("ahriman.models.package.Package.from_build", return_value=package_ahriman)
|
||||
patterns = object()
|
||||
ignore_patterns_mock = mocker.patch("shutil.ignore_patterns", return_value=patterns)
|
||||
copytree_mock = mocker.patch("shutil.copytree")
|
||||
init_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.init")
|
||||
runner = RemotePull(configuration, "x86_64", "gitremote")
|
||||
local = Path("local")
|
||||
|
||||
runner.package_copy(local / "PKGBUILD")
|
||||
package_mock.assert_called_once_with(local, "x86_64", None)
|
||||
ignore_patterns_mock.assert_called_once_with(".git*")
|
||||
copytree_mock.assert_called_once_with(
|
||||
local, configuration.repository_paths.cache_for(package_ahriman.base),
|
||||
ignore=patterns, dirs_exist_ok=True)
|
||||
init_mock.assert_called_once_with(configuration.repository_paths.cache_for(package_ahriman.base))
|
||||
|
||||
|
||||
def test_repo_copy(configuration: Configuration, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must copy repository tree from temporary directory to the local cache
|
||||
"""
|
||||
local = Path("local")
|
||||
mocker.patch("ahriman.core.gitremote.remote_pull.walk", return_value=[
|
||||
Path("local") / "package1" / "PKGBUILD",
|
||||
Path("local") / "package1" / ".SRCINFO",
|
||||
Path("local") / "package2" / ".SRCINFO",
|
||||
Path("local") / "package3" / "PKGBUILD",
|
||||
Path("local") / "package3" / ".SRCINFO",
|
||||
local / "package1" / "PKGBUILD",
|
||||
local / "package1" / ".SRCINFO",
|
||||
local / "package2" / ".SRCINFO",
|
||||
local / "package3" / "PKGBUILD",
|
||||
local / "package3" / ".SRCINFO",
|
||||
])
|
||||
copytree_mock = mocker.patch("shutil.copytree")
|
||||
init_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.init")
|
||||
runner = RemotePull(configuration, "gitremote")
|
||||
copy_mock = mocker.patch("ahriman.core.gitremote.remote_pull.RemotePull.package_copy")
|
||||
runner = RemotePull(configuration, "x86_64", "gitremote")
|
||||
|
||||
runner.repo_copy(Path("local"))
|
||||
copytree_mock.assert_has_calls([
|
||||
MockCall(Path("local") / "package1", configuration.repository_paths.cache_for("package1"), dirs_exist_ok=True),
|
||||
MockCall(Path("local") / "package3", configuration.repository_paths.cache_for("package3"), dirs_exist_ok=True),
|
||||
])
|
||||
init_mock.assert_has_calls([
|
||||
MockCall(configuration.repository_paths.cache_for("package1")),
|
||||
MockCall(configuration.repository_paths.cache_for("package3")),
|
||||
runner.repo_copy(local)
|
||||
copy_mock.assert_has_calls([
|
||||
MockCall(local / "package1" / "PKGBUILD"),
|
||||
MockCall(local / "package3" / "PKGBUILD"),
|
||||
])
|
||||
|
||||
|
||||
@ -53,7 +71,7 @@ def test_run(configuration: Configuration, mocker: MockerFixture) -> None:
|
||||
must clone repo on run
|
||||
"""
|
||||
clone_mock = mocker.patch("ahriman.core.gitremote.remote_pull.RemotePull.repo_clone")
|
||||
runner = RemotePull(configuration, "gitremote")
|
||||
runner = RemotePull(configuration, "x86_64", "gitremote")
|
||||
|
||||
runner.run()
|
||||
clone_mock.assert_called_once_with()
|
||||
@ -64,7 +82,7 @@ def test_run_failed(configuration: Configuration, mocker: MockerFixture) -> None
|
||||
must reraise exception on error occurred
|
||||
"""
|
||||
mocker.patch("ahriman.core.gitremote.remote_pull.RemotePull.repo_clone", side_effect=Exception())
|
||||
runner = RemotePull(configuration, "gitremote")
|
||||
runner = RemotePull(configuration, "x86_64", "gitremote")
|
||||
|
||||
with pytest.raises(GitRemoteError):
|
||||
runner.run()
|
||||
|
@ -30,22 +30,41 @@ def test_process_build(executor: Executor, package_ahriman: Package, mocker: Moc
|
||||
"""
|
||||
must run build process
|
||||
"""
|
||||
mocker.patch("ahriman.core.repository.executor.Executor.packages", return_value=[package_ahriman])
|
||||
mocker.patch("ahriman.core.build_tools.task.Task.build", return_value=[Path(package_ahriman.base)])
|
||||
mocker.patch("ahriman.core.build_tools.task.Task.init")
|
||||
init_mock = mocker.patch("ahriman.core.build_tools.task.Task.init")
|
||||
move_mock = mocker.patch("shutil.move")
|
||||
status_client_mock = mocker.patch("ahriman.core.status.client.Client.set_building")
|
||||
|
||||
executor.process_build([package_ahriman], Packagers("packager"))
|
||||
executor.process_build([package_ahriman], Packagers("packager"), bump_pkgrel=False)
|
||||
init_mock.assert_called_once_with(pytest.helpers.anyvar(int), pytest.helpers.anyvar(int), None)
|
||||
# must move files (once)
|
||||
move_mock.assert_called_once_with(Path(package_ahriman.base), executor.paths.packages / package_ahriman.base)
|
||||
# must update status
|
||||
status_client_mock.assert_called_once_with(package_ahriman.base)
|
||||
|
||||
|
||||
def test_process_build_bump_pkgrel(executor: Executor, package_ahriman: Package, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must run build process and pass current package version to build tools
|
||||
"""
|
||||
mocker.patch("ahriman.core.repository.executor.Executor.packages", return_value=[package_ahriman])
|
||||
mocker.patch("ahriman.core.build_tools.task.Task.build", return_value=[Path(package_ahriman.base)])
|
||||
mocker.patch("shutil.move")
|
||||
mocker.patch("ahriman.core.status.client.Client.set_building")
|
||||
init_mock = mocker.patch("ahriman.core.build_tools.task.Task.init")
|
||||
|
||||
executor.process_build([package_ahriman], Packagers("packager"), bump_pkgrel=True)
|
||||
init_mock.assert_called_once_with(pytest.helpers.anyvar(int),
|
||||
pytest.helpers.anyvar(int),
|
||||
package_ahriman.version)
|
||||
|
||||
|
||||
def test_process_build_failure(executor: Executor, package_ahriman: Package, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must run correct process failed builds
|
||||
"""
|
||||
mocker.patch("ahriman.core.repository.executor.Executor.packages", return_value=[package_ahriman])
|
||||
mocker.patch("ahriman.core.repository.executor.Executor.packages_built")
|
||||
mocker.patch("ahriman.core.build_tools.task.Task.build", return_value=[Path(package_ahriman.base)])
|
||||
mocker.patch("ahriman.core.build_tools.task.Task.init")
|
||||
|
@ -11,6 +11,8 @@ from ahriman.core.repository import Repository
|
||||
from ahriman.core.sign.gpg import GPG
|
||||
from ahriman.models.context_key import ContextKey
|
||||
from ahriman.models.package import Package
|
||||
from ahriman.models.package_source import PackageSource
|
||||
from ahriman.models.remote_source import RemoteSource
|
||||
|
||||
|
||||
def test_load(configuration: Configuration, database: SQLite, mocker: MockerFixture) -> None:
|
||||
@ -51,6 +53,9 @@ def test_load_archives(package_ahriman: Package, package_python_schedule: Packag
|
||||
for package, props in package_python_schedule.packages.items()
|
||||
] + [package_ahriman]
|
||||
mocker.patch("ahriman.models.package.Package.from_archive", side_effect=single_packages)
|
||||
mocker.patch("ahriman.core.database.SQLite.remotes_get", return_value={
|
||||
package_ahriman.base: package_ahriman.base
|
||||
})
|
||||
|
||||
packages = repository.load_archives([Path("a.pkg.tar.xz"), Path("b.pkg.tar.xz"), Path("c.pkg.tar.xz")])
|
||||
assert len(packages) == 2
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user