Compare commits

..

24 Commits

Author SHA1 Message Date
730f3ca0c9 copyright update 2023-01-04 03:43:10 +02:00
42c13b5d4b Release 2.5.4 2023-01-03 01:59:25 +02:00
04e5a263b7 add notes about documentation and methods inside class
Because I always forget which way I used before
2023-01-03 01:53:10 +02:00
caca1576c8 Correct way to allow setting context with existing
This reverts commit 5c4d3eeffd.

Original solution has introduced special workaround (strict flag) which
contradicts the concept of immutable context. Moreover, it introduces
possible side-effects, because child process will use the one set by
parent instead of having own one.

The correct solution is to re-create context in process entry point

Sorry, it was Jan 1 and I was drunk :(
2023-01-03 00:48:14 +02:00
98f2f19d5b Release 2.5.3 2023-01-02 03:24:11 +02:00
5c4d3eeffd allow setting context with existing
In case of running command from web interface, it will raise exception
because context has been copied with subprocesses
2023-01-02 03:21:15 +02:00
84d4523e85 Release 2.5.2 2023-01-02 01:57:09 +02:00
2c2eae2334 remote all gitfiles in git remote trigger
In case if there is .gitignore file with asterics, the pkgbuild upload
would not appear
2023-01-02 01:45:50 +02:00
214d6d7fdd Release 2.5.1 2022-12-31 14:58:37 +02:00
e9512e9a6a remote log for calculate version as it cleans logs 2022-12-31 14:48:21 +02:00
f984ea75d0 fully lazy handle load
In case of immediate handle load it would try to sync databases (or at
least to create database files), which is not possible in case if
command is run as non-ahriman user. This commit makes handle load lazy
and allows to run some commands as non-ahriman user
2022-12-31 14:48:21 +02:00
b44e5c3a3d Release 2.5.0 2022-12-31 02:02:37 +02:00
1891d6c944 force upgrade sphinx documentation 2022-12-30 22:58:13 +02:00
08d68258ca add completion files generated by shtab 2022-12-30 21:19:23 +02:00
cd3d12a754 allow 3 symbols for package search 2022-12-30 21:19:23 +02:00
81d9526054 improve VCS packages checks
* Unlike older version, currently service will always try to pull AUR
  package to check version. Previously if no-vcs flag is set, it would
  ignore VCS packages completelly
* Introduce build.vcs_allowed_age option. If set, it will skip version
  calculation if package age (now - build_date) is less than this value
2022-12-30 21:19:23 +02:00
c7447f19f0 change another boolean info option to boolean action 2022-12-29 03:15:48 +02:00
7de94a8daa add repo-structure subcommand
This commit also changes Tree class, replacing load method by resolve
2022-12-27 10:35:03 +02:00
aa1a59d0a3 fix property description in docs 2022-12-26 02:32:14 +02:00
8864855c14 write patches via gitremote push trigger (#79)
* write patches via gitremote push trigger

* implement context variables intead of custom database class
2022-12-25 02:10:38 +03:00
b0b37e8169 Release 2.4.1 2022-12-11 05:17:10 +02:00
7df4adfc9d replace alert bodals with toasts 2022-12-09 11:33:19 +02:00
2d5b73c6dc remove badges from status page 2022-12-09 00:58:03 +02:00
1c8aed4a97 check that package has been created during setup workflow 2022-12-06 11:09:56 +02:00
256 changed files with 7368 additions and 5196 deletions

View File

@ -52,7 +52,7 @@ fi
# the build itself does not really work in the container
sudo -u ahriman -- ahriman package-add --now yay
# check if package was actually installed
#test -n "$(find "/var/lib/ahriman/repository/x86_64" -name "yay*pkg*")"
test -n "$(find "/var/lib/ahriman/repository/x86_64" -name "yay*pkg*")"
# run package check
sudo -u ahriman -- ahriman repo-update
# stop web service lol

View File

@ -26,7 +26,95 @@ In order to resolve all difficult cases the `autopep8` is used. You can perform
Again, the most checks can be performed by `make check` command, though some additional guidelines must be applied:
* Every class, every function (including private and protected), every attribute must be documented. The project follows [Google style documentation](https://google.github.io/styleguide/pyguide.html). The only exception is local functions.
* Correct way to document function, if section is empty, e.g. no notes or there are no args, it should be omitted:
```python
def foo(argument: str, *, flag: bool = False) -> int:
"""
do foo
Note:
Very important note about this function
Args:
argument(str): an argument
flag(bool, optional): a flag (Default value = False)
Returns:
int: result
Raises:
RuntimeException: a local function error occurs
Examples:
Very informative example how to use this function, e.g.::
>>> foo("argument", flag=False)
Note that function documentation is in rST.
"""
```
`Returns` should be replaced with `Yields` for generators.
Class attributes should be documented in the following way:
```python
class Clazz(BaseClazz):
"""
brand-new implementation of ``BaseClazz``
Attributes:
CLAZZ_ATTRIBUTE(int): (class attribute) a brand-new class attribute
instance_attribute(str): an instance attribute
Examples:
Very informative class usage example, e.g.::
>>> from module import Clazz
>>> clazz = Clazz()
"""
CLAZZ_ATTRIBUTE = 42
def __init__(self) -> None:
"""
default constructor
"""
self.instance_attribute = ""
```
* Type annotations are the must, even for local functions.
* Recommended order of function definitions in class:
```python
class Clazz:
def __init__(self) -> None: ... # replace with `__post_init__` for dataclasses
@property
def property(self) -> Any: ...
@classmethod
def class_method(cls: Type[Clazz]) -> Clazz: ...
@staticmethod
def static_method() -> Any: ...
def __private_method(self) -> Any: ...
def _protected_method(self) -> Any: ...
def usual_method(self) -> Any: ...
def __hash__(self) -> int: ... # basically any magic (or look-alike) method
```
Methods inside one group should be ordered alphabetically, the only exception is `__init__` method (`__post__init__` for dataclasses) which should be defined first. For test methods it is recommended to follow the order in which functions are defined.
Though, we would like to highlight abstract methods (i.e. ones which raise `NotImplementedError`), we still keep in global order at the moment.
* Abstract methods must raise `NotImplementedError` instead of using `abc.abstractmethod`. The reason behind this restriction is the fact that we have class/static abstract methods for those we need to define their attribute first making the code harder to read.
* For any path interactions `pathlib.Path` must be used.
* Configuration interactions must go through `ahriman.core.configuration.Configuration` class instance.
* In case if class load requires some actions, it is recommended to create class method which can be used for class instantiating.
@ -59,7 +147,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.
* No global variable is allowed outside of `ahriman.version` 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.

View File

@ -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
git add package/archlinux/PKGBUILD src/ahriman/version.py docs/ahriman-architecture.svg docs/ahriman.1 docs/completions/
git commit -m "Release $(VERSION)"
git tag "$(VERSION)"
git push

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 621 KiB

After

Width:  |  Height:  |  Size: 641 KiB

View File

@ -1,9 +1,9 @@
.TH AHRIMAN "1" "2022\-12\-05" "ahriman" "Generated Python Manual"
.TH AHRIMAN "1" "2023\-01\-03" "ahriman" "Generated Python Manual"
.SH NAME
ahriman
.SH SYNOPSIS
.B ahriman
[-h] [-a ARCHITECTURE] [-c CONFIGURATION] [--force] [-l LOCK] [--report | --no-report] [-q] [--unsafe] [-V] {aur-search,search,daemon,help,help-commands-unsafe,key-import,package-add,add,package-update,package-remove,remove,package-status,status,package-status-remove,package-status-update,status-update,patch-add,patch-list,patch-remove,patch-set-add,repo-backup,repo-check,check,repo-clean,clean,repo-config,config,repo-rebuild,rebuild,repo-remove-unknown,remove-unknown,repo-report,report,repo-restore,repo-setup,init,repo-init,setup,repo-sign,sign,repo-status-update,repo-sync,sync,repo-triggers,repo-update,update,shell,user-add,user-list,user-remove,version,web} ...
[-h] [-a ARCHITECTURE] [-c CONFIGURATION] [--force] [-l LOCK] [--report | --no-report] [-q] [--unsafe] [-V] {aur-search,search,daemon,help,help-commands-unsafe,key-import,package-add,add,package-update,package-remove,remove,package-status,status,package-status-remove,package-status-update,status-update,patch-add,patch-list,patch-remove,patch-set-add,repo-backup,repo-check,check,repo-clean,clean,repo-config,config,repo-rebuild,rebuild,repo-remove-unknown,remove-unknown,repo-report,report,repo-restore,repo-setup,init,repo-init,setup,repo-sign,sign,repo-status-update,repo-sync,sync,repo-tree,repo-triggers,repo-update,update,shell,user-add,user-list,user-remove,version,web} ...
.SH DESCRIPTION
ArcH linux ReposItory MANager
@ -121,6 +121,9 @@ update repository status
\fBahriman\fR \fI\,repo\-sync\/\fR
sync repository
.TP
\fBahriman\fR \fI\,repo\-tree\/\fR
dump repository tree
.TP
\fBahriman\fR \fI\,repo\-triggers\/\fR
run triggers
.TP
@ -277,7 +280,8 @@ remove package from the repository
package name or base
.SH COMMAND \fI\,'ahriman package\-status'\/\fR
usage: ahriman package\-status [\-h] [\-\-ahriman] [\-e] [\-i] [\-s {unknown,pending,building,failed,success}] [package ...]
usage: ahriman package\-status [\-h] [\-\-ahriman] [\-e] [\-\-info | \-\-no\-info] [\-s {unknown,pending,building,failed,success}]
[package ...]
request status of the package
@ -295,8 +299,8 @@ get service status itself
return non\-zero exit status if result is empty
.TP
\fB\-i\fR, \fB\-\-info\fR
show additional package information
\fB\-\-info\fR, \fB\-\-no\-info\fR
show additional package information (default: False)
.TP
\fB\-s\fR \fI\,{unknown,pending,building,failed,success}\/\fR, \fB\-\-status\fR \fI\,{unknown,pending,building,failed,success}\/\fR
@ -583,6 +587,11 @@ usage: ahriman repo\-sync [\-h]
sync repository files to remote server according to current settings
.SH COMMAND \fI\,'ahriman repo\-tree'\/\fR
usage: ahriman repo\-tree [\-h]
dump repository tree based on packages dependencies
.SH COMMAND \fI\,'ahriman repo\-triggers'\/\fR
usage: ahriman repo\-triggers [\-h] [trigger ...]

View File

@ -156,6 +156,14 @@ ahriman.application.handlers.status\_update module
:no-undoc-members:
:show-inheritance:
ahriman.application.handlers.structure module
---------------------------------------------
.. automodule:: ahriman.application.handlers.structure
:members:
:no-undoc-members:
:show-inheritance:
ahriman.application.handlers.triggers module
--------------------------------------------

View File

@ -68,6 +68,14 @@ ahriman.core.formatters.string\_printer module
:no-undoc-members:
:show-inheritance:
ahriman.core.formatters.tree\_printer module
--------------------------------------------
.. automodule:: ahriman.core.formatters.tree_printer
:members:
:no-undoc-members:
:show-inheritance:
ahriman.core.formatters.update\_printer module
----------------------------------------------

View File

@ -36,6 +36,14 @@ ahriman.models.build\_status module
:no-undoc-members:
:show-inheritance:
ahriman.models.context\_key module
----------------------------------
.. automodule:: ahriman.models.context_key
:members:
:no-undoc-members:
:show-inheritance:
ahriman.models.counters module
------------------------------

View File

@ -169,6 +169,15 @@ Utils
For every external command run (which is actually not recommended if possible) custom wrapper for ``subprocess`` is used. Additional functions ``ahriman.core.auth.helpers`` provide safe calls for ``aiohttp_security`` methods and are required to make this dependency optional.
Context variables
^^^^^^^^^^^^^^^^^
Package provides implicit global variables which can be accessed from ``ahriman.core`` package as ``context`` variable, wrapped by ``contextvars.ContextVar`` class. The value of the variable is defaulting to private ``_Context`` class which is defined in the same module. The default values - such as ``database`` and ``sign`` - are being set on the service initialization.
The ``_Context`` class itself mimics default collection interface (as is Mapping) and can be modified by ``_Context.set`` method. The stored variables can be achieved by ``_Context.get`` method, which is unlike default ``Mapping`` interface also performs type and presence checks.
In order to provide statically typed interface, the ``ahriman.models.context_key.ContextKey`` class is used for both ``_Content.get`` and ``_Content.set`` methods; the context instance itself, however, does not store information about types.
Submodules
^^^^^^^^^^

View File

@ -0,0 +1,484 @@
# AUTOMATICALLY GENERATED by `shtab`
_shtab_ahriman_subparsers=('aur-search' 'search' 'daemon' 'help' 'help-commands-unsafe' 'key-import' 'package-add' 'add' 'package-update' 'package-remove' 'remove' 'package-status' 'status' 'package-status-remove' 'package-status-update' 'status-update' 'patch-add' 'patch-list' 'patch-remove' 'patch-set-add' 'repo-backup' 'repo-check' 'check' 'repo-clean' 'clean' 'repo-config' 'config' 'repo-rebuild' 'rebuild' 'repo-remove-unknown' 'remove-unknown' 'repo-report' 'report' 'repo-restore' 'repo-setup' 'init' 'repo-init' 'setup' 'repo-sign' 'sign' 'repo-status-update' 'repo-sync' 'sync' 'repo-tree' 'repo-triggers' 'repo-update' 'update' 'shell' 'user-add' 'user-list' 'user-remove' 'version' 'web')
_shtab_ahriman_option_strings=('-h' '--help' '-a' '--architecture' '-c' '--configuration' '--force' '-l' '--lock' '--report' '--no-report' '-q' '--quiet' '--unsafe' '-V' '--version')
_shtab_ahriman_aur_search_option_strings=('-h' '--help' '-e' '--exit-code' '--info' '--no-info' '--sort-by')
_shtab_ahriman_search_option_strings=('-h' '--help' '-e' '--exit-code' '--info' '--no-info' '--sort-by')
_shtab_ahriman_daemon_option_strings=('-h' '--help' '-i' '--interval' '--aur' '--no-aur' '--local' '--no-local' '--manual' '--no-manual' '--vcs' '--no-vcs' '-y' '--refresh')
_shtab_ahriman_help_option_strings=('-h' '--help')
_shtab_ahriman_help_commands_unsafe_option_strings=('-h' '--help' '--command')
_shtab_ahriman_key_import_option_strings=('-h' '--help' '--key-server')
_shtab_ahriman_package_add_option_strings=('-h' '--help' '-e' '--exit-code' '-n' '--now' '-y' '--refresh' '-s' '--source' '--without-dependencies')
_shtab_ahriman_add_option_strings=('-h' '--help' '-e' '--exit-code' '-n' '--now' '-y' '--refresh' '-s' '--source' '--without-dependencies')
_shtab_ahriman_package_update_option_strings=('-h' '--help' '-e' '--exit-code' '-n' '--now' '-y' '--refresh' '-s' '--source' '--without-dependencies')
_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')
_shtab_ahriman_status_option_strings=('-h' '--help' '--ahriman' '-e' '--exit-code' '--info' '--no-info' '-s' '--status')
_shtab_ahriman_package_status_remove_option_strings=('-h' '--help')
_shtab_ahriman_package_status_update_option_strings=('-h' '--help' '-s' '--status')
_shtab_ahriman_status_update_option_strings=('-h' '--help' '-s' '--status')
_shtab_ahriman_patch_add_option_strings=('-h' '--help')
_shtab_ahriman_patch_list_option_strings=('-h' '--help' '-e' '--exit-code' '-v' '--variable')
_shtab_ahriman_patch_remove_option_strings=('-h' '--help' '-v' '--variable')
_shtab_ahriman_patch_set_add_option_strings=('-h' '--help' '-t' '--track')
_shtab_ahriman_repo_backup_option_strings=('-h' '--help')
_shtab_ahriman_repo_check_option_strings=('-h' '--help' '-e' '--exit-code' '--vcs' '--no-vcs' '-y' '--refresh')
_shtab_ahriman_check_option_strings=('-h' '--help' '-e' '--exit-code' '--vcs' '--no-vcs' '-y' '--refresh')
_shtab_ahriman_repo_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_config_option_strings=('-h' '--help')
_shtab_ahriman_config_option_strings=('-h' '--help')
_shtab_ahriman_repo_rebuild_option_strings=('-h' '--help' '--depends-on' '--dry-run' '--from-database' '-e' '--exit-code')
_shtab_ahriman_rebuild_option_strings=('-h' '--help' '--depends-on' '--dry-run' '--from-database' '-e' '--exit-code')
_shtab_ahriman_repo_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')
_shtab_ahriman_report_option_strings=('-h' '--help')
_shtab_ahriman_repo_restore_option_strings=('-h' '--help' '-o' '--output')
_shtab_ahriman_repo_setup_option_strings=('-h' '--help' '--build-as-user' '--build-command' '--from-configuration' '--makeflags-jobs' '--no-makeflags-jobs' '--multilib' '--no-multilib' '--packager' '--repository' '--sign-key' '--sign-target' '--web-port' '--web-unix-socket')
_shtab_ahriman_init_option_strings=('-h' '--help' '--build-as-user' '--build-command' '--from-configuration' '--makeflags-jobs' '--no-makeflags-jobs' '--multilib' '--no-multilib' '--packager' '--repository' '--sign-key' '--sign-target' '--web-port' '--web-unix-socket')
_shtab_ahriman_repo_init_option_strings=('-h' '--help' '--build-as-user' '--build-command' '--from-configuration' '--makeflags-jobs' '--no-makeflags-jobs' '--multilib' '--no-multilib' '--packager' '--repository' '--sign-key' '--sign-target' '--web-port' '--web-unix-socket')
_shtab_ahriman_setup_option_strings=('-h' '--help' '--build-as-user' '--build-command' '--from-configuration' '--makeflags-jobs' '--no-makeflags-jobs' '--multilib' '--no-multilib' '--packager' '--repository' '--sign-key' '--sign-target' '--web-port' '--web-unix-socket')
_shtab_ahriman_repo_sign_option_strings=('-h' '--help')
_shtab_ahriman_sign_option_strings=('-h' '--help')
_shtab_ahriman_repo_status_update_option_strings=('-h' '--help' '-s' '--status')
_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' '--dry-run' '-e' '--exit-code' '--aur' '--no-aur' '--local' '--no-local' '--manual' '--no-manual' '--vcs' '--no-vcs' '-y' '--refresh')
_shtab_ahriman_update_option_strings=('-h' '--help' '--dry-run' '-e' '--exit-code' '--aur' '--no-aur' '--local' '--no-local' '--manual' '--no-manual' '--vcs' '--no-vcs' '-y' '--refresh')
_shtab_ahriman_shell_option_strings=('-h' '--help')
_shtab_ahriman_user_add_option_strings=('-h' '--help' '-p' '--password' '-r' '--role' '-s' '--secure')
_shtab_ahriman_user_list_option_strings=('-h' '--help' '-e' '--exit-code' '-r' '--role')
_shtab_ahriman_user_remove_option_strings=('-h' '--help')
_shtab_ahriman_version_option_strings=('-h' '--help')
_shtab_ahriman_web_option_strings=('-h' '--help')
_shtab_ahriman_pos_0_choices=('aur-search' 'search' 'daemon' 'help' 'help-commands-unsafe' 'key-import' 'package-add' 'add' 'package-update' 'package-remove' 'remove' 'package-status' 'status' 'package-status-remove' 'package-status-update' 'status-update' 'patch-add' 'patch-list' 'patch-remove' 'patch-set-add' 'repo-backup' 'repo-check' 'check' 'repo-clean' 'clean' 'repo-config' 'config' 'repo-rebuild' 'rebuild' 'repo-remove-unknown' 'remove-unknown' 'repo-report' 'report' 'repo-restore' 'repo-setup' 'init' 'repo-init' 'setup' 'repo-sign' 'sign' 'repo-status-update' 'repo-sync' 'sync' 'repo-tree' 'repo-triggers' 'repo-update' 'update' 'shell' 'user-add' 'user-list' 'user-remove' 'version' 'web')
_shtab_ahriman_aur_search___sort_by_choices=('description' 'first_submitted' 'id' 'last_modified' 'maintainer' 'name' 'num_votes' 'out_of_date' 'package_base' 'package_base_id' 'popularity' 'repository' 'url' 'url_path' 'version')
_shtab_ahriman_search___sort_by_choices=('description' 'first_submitted' 'id' 'last_modified' 'maintainer' 'name' 'num_votes' 'out_of_date' 'package_base' 'package_base_id' 'popularity' 'repository' 'url' 'url_path' 'version')
_shtab_ahriman_package_add__s_choices=('auto' 'archive' 'aur' 'directory' 'local' 'remote' 'repository')
_shtab_ahriman_package_add___source_choices=('auto' 'archive' 'aur' 'directory' 'local' 'remote' 'repository')
_shtab_ahriman_add__s_choices=('auto' 'archive' 'aur' 'directory' 'local' 'remote' 'repository')
_shtab_ahriman_add___source_choices=('auto' 'archive' 'aur' 'directory' 'local' 'remote' 'repository')
_shtab_ahriman_package_update__s_choices=('auto' 'archive' 'aur' 'directory' 'local' 'remote' 'repository')
_shtab_ahriman_package_update___source_choices=('auto' 'archive' 'aur' 'directory' 'local' 'remote' 'repository')
_shtab_ahriman_package_status__s_choices=('unknown' 'pending' 'building' 'failed' 'success')
_shtab_ahriman_package_status___status_choices=('unknown' 'pending' 'building' 'failed' 'success')
_shtab_ahriman_status__s_choices=('unknown' 'pending' 'building' 'failed' 'success')
_shtab_ahriman_status___status_choices=('unknown' 'pending' 'building' 'failed' 'success')
_shtab_ahriman_package_status_update__s_choices=('unknown' 'pending' 'building' 'failed' 'success')
_shtab_ahriman_package_status_update___status_choices=('unknown' 'pending' 'building' 'failed' 'success')
_shtab_ahriman_status_update__s_choices=('unknown' 'pending' 'building' 'failed' 'success')
_shtab_ahriman_status_update___status_choices=('unknown' 'pending' 'building' 'failed' 'success')
_shtab_ahriman_repo_setup___sign_target_choices=('disabled' 'packages' 'repository')
_shtab_ahriman_init___sign_target_choices=('disabled' 'packages' 'repository')
_shtab_ahriman_repo_init___sign_target_choices=('disabled' 'packages' 'repository')
_shtab_ahriman_setup___sign_target_choices=('disabled' 'packages' 'repository')
_shtab_ahriman_repo_status_update__s_choices=('unknown' 'pending' 'building' 'failed' 'success')
_shtab_ahriman_repo_status_update___status_choices=('unknown' 'pending' 'building' 'failed' 'success')
_shtab_ahriman_user_add__r_choices=('unauthorized' 'read' 'reporter' 'full')
_shtab_ahriman_user_add___role_choices=('unauthorized' 'read' 'reporter' 'full')
_shtab_ahriman_user_list__r_choices=('unauthorized' 'read' 'reporter' 'full')
_shtab_ahriman_user_list___role_choices=('unauthorized' 'read' 'reporter' 'full')
_shtab_ahriman_pos_0_nargs=A...
_shtab_ahriman__h_nargs=0
_shtab_ahriman___help_nargs=0
_shtab_ahriman___force_nargs=0
_shtab_ahriman___report_nargs=0
_shtab_ahriman___no_report_nargs=0
_shtab_ahriman__q_nargs=0
_shtab_ahriman___quiet_nargs=0
_shtab_ahriman___unsafe_nargs=0
_shtab_ahriman__V_nargs=0
_shtab_ahriman___version_nargs=0
_shtab_ahriman_aur_search_pos_0_nargs=+
_shtab_ahriman_aur_search__h_nargs=0
_shtab_ahriman_aur_search___help_nargs=0
_shtab_ahriman_aur_search__e_nargs=0
_shtab_ahriman_aur_search___exit_code_nargs=0
_shtab_ahriman_aur_search___info_nargs=0
_shtab_ahriman_aur_search___no_info_nargs=0
_shtab_ahriman_search_pos_0_nargs=+
_shtab_ahriman_search__h_nargs=0
_shtab_ahriman_search___help_nargs=0
_shtab_ahriman_search__e_nargs=0
_shtab_ahriman_search___exit_code_nargs=0
_shtab_ahriman_search___info_nargs=0
_shtab_ahriman_search___no_info_nargs=0
_shtab_ahriman_daemon__h_nargs=0
_shtab_ahriman_daemon___help_nargs=0
_shtab_ahriman_daemon___aur_nargs=0
_shtab_ahriman_daemon___no_aur_nargs=0
_shtab_ahriman_daemon___local_nargs=0
_shtab_ahriman_daemon___no_local_nargs=0
_shtab_ahriman_daemon___manual_nargs=0
_shtab_ahriman_daemon___no_manual_nargs=0
_shtab_ahriman_daemon___vcs_nargs=0
_shtab_ahriman_daemon___no_vcs_nargs=0
_shtab_ahriman_daemon__y_nargs=0
_shtab_ahriman_daemon___refresh_nargs=0
_shtab_ahriman_help__h_nargs=0
_shtab_ahriman_help___help_nargs=0
_shtab_ahriman_help_commands_unsafe__h_nargs=0
_shtab_ahriman_help_commands_unsafe___help_nargs=0
_shtab_ahriman_key_import__h_nargs=0
_shtab_ahriman_key_import___help_nargs=0
_shtab_ahriman_package_add_pos_0_nargs=+
_shtab_ahriman_package_add__h_nargs=0
_shtab_ahriman_package_add___help_nargs=0
_shtab_ahriman_package_add__e_nargs=0
_shtab_ahriman_package_add___exit_code_nargs=0
_shtab_ahriman_package_add__n_nargs=0
_shtab_ahriman_package_add___now_nargs=0
_shtab_ahriman_package_add__y_nargs=0
_shtab_ahriman_package_add___refresh_nargs=0
_shtab_ahriman_package_add___without_dependencies_nargs=0
_shtab_ahriman_add_pos_0_nargs=+
_shtab_ahriman_add__h_nargs=0
_shtab_ahriman_add___help_nargs=0
_shtab_ahriman_add__e_nargs=0
_shtab_ahriman_add___exit_code_nargs=0
_shtab_ahriman_add__n_nargs=0
_shtab_ahriman_add___now_nargs=0
_shtab_ahriman_add__y_nargs=0
_shtab_ahriman_add___refresh_nargs=0
_shtab_ahriman_add___without_dependencies_nargs=0
_shtab_ahriman_package_update_pos_0_nargs=+
_shtab_ahriman_package_update__h_nargs=0
_shtab_ahriman_package_update___help_nargs=0
_shtab_ahriman_package_update__e_nargs=0
_shtab_ahriman_package_update___exit_code_nargs=0
_shtab_ahriman_package_update__n_nargs=0
_shtab_ahriman_package_update___now_nargs=0
_shtab_ahriman_package_update__y_nargs=0
_shtab_ahriman_package_update___refresh_nargs=0
_shtab_ahriman_package_update___without_dependencies_nargs=0
_shtab_ahriman_package_remove_pos_0_nargs=+
_shtab_ahriman_package_remove__h_nargs=0
_shtab_ahriman_package_remove___help_nargs=0
_shtab_ahriman_remove_pos_0_nargs=+
_shtab_ahriman_remove__h_nargs=0
_shtab_ahriman_remove___help_nargs=0
_shtab_ahriman_package_status_pos_0_nargs=*
_shtab_ahriman_package_status__h_nargs=0
_shtab_ahriman_package_status___help_nargs=0
_shtab_ahriman_package_status___ahriman_nargs=0
_shtab_ahriman_package_status__e_nargs=0
_shtab_ahriman_package_status___exit_code_nargs=0
_shtab_ahriman_package_status___info_nargs=0
_shtab_ahriman_package_status___no_info_nargs=0
_shtab_ahriman_status_pos_0_nargs=*
_shtab_ahriman_status__h_nargs=0
_shtab_ahriman_status___help_nargs=0
_shtab_ahriman_status___ahriman_nargs=0
_shtab_ahriman_status__e_nargs=0
_shtab_ahriman_status___exit_code_nargs=0
_shtab_ahriman_status___info_nargs=0
_shtab_ahriman_status___no_info_nargs=0
_shtab_ahriman_package_status_remove_pos_0_nargs=+
_shtab_ahriman_package_status_remove__h_nargs=0
_shtab_ahriman_package_status_remove___help_nargs=0
_shtab_ahriman_package_status_update_pos_0_nargs=*
_shtab_ahriman_package_status_update__h_nargs=0
_shtab_ahriman_package_status_update___help_nargs=0
_shtab_ahriman_status_update_pos_0_nargs=*
_shtab_ahriman_status_update__h_nargs=0
_shtab_ahriman_status_update___help_nargs=0
_shtab_ahriman_patch_add__h_nargs=0
_shtab_ahriman_patch_add___help_nargs=0
_shtab_ahriman_patch_list__h_nargs=0
_shtab_ahriman_patch_list___help_nargs=0
_shtab_ahriman_patch_list__e_nargs=0
_shtab_ahriman_patch_list___exit_code_nargs=0
_shtab_ahriman_patch_remove__h_nargs=0
_shtab_ahriman_patch_remove___help_nargs=0
_shtab_ahriman_patch_set_add__h_nargs=0
_shtab_ahriman_patch_set_add___help_nargs=0
_shtab_ahriman_repo_backup__h_nargs=0
_shtab_ahriman_repo_backup___help_nargs=0
_shtab_ahriman_repo_check_pos_0_nargs=*
_shtab_ahriman_repo_check__h_nargs=0
_shtab_ahriman_repo_check___help_nargs=0
_shtab_ahriman_repo_check__e_nargs=0
_shtab_ahriman_repo_check___exit_code_nargs=0
_shtab_ahriman_repo_check___vcs_nargs=0
_shtab_ahriman_repo_check___no_vcs_nargs=0
_shtab_ahriman_repo_check__y_nargs=0
_shtab_ahriman_repo_check___refresh_nargs=0
_shtab_ahriman_check_pos_0_nargs=*
_shtab_ahriman_check__h_nargs=0
_shtab_ahriman_check___help_nargs=0
_shtab_ahriman_check__e_nargs=0
_shtab_ahriman_check___exit_code_nargs=0
_shtab_ahriman_check___vcs_nargs=0
_shtab_ahriman_check___no_vcs_nargs=0
_shtab_ahriman_check__y_nargs=0
_shtab_ahriman_check___refresh_nargs=0
_shtab_ahriman_repo_clean__h_nargs=0
_shtab_ahriman_repo_clean___help_nargs=0
_shtab_ahriman_repo_clean___cache_nargs=0
_shtab_ahriman_repo_clean___no_cache_nargs=0
_shtab_ahriman_repo_clean___chroot_nargs=0
_shtab_ahriman_repo_clean___no_chroot_nargs=0
_shtab_ahriman_repo_clean___manual_nargs=0
_shtab_ahriman_repo_clean___no_manual_nargs=0
_shtab_ahriman_repo_clean___packages_nargs=0
_shtab_ahriman_repo_clean___no_packages_nargs=0
_shtab_ahriman_repo_clean___pacman_nargs=0
_shtab_ahriman_repo_clean___no_pacman_nargs=0
_shtab_ahriman_clean__h_nargs=0
_shtab_ahriman_clean___help_nargs=0
_shtab_ahriman_clean___cache_nargs=0
_shtab_ahriman_clean___no_cache_nargs=0
_shtab_ahriman_clean___chroot_nargs=0
_shtab_ahriman_clean___no_chroot_nargs=0
_shtab_ahriman_clean___manual_nargs=0
_shtab_ahriman_clean___no_manual_nargs=0
_shtab_ahriman_clean___packages_nargs=0
_shtab_ahriman_clean___no_packages_nargs=0
_shtab_ahriman_clean___pacman_nargs=0
_shtab_ahriman_clean___no_pacman_nargs=0
_shtab_ahriman_repo_config__h_nargs=0
_shtab_ahriman_repo_config___help_nargs=0
_shtab_ahriman_config__h_nargs=0
_shtab_ahriman_config___help_nargs=0
_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__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__e_nargs=0
_shtab_ahriman_rebuild___exit_code_nargs=0
_shtab_ahriman_repo_remove_unknown__h_nargs=0
_shtab_ahriman_repo_remove_unknown___help_nargs=0
_shtab_ahriman_repo_remove_unknown___dry_run_nargs=0
_shtab_ahriman_remove_unknown__h_nargs=0
_shtab_ahriman_remove_unknown___help_nargs=0
_shtab_ahriman_remove_unknown___dry_run_nargs=0
_shtab_ahriman_repo_report__h_nargs=0
_shtab_ahriman_repo_report___help_nargs=0
_shtab_ahriman_report__h_nargs=0
_shtab_ahriman_report___help_nargs=0
_shtab_ahriman_repo_restore__h_nargs=0
_shtab_ahriman_repo_restore___help_nargs=0
_shtab_ahriman_repo_setup__h_nargs=0
_shtab_ahriman_repo_setup___help_nargs=0
_shtab_ahriman_repo_setup___makeflags_jobs_nargs=0
_shtab_ahriman_repo_setup___no_makeflags_jobs_nargs=0
_shtab_ahriman_repo_setup___multilib_nargs=0
_shtab_ahriman_repo_setup___no_multilib_nargs=0
_shtab_ahriman_init__h_nargs=0
_shtab_ahriman_init___help_nargs=0
_shtab_ahriman_init___makeflags_jobs_nargs=0
_shtab_ahriman_init___no_makeflags_jobs_nargs=0
_shtab_ahriman_init___multilib_nargs=0
_shtab_ahriman_init___no_multilib_nargs=0
_shtab_ahriman_repo_init__h_nargs=0
_shtab_ahriman_repo_init___help_nargs=0
_shtab_ahriman_repo_init___makeflags_jobs_nargs=0
_shtab_ahriman_repo_init___no_makeflags_jobs_nargs=0
_shtab_ahriman_repo_init___multilib_nargs=0
_shtab_ahriman_repo_init___no_multilib_nargs=0
_shtab_ahriman_setup__h_nargs=0
_shtab_ahriman_setup___help_nargs=0
_shtab_ahriman_setup___makeflags_jobs_nargs=0
_shtab_ahriman_setup___no_makeflags_jobs_nargs=0
_shtab_ahriman_setup___multilib_nargs=0
_shtab_ahriman_setup___no_multilib_nargs=0
_shtab_ahriman_repo_sign_pos_0_nargs=*
_shtab_ahriman_repo_sign__h_nargs=0
_shtab_ahriman_repo_sign___help_nargs=0
_shtab_ahriman_sign_pos_0_nargs=*
_shtab_ahriman_sign__h_nargs=0
_shtab_ahriman_sign___help_nargs=0
_shtab_ahriman_repo_status_update__h_nargs=0
_shtab_ahriman_repo_status_update___help_nargs=0
_shtab_ahriman_repo_sync__h_nargs=0
_shtab_ahriman_repo_sync___help_nargs=0
_shtab_ahriman_sync__h_nargs=0
_shtab_ahriman_sync___help_nargs=0
_shtab_ahriman_repo_tree__h_nargs=0
_shtab_ahriman_repo_tree___help_nargs=0
_shtab_ahriman_repo_triggers_pos_0_nargs=*
_shtab_ahriman_repo_triggers__h_nargs=0
_shtab_ahriman_repo_triggers___help_nargs=0
_shtab_ahriman_repo_update_pos_0_nargs=*
_shtab_ahriman_repo_update__h_nargs=0
_shtab_ahriman_repo_update___help_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___aur_nargs=0
_shtab_ahriman_repo_update___no_aur_nargs=0
_shtab_ahriman_repo_update___local_nargs=0
_shtab_ahriman_repo_update___no_local_nargs=0
_shtab_ahriman_repo_update___manual_nargs=0
_shtab_ahriman_repo_update___no_manual_nargs=0
_shtab_ahriman_repo_update___vcs_nargs=0
_shtab_ahriman_repo_update___no_vcs_nargs=0
_shtab_ahriman_repo_update__y_nargs=0
_shtab_ahriman_repo_update___refresh_nargs=0
_shtab_ahriman_update_pos_0_nargs=*
_shtab_ahriman_update__h_nargs=0
_shtab_ahriman_update___help_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___aur_nargs=0
_shtab_ahriman_update___no_aur_nargs=0
_shtab_ahriman_update___local_nargs=0
_shtab_ahriman_update___no_local_nargs=0
_shtab_ahriman_update___manual_nargs=0
_shtab_ahriman_update___no_manual_nargs=0
_shtab_ahriman_update___vcs_nargs=0
_shtab_ahriman_update___no_vcs_nargs=0
_shtab_ahriman_update__y_nargs=0
_shtab_ahriman_update___refresh_nargs=0
_shtab_ahriman_shell__h_nargs=0
_shtab_ahriman_shell___help_nargs=0
_shtab_ahriman_shell__v_nargs=0
_shtab_ahriman_shell___verbose_nargs=0
_shtab_ahriman_user_add__h_nargs=0
_shtab_ahriman_user_add___help_nargs=0
_shtab_ahriman_user_add__s_nargs=0
_shtab_ahriman_user_add___secure_nargs=0
_shtab_ahriman_user_list__h_nargs=0
_shtab_ahriman_user_list___help_nargs=0
_shtab_ahriman_user_list__e_nargs=0
_shtab_ahriman_user_list___exit_code_nargs=0
_shtab_ahriman_user_remove__h_nargs=0
_shtab_ahriman_user_remove___help_nargs=0
_shtab_ahriman_version__h_nargs=0
_shtab_ahriman_version___help_nargs=0
_shtab_ahriman_web__h_nargs=0
_shtab_ahriman_web___help_nargs=0
# $1=COMP_WORDS[1]
_shtab_compgen_files() {
compgen -f -- $1 # files
}
# $1=COMP_WORDS[1]
_shtab_compgen_dirs() {
compgen -d -- $1 # recurse into subdirs
}
# $1=COMP_WORDS[1]
_shtab_replace_nonword() {
echo "${1//[^[:word:]]/_}"
}
# set default values (called for the initial parser & any subparsers)
_set_parser_defaults() {
local subparsers_var="${prefix}_subparsers[@]"
sub_parsers=${!subparsers_var}
local current_option_strings_var="${prefix}_option_strings[@]"
current_option_strings=${!current_option_strings_var}
completed_positional_actions=0
_set_new_action "pos_${completed_positional_actions}" true
}
# $1=action identifier
# $2=positional action (bool)
# set all identifiers for an action's parameters
_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}"
local current_action_choices_var="${current_action}_choices[@]"
current_action_choices="${!current_action_choices_var}"
local current_action_nargs_var="${current_action}_nargs"
if [ -n "${!current_action_nargs_var}" ]; then
current_action_nargs="${!current_action_nargs_var}"
else
current_action_nargs=1
fi
current_action_args_start_index=$(( $word_index + 1 ))
current_action_is_positional=$2
}
# Notes:
# `COMPREPLY`: what will be rendered after completion is triggered
# `completing_word`: currently typed word to generate completions for
# `${!var}`: evaluates the content of `var` and expand its content as a variable
# hello="world"
# x="hello"
# ${!x} -> ${hello} -> "world"
_shtab_ahriman() {
local completing_word="${COMP_WORDS[COMP_CWORD]}"
COMPREPLY=()
prefix=_shtab_ahriman
word_index=0
_set_parser_defaults
word_index=1
# determine what arguments are appropriate for the current state
# of the arg parser
while [ $word_index -ne $COMP_CWORD ]; do
local this_word="${COMP_WORDS[$word_index]}"
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
# 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
_set_new_action $this_word false
fi
if [[ "$current_action_nargs" != "*" ]] && \
[[ "$current_action_nargs" != "+" ]] && \
[[ "$current_action_nargs" != *"..." ]] && \
(( $word_index + 1 - $current_action_args_start_index >= \
$current_action_nargs )); then
$current_action_is_positional && let "completed_positional_actions += 1"
_set_new_action "pos_${completed_positional_actions}" true
fi
let "word_index+=1"
done
# Generate the completions
if [[ "${completing_word}" == -* ]]; then
# optional argument started: use option strings
COMPREPLY=( $(compgen -W "${current_option_strings[*]}" -- "${completing_word}") )
else
# use choices & compgen
local IFS=$'\n' # items may contain spaces, so delimit using newline
COMPREPLY=( $([ -n "${current_action_compgen}" ] \
&& "${current_action_compgen}" "${completing_word}") )
unset IFS
COMPREPLY+=( $(compgen -W "${current_action_choices[*]}" -- "${completing_word}") )
fi
return 0
}
complete -o filenames -F _shtab_ahriman ahriman

View File

@ -0,0 +1,531 @@
#compdef ahriman
# AUTOMATICALLY GENERATED by `shtab`
_shtab_ahriman_commands() {
local _commands=(
"add:add existing or new package to the build queue"
"aur-search:search for package in AUR using API"
"check:check for packages updates. Same as repo-update --dry-run --no-manual"
"clean:remove local caches"
"config:dump configuration for the specified architecture"
"daemon:start process which periodically will run update process"
"help:show help message for application or command and exit"
"help-commands-unsafe:list unsafe commands as defined in default args"
"init:create initial service configuration, requires root"
"key-import:import PGP key from public sources to the repository user"
"package-add:add existing or new package to the build queue"
"package-remove:remove package from the repository"
"package-status:request status of the package"
"package-status-remove:remove the package from the status page"
"package-status-update:update package status on the status page"
"package-update:add existing or new package to the build queue"
"patch-add:create or update patched PKGBUILD function or variable"
"patch-list:list available patches for the package"
"patch-remove:remove patches for the package"
"patch-set-add:create or update source patches"
"rebuild:force rebuild whole repository"
"remove:remove package from the repository"
"remove-unknown:remove packages which are missing in AUR and do not have local PKGBUILDs"
"repo-backup:backup repository settings and database"
"repo-check:check for packages updates. Same as repo-update --dry-run --no-manual"
"repo-clean:remove local caches"
"repo-config:dump configuration for the specified architecture"
"repo-init:create initial service configuration, requires root"
"repo-rebuild:force rebuild whole repository"
"repo-remove-unknown:remove packages which are missing in AUR and do not have local PKGBUILDs"
"repo-report:generate repository report according to current settings"
"repo-restore:restore settings and database"
"repo-setup:create initial service configuration, requires root"
"repo-sign:(re-)sign packages and repository database according to current settings"
"repo-status-update:update repository status on the status page"
"repo-sync:sync repository files to remote server according to current settings"
"repo-tree:dump repository tree based on packages dependencies"
"repo-triggers:run triggers on empty build result as configured by settings"
"repo-update:check for packages updates and run build process if requested"
"report:generate repository report according to current settings"
"search:search for package in AUR using API"
"setup:create initial service configuration, requires root"
"shell:drop into python shell while having created application"
"sign:(re-)sign packages and repository database according to current settings"
"status:request status of the package"
"status-update:update package status on the status page"
"sync:sync repository files to remote server according to current settings"
"update:check for packages updates and run build process if requested"
"user-add:update user for web services with the given password and role. In case if password was not entered it will be asked interactively"
"user-list:list users from the user mapping and their roles"
"user-remove:remove user from the user mapping and update the configuration"
"version:print application and its dependencies versions"
"web:start web server"
)
_describe 'ahriman commands' _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:"
{--report,--no-report}"[force enable or disable reporting to web service (default\: \%(default)s)]:report:"
{-q,--quiet}"[force disable any logging]"
"--unsafe[allow to run ahriman as non-ahriman user. Some actions might be unavailable]"
"(- : *)"{-V,--version}"[show program\'s version number and exit]"
)
_shtab_ahriman_add_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
{-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)"
"--without-dependencies[do not add dependencies]"
"(*):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 (default\: \%(default)s)]: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 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}"[enable or disable checking of VCS packages (default\: \%(default)s)]: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:"
)
_shtab_ahriman_clean_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
{--cache,--no-cache}"[clear directory with package caches (default\: \%(default)s)]:cache:"
{--chroot,--no-chroot}"[clear build chroot (default\: \%(default)s)]:chroot:"
{--manual,--no-manual}"[clear manually added packages queue (default\: \%(default)s)]:manual:"
{--packages,--no-packages}"[clear directory with built packages (default\: \%(default)s)]:packages:"
{--pacman,--no-pacman}"[clear directory with pacman local database cache (default\: \%(default)s)]:pacman:"
)
_shtab_ahriman_config_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
)
_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. Implies --no-vcs (default\: \%(default)s)]:aur:"
{--local,--no-local}"[enable or disable checking of local packages for updates (default\: \%(default)s)]:local:"
{--manual,--no-manual}"[include or exclude manual updates (default\: \%(default)s)]:manual:"
{--vcs,--no-vcs}"[enable or disable checking of VCS packages (default\: \%(default)s)]:vcs:"
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date]"
)
_shtab_ahriman_help_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
":show help message for specific command:"
)
_shtab_ahriman_help_commands_unsafe_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
"--command[instead of showing commands, just test command line for unsafe subcommand and return 0 in case if command is safe and 1 otherwise]:command:"
)
_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:"
{--makeflags-jobs,--no-makeflags-jobs}"[append MAKEFLAGS variable with parallelism set to number of cores (default\: \%(default)s)]:makeflags_jobs:"
{--multilib,--no-multilib}"[add or do not multilib repository (default\: \%(default)s)]: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:"
)
_shtab_ahriman_key_import_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
"--key-server[key server for key import]:key_server:"
":PGP key to import from public server:"
)
_shtab_ahriman_package_add_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
{-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)"
"--without-dependencies[do not add dependencies]"
"(*):package source (base name, path to local files, remote URL):"
)
_shtab_ahriman_package_remove_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
"(*):package name or base:"
)
_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 (default\: \%(default)s)]:info:"
{-s,--status}"[filter packages by status]:status:(unknown pending building failed success)"
"(*)::filter status by package base:"
)
_shtab_ahriman_package_status_remove_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
"(*):remove specified packages from status page:"
)
_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:"
)
_shtab_ahriman_package_update_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
{-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)"
"--without-dependencies[do not add dependencies]"
"(*):package source (base name, path to local files, remote URL):"
)
_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:"
)
_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:"
)
_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:"
":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:"
":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]"
)
_shtab_ahriman_remove_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
"(*):package name or base:"
)
_shtab_ahriman_remove_unknown_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
"--dry-run[just perform check for packages without removal]"
)
_shtab_ahriman_repo_backup_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
":path of the output archive:"
)
_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}"[enable or disable checking of VCS packages (default\: \%(default)s)]: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:"
)
_shtab_ahriman_repo_clean_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
{--cache,--no-cache}"[clear directory with package caches (default\: \%(default)s)]:cache:"
{--chroot,--no-chroot}"[clear build chroot (default\: \%(default)s)]:chroot:"
{--manual,--no-manual}"[clear manually added packages queue (default\: \%(default)s)]:manual:"
{--packages,--no-packages}"[clear directory with built packages (default\: \%(default)s)]:packages:"
{--pacman,--no-pacman}"[clear directory with pacman local database cache (default\: \%(default)s)]:pacman:"
)
_shtab_ahriman_repo_config_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
)
_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:"
{--makeflags-jobs,--no-makeflags-jobs}"[append MAKEFLAGS variable with parallelism set to number of cores (default\: \%(default)s)]:makeflags_jobs:"
{--multilib,--no-multilib}"[add or do not multilib repository (default\: \%(default)s)]: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:"
)
_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]"
)
_shtab_ahriman_repo_remove_unknown_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
"--dry-run[just perform check for packages without removal]"
)
_shtab_ahriman_repo_report_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
)
_shtab_ahriman_repo_restore_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
{-o,--output}"[root path of the extracted files]: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:"
{--makeflags-jobs,--no-makeflags-jobs}"[append MAKEFLAGS variable with parallelism set to number of cores (default\: \%(default)s)]:makeflags_jobs:"
{--multilib,--no-multilib}"[add or do not multilib repository (default\: \%(default)s)]: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:"
)
_shtab_ahriman_repo_sign_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
"(*)::sign only specified packages:"
)
_shtab_ahriman_repo_status_update_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
{-s,--status}"[new status]:status:(unknown pending building failed success)"
)
_shtab_ahriman_repo_sync_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
)
_shtab_ahriman_repo_tree_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
)
_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:"
)
_shtab_ahriman_repo_update_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
"--dry-run[just perform check for updates, same as check command]"
{-e,--exit-code}"[return non-zero exit status if result is empty]"
{--aur,--no-aur}"[enable or disable checking for AUR updates. Implies --no-vcs (default\: \%(default)s)]:aur:"
{--local,--no-local}"[enable or disable checking of local packages for updates (default\: \%(default)s)]:local:"
{--manual,--no-manual}"[include or exclude manual updates (default\: \%(default)s)]:manual:"
{--vcs,--no-vcs}"[enable or disable checking of VCS packages (default\: \%(default)s)]: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:"
)
_shtab_ahriman_report_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
)
_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 (default\: \%(default)s)]: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 url url_path version)"
"(*):search terms, can be specified multiple times, the result will match all terms:"
)
_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:"
{--makeflags-jobs,--no-makeflags-jobs}"[append MAKEFLAGS variable with parallelism set to number of cores (default\: \%(default)s)]:makeflags_jobs:"
{--multilib,--no-multilib}"[add or do not multilib repository (default\: \%(default)s)]: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:"
)
_shtab_ahriman_shell_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
":instead of dropping into shell, just execute the specified code:"
)
_shtab_ahriman_sign_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
"(*)::sign only specified packages:"
)
_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 (default\: \%(default)s)]:info:"
{-s,--status}"[filter packages by status]:status:(unknown pending building failed success)"
"(*)::filter status by package base:"
)
_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:"
)
_shtab_ahriman_sync_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
)
_shtab_ahriman_update_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
"--dry-run[just perform check for updates, same as check command]"
{-e,--exit-code}"[return non-zero exit status if result is empty]"
{--aur,--no-aur}"[enable or disable checking for AUR updates. Implies --no-vcs (default\: \%(default)s)]:aur:"
{--local,--no-local}"[enable or disable checking of local packages for updates (default\: \%(default)s)]:local:"
{--manual,--no-manual}"[include or exclude manual updates (default\: \%(default)s)]:manual:"
{--vcs,--no-vcs}"[enable or disable checking of VCS packages (default\: \%(default)s)]: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:"
)
_shtab_ahriman_user_add_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
{-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)"
{-s,--secure}"[set file permissions to user-only]"
":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:"
)
_shtab_ahriman_user_remove_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
":username for web service:"
)
_shtab_ahriman_version_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
)
_shtab_ahriman_web_options=(
"(- : *)"{-h,--help}"[show this help message and exit]"
)
_shtab_ahriman() {
local context state line curcontext="$curcontext" one_or_more='(-)*' remainder='(*)'
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
case $state in
ahriman)
words=($line[1] "${words[@]}")
(( 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 ;;
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 ;;
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-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 ;;
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 ;;
esac
esac
}
typeset -A opt_args
_shtab_ahriman "$@"

View File

@ -35,7 +35,7 @@ for module in (
# -- Project information -----------------------------------------------------
project = "ahriman"
copyright = "2021-2022, ahriman team"
copyright = "2021-2023, ahriman team"
author = "ahriman team"
# The full version, including alpha/beta/rc tags

View File

@ -59,6 +59,7 @@ Build related configuration. Group name can refer to architecture, e.g. ``build:
* ``makepkg_flags`` - additional flags passed to ``makepkg`` command, space separated list of strings, optional.
* ``makechrootpkg_flags`` - additional flags passed to ``makechrootpkg`` command, space separated list of strings, optional.
* ``triggers`` - list of ``ahriman.core.triggers.Trigger`` class implementation (e.g. ``ahriman.core.report.ReportTrigger ahriman.core.upload.UploadTrigger``) which will be loaded and run at the end of processing, space separated list of strings, optional. You can also specify triggers by their paths, e.g. ``/usr/lib/python3.10/site-packages/ahriman/core/report/report.py.ReportTrigger``. Triggers are run in the order of mention.
* ``vcs_allowed_age`` - maximal age in seconds of the VCS packages before their version will be updated with its remote source, int, optional, default ``0``.
``repository`` group
--------------------

View File

@ -36,6 +36,40 @@ Trigger which can be used for reporting. It implements ``on_result`` method and
This trigger takes build result (``on_result``) and performs syncing of the local packages to the remote mirror (e.g. S3 or just by rsync).
Context variables
-----------------
By default, only configuration and architecture are passed to triggers. However, some triggers might want to have access to other high-level wrappers. In order to provide such ability and avoid (double) initialization, the service provides a global context variables, which can be accessed from ``ahriman.core`` package:
.. code-block:: python
from ahriman.core import context
ctx = context.get()
Just because context is wrapped inside ``contexvars.ContextVar``, you need to explicitly extract variable by ``get()`` method. Later you can extract any variable if it is set, e.g.:
.. code-block:: python
from ahriman.core.database import SQLite
from ahriman.models.context_key import ContextKey
database = ctx.get(ContextKey("database", SQLite))
In order to provide typed API, all variables are stored together with their type. The ``get(ContextKey)`` method will throw ``KeyError`` in case if key is missing. Alternatively you can set your own variable inside context:
.. code-block:: python
ctx.set(ContextKey("answer", int), 42)
context.set(ctx)
Note, however, that there are several limitations:
* Context variables are immutable, thus you cannot override value if the key already presented.
* The ``return_type`` of ``ContextKey`` should match the value type, otherwise exception will be thrown.
The ``context`` also implements collection methods such as ``__iter__`` and ``__len__``.
Trigger example
---------------

View File

@ -1,7 +1,7 @@
# Maintainer: Evgeniy Alekseev
pkgname='ahriman'
pkgver=2.4.0
pkgver=2.5.4
pkgrel=1
pkgdesc="ArcH linux ReposItory MANager"
arch=('any')

View File

@ -24,6 +24,7 @@ ignore_packages =
makechrootpkg_flags =
makepkg_flags = --nocolor --ignorearch
triggers = ahriman.core.report.ReportTrigger ahriman.core.upload.UploadTrigger
vcs_allowed_age = 604800
[repository]
name = aur-clone

View File

@ -15,16 +15,15 @@
{% include "utils/bootstrap-scripts.jinja2" %}
<div class="container">
<h1>ahriman
<img id="badge-version" src="https://img.shields.io/badge/version-unknown-informational" alt="unknown">
<img id="badge-repository" src="https://img.shields.io/badge/repository-unknown-informational" alt="unknown">
<img id="badge-architecture" src="https://img.shields.io/badge/architecture-unknown-informational" alt="unknown">
<img id="badge-status" src="https://img.shields.io/badge/service%20status-unknown-inactive" alt="unknown">
</h1>
<h1 id="badge-repository">ahriman</h1>
</div>
<div id="alert-placeholder" class="toast-container p3 top-0 start-50 translate-middle-x"></div>
<div class="container">
<div id="toolbar" class="dropdown">
<a id="badge-status" tabindex="0" role="button" class="btn btn-outline-secondary" data-bs-toggle="popover" data-bs-trigger="focus" data-bs-content="no run data"><i class="bi bi-info-circle"></i></a>
{% if not auth.enabled or auth.username is not none %}
<button type="button" class="btn btn-primary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-box"></i> packages
@ -51,11 +50,13 @@
</button>
</li>
</ul>
<button id="key-import-btn" class="btn btn-info" data-bs-toggle="modal" data-bs-target="#key-import-modal" hidden>
<button id="key-import-btn" type="button" class="btn btn-info" data-bs-toggle="modal" data-bs-target="#key-import-modal" hidden>
<i class="bi bi-key"></i> import key
</button>
{% endif %}
<button class="btn btn-secondary" onclick="reload()">
<button type="button" class="btn btn-secondary" onclick="reload()">
<i class="bi bi-arrow-clockwise"></i> reload
</button>
</div>
@ -96,7 +97,7 @@
<div class="container">
<footer class="d-flex flex-wrap justify-content-between align-items-center border-top">
<ul class="nav">
<li><a class="nav-link" href="https://github.com/arcan1s/ahriman" title="sources"><i class="bi bi-github"></i> ahriman</a></li>
<li><a id="badge-version" class="nav-link" href="https://github.com/arcan1s/ahriman" title="sources"><i class="bi bi-github"></i> ahriman</a></li>
<li><a class="nav-link" href="https://github.com/arcan1s/ahriman/releases" title="releases list">releases</a></li>
<li><a class="nav-link" href="https://github.com/arcan1s/ahriman/issues" title="issues tracker">report a bug</a></li>
</ul>
@ -127,8 +128,7 @@
{% include "build-status/login-modal.jinja2" %}
{% endif %}
{% include "build-status/failed-modal.jinja2" %}
{% include "build-status/success-modal.jinja2" %}
{% include "build-status/alerts.jinja2" %}
{% include "build-status/package-add-modal.jinja2" %}
{% include "build-status/package-rebuild-modal.jinja2" %}

View File

@ -0,0 +1,45 @@
<script>
const alertPlaceholder = $("#alert-placeholder");
function createAlert(title, message, clz) {
const wrapper = document.createElement("div");
wrapper.classList.add("toast", clz);
wrapper.role = "alert";
wrapper.ariaLive = "assertive";
wrapper.ariaAtomic = "true";
wrapper.style.width = "500px"; // 500px is default modal size
const header = document.createElement("div");
header.classList.add("toast-header");
header.innerHTML = `<strong class="me-auto">${safe(title)}</strong> <button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="close"></button>`;
wrapper.appendChild(header);
const body = document.createElement("div");
body.classList.add("toast-body", "text-bg-light");
body.innerText = message;
wrapper.appendChild(body);
alertPlaceholder.append(wrapper);
const toast = new bootstrap.Toast(wrapper);
wrapper.addEventListener("hidden.bs.toast", () => {
wrapper.remove(); // bootstrap doesn't remove elements
reload();
});
toast.show();
}
function showFailure(title, description, jqXHR, errorThrown) {
let details;
try {
details = $.parseJSON(jqXHR.responseText).error; // execution handler json error response
} catch (_) {
details = errorThrown;
}
createAlert(title, description(details), "text-bg-danger");
}
function showSuccess(title, description) {
createAlert(title, description, "text-bg-success");
}
</script>

View File

@ -1,34 +0,0 @@
<div id="failed-modal" tabindex="-1" role="dialog" class="modal fade">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header bg-danger text-white">
<h4 id="failed-title" class="modal-title"></h4>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="close"></button>
</div>
<div class="modal-body">
<p id="failed-description"></p>
<p id="failed-details"></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-bs-dismiss="modal"><i class="bi bi-x"></i> close</button>
</div>
</div>
</div>
</div>
<script>
const failedModal = $("#failed-modal");
failedModal.on("hidden.bs.modal", () => { reload(); });
const failedDescription = $("#failed-description");
const failedDetails = $("#failed-details");
const failedTitle = $("#failed-title");
function showFailure(title, description, details) {
failedTitle.text(title);
failedDescription.text(description);
failedDetails.text(details);
failedModal.modal("show");
}
</script>

View File

@ -22,7 +22,7 @@
<div class="form-group row">
<div class="col-sm-2"></div>
<div class="col-sm-10">
<pre class="language-less"><code id="key-body-input" class="pre-scrollable language-less"></code><button id="key-copy-btn" type="button" class="btn language-less" onclick="copyPgpKey()"><i class="bi bi-clipboard"></i> copy</button></pre>
<pre class="language-less"><samp id="key-body-input" class="pre-scrollable language-less"></samp><button id="key-copy-btn" type="button" class="btn language-less" onclick="copyPgpKey()"><i class="bi bi-clipboard"></i> copy</button></pre>
</div>
</div>
</div>
@ -81,10 +81,11 @@
contentType: "application/json",
success: _ => {
keyImportModal.modal("hide");
showSuccess("Success", `Key ${key} has been imported`, "");
showSuccess("Success", `Key ${key} has been imported`);
},
error: (jqXHR, _, errorThrown) => {
showFailure("Action failed", `Could not import key ${key} from ${server}`, errorThrown);
const message = _ => { return `Could not import key ${key} from ${server}`; };
showFailure("Action failed", message, jqXHR, errorThrown);
},
});
}

View File

@ -60,7 +60,9 @@
const packages = packageInput.val();
if (packages) {
packageAddModal.modal("hide");
doPackageAction("/api/v1/service/add", [packages], "The following package has been added:", "Package addition failed:");
const onSuccess = update => { return `Packages ${update} have been added`; };
const onFailure = error => { return `Package addition failed: ${error}`; };
doPackageAction("/api/v1/service/add", [packages], onSuccess, onFailure);
}
}
@ -68,7 +70,9 @@
const packages = packageInput.val();
if (packages) {
packageAddModal.modal("hide");
doPackageAction("/api/v1/service/request", [packages], "The following package has been requested:", "Package request failed:");
const onSuccess = update => { return `Packages ${update} have been requested`; };
const onFailure = error => { return `Package request failed: ${error}`; };
doPackageAction("/api/v1/service/request", [packages], onSuccess, onFailure);
}
}
</script>

View File

@ -6,7 +6,7 @@
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="close"></button>
</div>
<div class="modal-body">
<pre class="language-logs"><code id="package-info-logs-input" class="pre-scrollable language-logs"></code><button id="logs-copy-btn" type="button" class="btn language-logs" onclick="copyLogs()"><i class="bi bi-clipboard"></i> copy</button></pre>
<pre class="language-logs"><samp id="package-info-logs-input" class="pre-scrollable language-logs"></samp><button id="logs-copy-btn" type="button" class="btn language-logs" onclick="copyLogs()"><i class="bi bi-clipboard"></i> copy</button></pre>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" onclick="showLogs()"><i class="bi bi-arrow-clockwise"></i> reload</button>
@ -60,7 +60,10 @@
},
error: (jqXHR, _, errorThrown) => {
// show failed modal in case if first time loading
if (isPackageBaseSet) showFailure("Load failure", `Could not load package ${packageBase} logs:`, errorThrown);
if (isPackageBaseSet) {
const message = error => { return `Could not load package ${packageBase} logs: ${error}`; };
showFailure("Load failure", message, jqXHR, errorThrown);
}
},
});
}

View File

@ -33,7 +33,9 @@
const packages = dependencyInput.val();
if (packages) {
packageRebuildModal.modal("hide");
doPackageAction("/api/v1/service/rebuild", [packages], "Repository rebuild ran for the following dependencies:", "Repository rebuild failed:");
const onSuccess = update => { return `Repository rebuild has been run for packages which depend on ${update}`; };
const onFailure = error => { return `Repository rebuild failed: ${error}`; };
doPackageAction("/api/v1/service/rebuild", [packages], onSuccess, onFailure);
}
}
</script>

View File

@ -1,34 +0,0 @@
<div id="success-modal" tabindex="-1" role="dialog" class="modal fade">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header bg-success text-white">
<h4 id="success-title" class="modal-title"></h4>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="close"></button>
</div>
<div class="modal-body">
<p id="success-description"></p>
<ul id="success-details"></ul>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-bs-dismiss="modal"><i class="bi bi-x"></i> close</button>
</div>
</div>
</div>
</div>
<script>
const successModal = $("#success-modal");
successModal.on("hidden.bs.modal", () => { reload(); });
const successDescription = $("#success-description");
const successDetails = $("#success-details");
const successTitle = $("#success-title");
function showSuccess(title, description, details) {
successTitle.text(title);
successDescription.text(description);
successDetails.empty().append(details);
successModal.modal("show");
}
</script>

View File

@ -16,7 +16,6 @@
} else showLogs(data.id);
});
const architectureBadge = $("#badge-architecture");
const repositoryBadge = $("#badge-repository");
const statusBadge = $("#badge-status");
const versionBadge = $("#badge-version");
@ -28,15 +27,11 @@
type: "POST",
contentType: "application/json",
success: _ => {
const details = packages.map(pkg => {
const li = document.createElement("li");
li.innerText = pkg;
return li;
});
showSuccess("Success", successText, details);
const message = successText(packages.join(", "));
showSuccess("Success", message);
},
error: (jqXHR, _, errorThrown) => {
showFailure("Action failed", failureText, errorThrown);
showFailure("Action failed", failureText, jqXHR, errorThrown);
},
});
}
@ -46,13 +41,18 @@
}
function removePackages() {
doPackageAction("/api/v1/service/remove", getSelection(), "The following packages have been removed:", "Packages removal failed:");
const onSuccess = update => { return `Packages ${update} have been removed`; };
const onFailure = error => { return `Could not remove packages: ${error}`; };
doPackageAction("/api/v1/service/remove", getSelection(), onSuccess, onFailure);
}
function updatePackages() {
const currentSelection = getSelection();
const url = currentSelection.length === 0 ? "/api/v1/service/update" : "/api/v1/service/add";
doPackageAction(url, getSelection(), "Packages update has been run", "Packages update failed:");
const [url, onSuccess] = currentSelection.length === 0
? ["/api/v1/service/update", _ => { return "Repository update has been run"; }]
: ["/api/v1/service/add", update => { return `Run update for packages ${update}`; }];
const onFailure = error => { return `Packages update failed: ${error}`; };
doPackageAction(url, currentSelection, onSuccess, onFailure);
}
function hideControls(hidden) {
@ -66,6 +66,14 @@
function reload() {
table.bootstrapTable("showLoading");
const badgeClass = status => {
if (status === "pending") return "btn-outline-warning";
if (status === "building") return "btn-outline-warning";
if (status === "failed") return "btn-outline-danger";
if (status === "success") return "btn-outline-success";
return "btn-outline-secondary";
};
$.ajax({
url: "/api/v1/packages",
type: "GET",
@ -112,7 +120,8 @@
table.bootstrapTable("hideLoading");
} else {
// other errors
showFailure("Load failure", "Could not load list of packages:", errorThrown);
const messaga = error => { return `Could not load list of packages: ${error}`; };
showFailure("Load failure", messaga, jqXHR, errorThrown);
}
hideControls(true);
},
@ -123,39 +132,20 @@
type: "GET",
dataType: "json",
success: response => {
const badgeColor = status => {
if (status === "pending") return "yellow";
if (status === "building") return "yellow";
if (status === "failed") return "critical";
if (status === "success") return "success";
return "inactive";
};
repositoryBadge.text(`${response.repository} ${response.architecture}`);
versionBadge.html(`<i class="bi bi-github"></i> ahriman ${safe(response.version)}`);
architectureBadge
.attr("src", `https://img.shields.io/badge/architecture-${response.architecture}-informational`)
.attr("alt", response.architecture);
repositoryBadge
.attr("src", `https://img.shields.io/badge/repository-${response.repository.replace(/-/g, "--")}-informational`)
.attr("alt", response.repository);
statusBadge
.attr("src", `https://img.shields.io/badge/service%20status-${response.status.status}-${badgeColor(response.status.status)}`)
.attr("alt", response.status.status)
.attr("title", `at ${new Date(1000 * response.status.timestamp).toISOString()}`);
versionBadge
.attr("src", `https://img.shields.io/badge/version-${response.version}-informational`)
.attr("alt", response.version);
.popover("dispose")
.attr("data-bs-content", `${response.status.status} at ${new Date(1000 * response.status.timestamp).toISOString()}`)
.popover();
statusBadge.removeClass();
statusBadge.addClass("btn");
statusBadge.addClass(badgeClass(response.status.status));
},
});
}
function safe(string) {
return String(string)
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;");
}
function statusFormat(value) {
const cellClass = status => {
if (status === "pending") return "table-warning";
@ -169,6 +159,7 @@
$(() => {
table.bootstrapTable({});
statusBadge.popover();
reload();
});
</script>

View File

@ -30,4 +30,12 @@
button.html("<i class=\"bi bi-clipboard\"></i> copy");
}, 2000);
}
function safe(string) {
return String(string)
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;");
}
</script>

View File

@ -3,7 +3,9 @@
<link rel="stylesheet" href="https://unpkg.com/bootstrap-table@1.21.1/dist/bootstrap-table.min.css" type="text/css">
<link href="https://unpkg.com/jquery-resizable-columns@0.2.3/dist/jquery.resizableColumns.css" rel="stylesheet">
<link rel="stylesheet" href="https://unpkg.com/jquery-resizable-columns@0.2.3/dist/jquery.resizableColumns.css" type="text/css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootswatch@5.2.2/dist/cosmo/bootstrap.min.css" integrity="sha256-5t++JZpgVLzo9vF7snO5Qw0y3fA5/NkoJENWB7kpg0E=" crossorigin="anonymous" type="text/css">
<style>
.pre-scrollable {
@ -16,7 +18,7 @@
position: relative;
}
pre[class*="language-"] button{
pre[class*="language-"] button {
position: absolute;
top: 0;
right: 5px;

View File

@ -52,17 +52,20 @@ setup(
"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/build-status.jinja2",
"package/share/ahriman/templates/email-index.jinja2",
@ -72,13 +75,12 @@ setup(
"package/share/ahriman/templates/telegram-index.jinja2",
]),
("share/ahriman/templates/build-status", [
"package/share/ahriman/templates/build-status/failed-modal.jinja2",
"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/success-modal.jinja2",
"package/share/ahriman/templates/build-status/table.jinja2",
]),
("share/ahriman/templates/static", [
@ -88,9 +90,17 @@ setup(
"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={
@ -104,7 +114,9 @@ setup(
"Sphinx",
"argparse-manpage",
"pydeps",
"shtab",
"sphinx-argparse",
"sphinx-rtd-theme>=1.1.1", # https://stackoverflow.com/a/74355734
"sphinxcontrib-napoleon",
],
# FIXME technically this dependency is required, but in some cases we do not have access to

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).
@ -109,6 +109,7 @@ def _parser() -> argparse.ArgumentParser:
_set_repo_sign_parser(subparsers)
_set_repo_status_update_parser(subparsers)
_set_repo_sync_parser(subparsers)
_set_repo_tree_parser(subparsers)
_set_repo_triggers_parser(subparsers)
_set_repo_update_parser(subparsers)
_set_shell_parser(subparsers)
@ -305,7 +306,8 @@ def _set_package_status_parser(root: SubParserAction) -> argparse.ArgumentParser
parser.add_argument("package", help="filter status by package base", nargs="*")
parser.add_argument("--ahriman", help="get service status itself", action="store_true")
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty", action="store_true")
parser.add_argument("-i", "--info", help="show additional package information", action="store_true")
parser.add_argument("--info", help="show additional package information",
action=argparse.BooleanOptionalAction, default=False)
parser.add_argument("-s", "--status", help="filter packages by status",
type=BuildStatusEnum, choices=enum_values(BuildStatusEnum))
parser.set_defaults(handler=handlers.Status, lock=None, report=False, quiet=True, unsafe=True)
@ -703,6 +705,23 @@ def _set_repo_sync_parser(root: SubParserAction) -> argparse.ArgumentParser:
return parser
def _set_repo_tree_parser(root: SubParserAction) -> argparse.ArgumentParser:
"""
add parser for repository tree subcommand
Args:
root(SubParserAction): subparsers for the commands
Returns:
argparse.ArgumentParser: created argument parser
"""
parser = root.add_parser("repo-tree", help="dump repository tree",
description="dump repository tree based on packages dependencies",
formatter_class=_formatter)
parser.set_defaults(handler=handlers.Structure, lock=None, report=False, quiet=True)
return parser
def _set_repo_triggers_parser(root: SubParserAction) -> argparse.ArgumentParser:
"""
add parser for repository triggers subcommand

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).
@ -37,30 +37,6 @@ class ApplicationPackages(ApplicationProperties):
package control class
"""
def _known_packages(self) -> Set[str]:
"""
load packages from repository and pacman repositories
Returns:
Set[str]: list of known packages
Raises:
NotImplementedError: not implemented method
"""
raise NotImplementedError
def on_result(self, result: Result) -> None:
"""
generate report and sync to remote server
Args:
result(Result): build result
Raises:
NotImplementedError: not implemented method
"""
raise NotImplementedError
def _add_archive(self, source: str, *_: Any) -> None:
"""
add package from archive
@ -147,6 +123,18 @@ class ApplicationPackages(ApplicationProperties):
self.database.remote_update(package)
# repository packages must not depend on unknown packages, thus we are not going to process dependencies
def _known_packages(self) -> Set[str]:
"""
load packages from repository and pacman repositories
Returns:
Set[str]: list of known packages
Raises:
NotImplementedError: not implemented method
"""
raise NotImplementedError
def _process_dependencies(self, local_dir: Path, known_packages: Set[str], without_dependencies: bool) -> None:
"""
process package dependencies
@ -178,6 +166,18 @@ class ApplicationPackages(ApplicationProperties):
fn = getattr(self, f"_add_{resolved_source.value}")
fn(name, known_packages, without_dependencies)
def on_result(self, result: Result) -> None:
"""
generate report and sync to remote server
Args:
result(Result): build result
Raises:
NotImplementedError: not implemented method
"""
raise NotImplementedError
def remove(self, names: Iterable[str]) -> None:
"""
remove packages from repository

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).
@ -50,5 +50,5 @@ class ApplicationProperties(LazyLogging):
self.configuration = configuration
self.architecture = architecture
self.database = SQLite.load(configuration)
self.repository = Repository(architecture, configuration, self.database,
report=report, unsafe=unsafe, refresh_pacman_database=refresh_pacman_database)
self.repository = Repository.load(architecture, configuration, self.database, report=report, unsafe=unsafe,
refresh_pacman_database=refresh_pacman_database)

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).
@ -33,18 +33,6 @@ class ApplicationRepository(ApplicationProperties):
repository control class
"""
def on_result(self, result: Result) -> None:
"""
generate report and sync to remote server
Args:
result(Result): build result
Raises:
NotImplementedError: not implemented method
"""
raise NotImplementedError
def clean(self, *, cache: bool, chroot: bool, manual: bool, packages: bool, pacman: bool) -> None:
"""
run all clean methods. Warning: some functions might not be available under non-root
@ -67,6 +55,18 @@ class ApplicationRepository(ApplicationProperties):
if pacman:
self.repository.clear_pacman()
def on_result(self, result: Result) -> None:
"""
generate report and sync to remote server
Args:
result(Result): build result
Raises:
NotImplementedError: not implemented method
"""
raise NotImplementedError
def sign(self, packages: Iterable[str]) -> None:
"""
sign packages and repository
@ -145,8 +145,8 @@ class ApplicationRepository(ApplicationProperties):
process_update(packages, build_result)
# process manual packages
tree = Tree.load(updates, self.repository.paths, self.database)
for num, level in enumerate(tree.levels()):
tree = Tree.resolve(updates, self.repository.paths, self.database)
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)
packages = self.repository.packages_built()
@ -181,8 +181,12 @@ class ApplicationRepository(ApplicationProperties):
local_versions = {package.base: package.version for package in self.repository.packages()}
updated_packages = [package for _, package in sorted(updates.items())]
for package in updated_packages:
UpdatePrinter(package, local_versions.get(package.base)).print(
verbose=True, log_fn=log_fn, separator=" -> ")
# reorder updates according to the dependency tree
tree = Tree.resolve(updated_packages, self.repository.paths, self.database)
for level in tree:
for package in level:
UpdatePrinter(package, local_versions.get(package.base)).print(
verbose=True, log_fn=log_fn, separator=" -> ")
return updated_packages

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).
@ -37,6 +37,7 @@ from ahriman.application.handlers.shell import Shell
from ahriman.application.handlers.sign import Sign
from ahriman.application.handlers.status import Status
from ahriman.application.handlers.status_update import StatusUpdate
from ahriman.application.handlers.structure import Structure
from ahriman.application.handlers.triggers import Triggers
from ahriman.application.handlers.unsafe_commands import UnsafeCommands
from ahriman.application.handlers.update import Update

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).
@ -71,6 +71,8 @@ class Setup(Handler):
Setup.configuration_create_sudo(application.repository.paths, args.build_command, architecture)
application.repository.repo.init()
# lazy database sync
application.repository.pacman.handle # pylint: disable=pointless-statement
@staticmethod
def build_command(root: Path, prefix: str, architecture: str) -> Path:
@ -78,7 +80,7 @@ class Setup(Handler):
generate build command name
Args:
root(Path): root directory for the build command (must be root of the reporitory)
root(Path): root directory for the build command (must be root of the repository)
prefix(str): command prefix in {prefix}-{architecture}-build
architecture(str): repository architecture

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -0,0 +1,56 @@
#
# 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 argparse
from typing import Type
from ahriman.application.application import Application
from ahriman.application.handlers import Handler
from ahriman.core.configuration import Configuration
from ahriman.core.formatters import TreePrinter
from ahriman.core.tree import Tree
class Structure(Handler):
"""
dump repository structure handler
"""
ALLOW_AUTO_ARCHITECTURE_RUN = False
@classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration, *,
report: bool, unsafe: bool) -> None:
"""
callback for command line
Args:
args(argparse.Namespace): command line args
architecture(str): repository architecture
configuration(Configuration): configuration instance
report(bool): force enable or disable reporting
unsafe(bool): if set no user check will be performed before path creation
"""
application = Application(architecture, configuration, report=report, unsafe=unsafe)
packages = application.repository.packages()
tree = Tree.resolve(packages, application.repository.paths, application.database)
for num, level in enumerate(tree):
TreePrinter(num, level).print(verbose=True, separator=" ")

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).
@ -61,7 +61,7 @@ class Versions(Handler):
Args:
root(str): root package name
root_extras(Tuple[str, ...]): extras for the root package (Default value = ())
root_extras(Tuple[str, ...], optional): extras for the root package (Default value = ())
Returns:
Dict[str, str]: map of installed dependency to its version

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).
@ -75,40 +75,6 @@ class Lock(LazyLogging):
self.paths = configuration.repository_paths
self.reporter = Client.load(configuration, report=args.report)
def __enter__(self) -> Lock:
"""
default workflow is the following:
1. Check user UID
2. Check if there is lock file
3. Check web status watcher status
4. Create lock file
5. Report to status page if enabled
"""
self.check_user()
self.check_version()
self.create()
self.reporter.update_self(BuildStatusEnum.Building)
return self
def __exit__(self, exc_type: Optional[Type[Exception]], exc_val: Optional[Exception],
exc_tb: TracebackType) -> Literal[False]:
"""
remove lock file when done
Args:
exc_type(Optional[Type[Exception]]): exception type name if any
exc_val(Optional[Exception]): exception raised if any
exc_tb(TracebackType): exception traceback if any
Returns:
Literal[False]: always False (do not suppress any exception)
"""
self.clear()
status = BuildStatusEnum.Success if exc_val is None else BuildStatusEnum.Failed
self.reporter.update_self(status)
return False
def check_version(self) -> None:
"""
check web server version
@ -145,3 +111,37 @@ class Lock(LazyLogging):
self.path.touch(exist_ok=self.force)
except FileExistsError:
raise DuplicateRunError()
def __enter__(self) -> Lock:
"""
default workflow is the following:
1. Check user UID
2. Check if there is lock file
3. Check web status watcher status
4. Create lock file
5. Report to status page if enabled
"""
self.check_user()
self.check_version()
self.create()
self.reporter.update_self(BuildStatusEnum.Building)
return self
def __exit__(self, exc_type: Optional[Type[Exception]], exc_val: Optional[Exception],
exc_tb: TracebackType) -> Literal[False]:
"""
remove lock file when done
Args:
exc_type(Optional[Type[Exception]]): exception type name if any
exc_val(Optional[Exception]): exception raised if any
exc_tb(TracebackType): exception traceback if any
Returns:
Literal[False]: always False (do not suppress any exception)
"""
self.clear()
status = BuildStatusEnum.Success if exc_val is None else BuildStatusEnum.Failed
self.reporter.update_self(status)
return False

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).
@ -17,3 +17,82 @@
# 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 contextvars import ContextVar
from typing import Any, Dict, Iterator, TypeVar
from ahriman.models.context_key import ContextKey
T = TypeVar("T")
class _Context:
"""
simple ahriman global context implementation
"""
def __init__(self) -> None:
"""
default constructor. Must not be used directly
"""
self._content: Dict[str, Any] = {}
def get(self, key: ContextKey[T]) -> T:
"""
get value for the specified key
Args:
key(ContextKey[T]): context key name
Returns:
T: value associated with the key
Raises:
KeyError: in case if the specified context variable was not found
ValueError: in case if type of value is not an instance of specified return type
"""
if key.key not in self._content:
raise KeyError(key.key)
value = self._content[key.key]
if not isinstance(value, key.return_type):
raise ValueError(f"Value {value} is not an instance of {key.return_type}")
return value
def set(self, key: ContextKey[T], value: T) -> None:
"""
set value for the specified key
Args:
key(ContextKey[T]): context key name
value(T): context value associated with the specified key
Raises:
KeyError: in case if the specified context variable already exists
ValueError: in case if type of value is not an instance of specified return type
"""
if key.key in self._content:
raise KeyError(key.key)
if not isinstance(value, key.return_type):
raise ValueError(f"Value {value} is not an instance of {key.return_type}")
self._content[key.key] = value
def __iter__(self) -> Iterator[str]:
"""
iterate over keys in local storage
Returns:
str: context key iterator
"""
return iter(self._content)
def __len__(self) -> int:
"""
get count of the context variables set
Returns:
int: count of stored context variables
"""
return len(self._content)
context = ContextVar("context", default=_Context())

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).
@ -21,7 +21,7 @@ import shutil
from pathlib import Path
from pyalpm import DB, Handle, Package, SIG_PACKAGE, error as PyalpmError # type: ignore
from typing import Generator, Set
from typing import Any, Callable, Generator, Set
from ahriman.core.configuration import Configuration
from ahriman.core.log import LazyLogging
@ -36,6 +36,8 @@ class Pacman(LazyLogging):
handle(Handle): pyalpm root ``Handle``
"""
handle: Handle
def __init__(self, architecture: str, configuration: Configuration, *, refresh_database: int) -> None:
"""
default constructor
@ -46,6 +48,22 @@ class Pacman(LazyLogging):
refresh_database(int): synchronize local cache to remote. If set to ``0``, no syncronization will be
enabled, if set to ``1`` - normal syncronization, if set to ``2`` - force syncronization
"""
self.__create_handle_fn: Callable[[], Handle] = lambda: self.__create_handle(
architecture, configuration, refresh_database=refresh_database)
def __create_handle(self, architecture: str, configuration: Configuration, *, refresh_database: int) -> Handle:
"""
create lazy handle function
Args:
architecture(str): repository architecture
configuration(Configuration): configuration instance
refresh_database(int): synchronize local cache to remote. If set to ``0``, no syncronization will be
enabled, if set to ``1`` - normal syncronization, if set to ``2`` - force syncronization
Returns:
Handle: fully initialized pacman handle
"""
root = configuration.getpath("alpm", "root")
pacman_root = configuration.getpath("alpm", "database")
use_ahriman_cache = configuration.getboolean("alpm", "use_ahriman_cache")
@ -53,20 +71,23 @@ class Pacman(LazyLogging):
paths = configuration.repository_paths
database_path = paths.pacman if use_ahriman_cache else pacman_root
self.handle = Handle(str(root), str(database_path))
handle = Handle(str(root), str(database_path))
for repository in configuration.getlist("alpm", "repositories"):
database = self.database_init(repository, mirror, architecture)
self.database_copy(database, pacman_root, paths, use_ahriman_cache=use_ahriman_cache)
database = self.database_init(handle, repository, mirror, architecture)
self.database_copy(handle, database, pacman_root, paths, use_ahriman_cache=use_ahriman_cache)
if use_ahriman_cache and refresh_database:
self.database_sync(refresh_database > 1)
self.database_sync(handle, force=refresh_database > 1)
def database_copy(self, database: DB, pacman_root: Path, paths: RepositoryPaths, *,
return handle
def database_copy(self, handle: Handle, database: DB, pacman_root: Path, paths: RepositoryPaths, *,
use_ahriman_cache: bool) -> None:
"""
copy database from the operating system root to the ahriman local home
Args:
handle(Handle): pacman handle which will be used for database copying
database(DB): pacman database instance to be copied
pacman_root(Path): operating system pacman root
paths(RepositoryPaths): repository paths instance
@ -78,7 +99,7 @@ class Pacman(LazyLogging):
if not use_ahriman_cache:
return
# copy root database if no local copy found
pacman_db_path = Path(self.handle.dbpath)
pacman_db_path = Path(handle.dbpath)
if not pacman_db_path.is_dir():
return # root directory does not exist yet
dst = repository_database(pacman_db_path)
@ -92,11 +113,12 @@ class Pacman(LazyLogging):
shutil.copy(src, dst)
paths.chown(dst)
def database_init(self, repository: str, mirror: str, architecture: str) -> DB:
def database_init(self, handle: Handle, repository: str, mirror: str, architecture: str) -> DB:
"""
create database instance from pacman handler and set its properties
Args:
handle(Handle): pacman handle which will be used for database initializing
repository(str): pacman repository name (e.g. core)
mirror(str): arch linux mirror url
architecture(str): repository architecture
@ -104,21 +126,23 @@ class Pacman(LazyLogging):
Returns:
DB: loaded pacman database instance
"""
database: DB = self.handle.register_syncdb(repository, SIG_PACKAGE)
self.logger.info("loading pacman databases")
database: DB = handle.register_syncdb(repository, SIG_PACKAGE)
# replace variables in mirror address
database.servers = [mirror.replace("$repo", repository).replace("$arch", architecture)]
return database
def database_sync(self, force: bool) -> None:
def database_sync(self, handle: Handle, *, force: bool) -> None:
"""
sync local database
Args:
handle(Handle): pacman handle which will be used for database sync
force(bool): force database syncronization (same as ``pacman -Syy``)
"""
self.logger.info("refresh ahriman's home pacman database (force refresh %s)", force)
transaction = self.handle.init_transaction()
for database in self.handle.get_syncdbs():
transaction = handle.init_transaction()
for database in handle.get_syncdbs():
try:
database.update(force)
except PyalpmError:
@ -155,3 +179,22 @@ class Pacman(LazyLogging):
result.update(package.provides) # provides list for meta-packages
return result
def __getattr__(self, item: str) -> Any:
"""
pacman handle extractor
Args:
item(str): property name
Returns:
Any: attribute by its name
Raises:
AttributeError: in case if no such attribute found
"""
if item == "handle":
handle = self.__create_handle_fn()
setattr(self, item, handle)
return handle
return super().__getattr__(item) # required for logging attribute

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).
@ -72,7 +72,7 @@ class Remote(LazyLogging):
"""
instance = cls()
packages: Dict[str, AURPackage] = {}
for term in filter(lambda word: len(word) > 3, keywords):
for term in filter(lambda word: len(word) >= 3, keywords):
portion = instance.search(term, pacman=pacman)
packages = {
package.name: package # not mistake to group them by name

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).
@ -17,14 +17,13 @@
# 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 datetime
import shutil
from pathlib import Path
from typing import List, Optional
from ahriman.core.log import LazyLogging
from ahriman.core.util import check_output, walk
from ahriman.core.util import check_output, utcnow, walk
from ahriman.models.package import Package
from ahriman.models.pkgbuild_patch import PkgbuildPatch
from ahriman.models.remote_source import RemoteSource
@ -215,7 +214,7 @@ class Sources(LazyLogging):
author(Optional[str], optional): optional commit author if any (Default value = None)
"""
if message is None:
message = f"Autogenerated commit at {datetime.datetime.utcnow()}"
message = f"Autogenerated commit at {utcnow()}"
args = ["--allow-empty", "--message", message]
if author is not None:
args.extend(["--author", author])

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2021-2022 ahriman team.
# Copyright (c) 2021-2023 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).

Some files were not shown because too many files have changed in this diff Show More