mirror of
https://github.com/arcan1s/ahriman.git
synced 2025-05-03 19:53:49 +00:00
Compare commits
7 Commits
8b26035fc9
...
8cafdb52e5
Author | SHA1 | Date | |
---|---|---|---|
8cafdb52e5 | |||
203ebad817 | |||
9f471d11a7 | |||
2ea8a4a07f | |||
856bbc30d4 | |||
c88f97c36e | |||
174d7578a0 |
@ -83,6 +83,7 @@ limit-inference-results=100
|
||||
# usually to register additional checkers.
|
||||
load-plugins=pylint.extensions.docparams,
|
||||
definition_order,
|
||||
import_order,
|
||||
|
||||
# Pickle collected data for later comparisons.
|
||||
persistent=yes
|
||||
|
File diff suppressed because it is too large
Load Diff
Before Width: | Height: | Size: 993 KiB After Width: | Height: | Size: 1.2 MiB |
@ -39,9 +39,9 @@ It will check current settings on common errors and compare configuration with k
|
||||
|
||||
Base configuration settings.
|
||||
|
||||
* ``apply_migrations`` - perform migrations on application start, boolean, optional, default ``yes``. Useful if you are using git version. Note, however, that this option must be changed only if you know what to do and going to handle migrations manually.
|
||||
* ``database`` - path to SQLite database, string, required.
|
||||
* ``include`` - path to directory with configuration files overrides, string, optional.
|
||||
* ``apply_migrations`` - perform database migrations on the application start, boolean, optional, default ``yes``. Useful if you are using git version. Note, however, that this option must be changed only if you know what to do and going to handle migrations manually.
|
||||
* ``database`` - path to the application SQLite database, string, required.
|
||||
* ``include`` - path to directory with configuration files overrides, string, optional. Files will be read in alphabetical order.
|
||||
* ``logging`` - path to logging configuration, string, required. Check ``logging.ini`` for reference.
|
||||
|
||||
``alpm:*`` groups
|
||||
@ -51,9 +51,9 @@ libalpm and AUR related configuration. Group name can refer to architecture, e.g
|
||||
|
||||
* ``database`` - path to pacman system database cache, string, required.
|
||||
* ``mirror`` - package database mirror used by pacman for synchronization, string, required. This option supports standard pacman substitutions with ``$arch`` and ``$repo``. Note that the mentioned mirror should contain all repositories which are set by ``alpm.repositories`` option.
|
||||
* ``repositories`` - list of pacman repositories, space separated list of strings, required.
|
||||
* ``root`` - root for alpm library, string, required.
|
||||
* ``use_ahriman_cache`` - use local pacman package cache instead of system one, boolean, required. With this option enabled you might want to refresh database periodically (available as additional flag for some subcommands).
|
||||
* ``repositories`` - list of pacman repositories, used for package search, space separated list of strings, required.
|
||||
* ``root`` - root for alpm library, string, required. In the most cases it must point to the system root.
|
||||
* ``use_ahriman_cache`` - use local pacman package cache instead of system one, boolean, required. With this option enabled you might want to refresh database periodically (available as additional flag for some subcommands). If set to ``no``, databases must be synchronized manually.
|
||||
|
||||
``auth`` group
|
||||
--------------
|
||||
@ -64,7 +64,7 @@ Base authorization settings. ``OAuth`` provider requires ``aioauth-client`` libr
|
||||
* ``allow_read_only`` - allow requesting status APIs without authorization, boolean, required.
|
||||
* ``client_id`` - OAuth2 application client ID, string, required in case if ``oauth`` is used.
|
||||
* ``client_secret`` - OAuth2 application client secret key, string, required in case if ``oauth`` is used.
|
||||
* ``cookie_secret_key`` - secret key which will be used for cookies encryption, string, optional. It must be 32 URL-safe base64-encoded bytes and can be generated as following ``base64.urlsafe_b64encode(os.urandom(32)).decode("utf8")``. If not set, it will be generated automatically; note, however, that in this case, all sessions will be automatically invalidated during the service restart.
|
||||
* ``cookie_secret_key`` - secret key which will be used for cookies encryption, string, optional. It must be 32 bytes URL-safe base64-encoded and can be generated as following ``base64.urlsafe_b64encode(os.urandom(32)).decode("utf8")``. If not set, it will be generated automatically; note, however, that in this case, all sessions will be automatically invalidated during the service restart.
|
||||
* ``max_age`` - parameter which controls both cookie expiration and token expiration inside the service in seconds, integer, optional, default is 7 days.
|
||||
* ``oauth_icon`` - OAuth2 login button icon, string, optional, default is ``google``. Must be valid `Bootstrap icon <https://icons.getbootstrap.com/>`__ name.
|
||||
* ``oauth_provider`` - OAuth2 provider class name as is in ``aioauth-client`` (e.g. ``GoogleClient``, ``GithubClient`` etc), string, required in case if ``oauth`` is used.
|
||||
@ -148,7 +148,7 @@ Keyring generator plugin
|
||||
* ``homepage`` - URL to homepage location if any, string, optional.
|
||||
* ``license`` - list of licenses which are applied to this package, space separated list of strings, optional, default is ``Unlicense``.
|
||||
* ``package`` - keyring package name, string, optional, default is ``repo-keyring``, where ``repo`` is the repository name.
|
||||
* ``packagers`` - list of packagers keys, space separated list of strings, optional, if not set, the ``key_*`` options from ``sign`` group will be used.
|
||||
* ``packagers`` - list of packagers keys, space separated list of strings, optional, if not set, the user keys from database will be used.
|
||||
* ``revoked`` - list of revoked packagers keys, space separated list of strings, optional.
|
||||
* ``trusted`` - list of master keys, space separated list of strings, optional, if not set, the ``key`` option from ``sign`` group will be used.
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
# Maintainer: Evgeniy Alekseev
|
||||
|
||||
pkgname='ahriman'
|
||||
pkgver=2.12.2
|
||||
pkgver=2.13.0
|
||||
pkgrel=1
|
||||
pkgdesc="ArcH linux ReposItory MANager"
|
||||
arch=('any')
|
||||
|
@ -1,85 +1,352 @@
|
||||
[settings]
|
||||
; Relative path to directory with configuration files overrides. Overrides will be applied in alphabetic order.
|
||||
include = ahriman.ini.d
|
||||
; Relative path to configuration used by logging package.
|
||||
logging = ahriman.ini.d/logging.ini
|
||||
apply_migrations = yes
|
||||
; Perform database migrations on the application start. Do not touch this option unless you know what are you doing.
|
||||
;apply_migrations = yes
|
||||
; Path to the application SQLite database.
|
||||
database = /var/lib/ahriman/ahriman.db
|
||||
|
||||
[alpm]
|
||||
; Path to pacman system database cache.
|
||||
database = /var/lib/pacman
|
||||
; Arch linux mirror used by local pacman for synchronization.
|
||||
mirror = https://geo.mirror.pkgbuild.com/$repo/os/$arch
|
||||
; Space separated list of pacman repositories to search for packages.
|
||||
repositories = core extra multilib
|
||||
; Pacman's root directory. In the most cases it must point to the system root.
|
||||
root = /
|
||||
; Use local packages cache. If this option is enabled, the service will be able to synchronize databases (available
|
||||
; as additional option for some subcommands). If set to no, databases must be synchronized manually.
|
||||
use_ahriman_cache = yes
|
||||
|
||||
[auth]
|
||||
; Authentication provider, must be one of disabled, configuration, oauth.
|
||||
target = disabled
|
||||
max_age = 604800
|
||||
oauth_provider = GoogleClient
|
||||
oauth_scopes = https://www.googleapis.com/auth/userinfo.email
|
||||
; Allow read-only endpoint to be called without authentication.
|
||||
allow_read_only = yes
|
||||
; OAuth2 application client ID and secret. Required if oauth is used.
|
||||
;client_id =
|
||||
;client_secret =
|
||||
; Cookie secret key to be used for cookies encryption. Must be valid 32 bytes URL-safe base64-encoded string.
|
||||
; If not set, it will be generated automatically.
|
||||
;cookie_secret_key =
|
||||
; Authentication cookie expiration in seconds.
|
||||
;max_age = 604800
|
||||
; OAuth2 provider icon for the web interface.
|
||||
;oauth_icon = google
|
||||
; OAuth2 provider class name, one of provided by aioauth-client. Required if oauth is used.
|
||||
;oauth_provider = GoogleClient
|
||||
; Scopes list for OAuth2 provider. Required if oauth is used.
|
||||
;oauth_scopes = https://www.googleapis.com/auth/userinfo.email
|
||||
; Optional password salt.
|
||||
;salt =
|
||||
|
||||
[build]
|
||||
archbuild_flags =
|
||||
ignore_packages =
|
||||
makechrootpkg_flags =
|
||||
; List of additional flags passed to archbuild command.
|
||||
;archbuild_flags =
|
||||
; List of packages to be ignored during automatic updates.
|
||||
;ignore_packages =
|
||||
; List of additional flags passed to makechrootpkg command.
|
||||
;makechrootpkg_flags =
|
||||
; List of additional flags passed to makepkg command.
|
||||
makepkg_flags = --nocolor --ignorearch
|
||||
; List of enabled triggers in the order of calls.
|
||||
triggers = ahriman.core.gitremote.RemotePullTrigger ahriman.core.report.ReportTrigger ahriman.core.upload.UploadTrigger ahriman.core.gitremote.RemotePushTrigger
|
||||
; List of well-known triggers. Used only for configuration purposes.
|
||||
triggers_known = ahriman.core.distributed.WorkerLoaderTrigger ahriman.core.distributed.WorkerRegisterTrigger ahriman.core.distributed.WorkerTrigger ahriman.core.distributed.WorkerUnregisterTrigger ahriman.core.gitremote.RemotePullTrigger ahriman.core.gitremote.RemotePushTrigger ahriman.core.report.ReportTrigger ahriman.core.upload.UploadTrigger ahriman.core.support.KeyringTrigger ahriman.core.support.MirrorlistTrigger
|
||||
vcs_allowed_age = 604800
|
||||
; Maximal age in seconds of the VCS packages before their version will be updated with its remote source.
|
||||
;vcs_allowed_age = 604800
|
||||
; List of worker nodes addresses used for build process, e.g.:
|
||||
; workers = http://10.0.0.1:8080 http://10.0.0.3:8080
|
||||
; Empty list means run on the local instance.
|
||||
;workers =
|
||||
|
||||
[repository]
|
||||
; Application root.
|
||||
root = /var/lib/ahriman
|
||||
|
||||
[sign]
|
||||
; Enable repository or package signing. Must be one of repository, package.
|
||||
target =
|
||||
|
||||
[keyring]
|
||||
target =
|
||||
|
||||
[mirrorlist]
|
||||
target =
|
||||
|
||||
[remote-pull]
|
||||
target =
|
||||
|
||||
[remote-push]
|
||||
target =
|
||||
|
||||
[report]
|
||||
target = console
|
||||
|
||||
[console]
|
||||
use_utf = yes
|
||||
|
||||
[email]
|
||||
no_empty_report = yes
|
||||
template = email-index.jinja2
|
||||
templates = /usr/share/ahriman/templates
|
||||
ssl = disabled
|
||||
|
||||
[html]
|
||||
template = repo-index.jinja2
|
||||
templates = /usr/share/ahriman/templates
|
||||
; PGP key used for signing as default.
|
||||
;key =
|
||||
|
||||
[status]
|
||||
; Global switch to enable or disable status reporting.
|
||||
enabled = yes
|
||||
; Address of the remote service, e.g.:
|
||||
; address = http://1.0.0.1:8080
|
||||
; In case if unix sockets are used, it might point to the valid socket with encoded path, e.g.:
|
||||
; address = http+unix://%2Fvar%2Flib%2Fahriman%2Fsocket
|
||||
;address =
|
||||
; Optional password for authentication (if enabled).
|
||||
;password =
|
||||
; Do not log HTTP errors if occurs.
|
||||
suppress_http_log_errors = yes
|
||||
|
||||
[telegram]
|
||||
template = telegram-index.jinja2
|
||||
templates = /usr/share/ahriman/templates
|
||||
|
||||
[upload]
|
||||
target =
|
||||
|
||||
[rsync]
|
||||
command = rsync --archive --compress --partial --delete
|
||||
|
||||
[s3]
|
||||
chunk_size = 8388608
|
||||
; HTTP request timeout in seconds.
|
||||
;timeout = 30
|
||||
; Optional username for authentication (if enabled).
|
||||
;username =
|
||||
|
||||
[web]
|
||||
; External address of the web service. Will be used for some features like OAuth. If none set will be generated as
|
||||
; address = http://web.host:web.port
|
||||
;address =
|
||||
; Enable file upload endpoint used by some triggers.
|
||||
;enable_archive_upload = no
|
||||
; Address to bind the server.
|
||||
host = 127.0.0.1
|
||||
; Full URL to the repository index page used by templates.
|
||||
;index_url =
|
||||
; Max file size in bytes which can be uploaded to the server.
|
||||
;max_body_size =
|
||||
; Port to listen. Must be set, if the web service is enabled.
|
||||
;port =
|
||||
; Disable status (e.g. package status, logs, etc) endpoints. Useful for build only modes.
|
||||
;service_only = no
|
||||
; Path to directory with static files.
|
||||
static_path = /usr/share/ahriman/templates/static
|
||||
; List of directories with templates.
|
||||
templates = /usr/share/ahriman/templates
|
||||
unix_socket_unsafe = yes
|
||||
; Path to unix socket. If none set, unix socket will be disabled.
|
||||
;unix_socket =
|
||||
; Allow unix socket to be world readable.
|
||||
;unix_socket_unsafe = yes
|
||||
; Maximum amount of time in seconds to be waited before lock will be free, used by spawned processes (0 is infinite).
|
||||
;wait_timeout =
|
||||
|
||||
[keyring]
|
||||
; List of configuration section names for keyring generator plugin, e.g.:
|
||||
; target = keyring-trigger
|
||||
target =
|
||||
|
||||
; Keyring generator trigger sample.
|
||||
;[keyring-trigger]
|
||||
; Generator type name.
|
||||
;type = keyring-generator
|
||||
; Optional keyring package description.
|
||||
;description=
|
||||
; Optional URL to the repository homepage.
|
||||
;homepage=
|
||||
; Keyring package licenses list.
|
||||
;license = Unlicense
|
||||
; Optional keyring package name.
|
||||
;package =
|
||||
; Optional packager PGP keys list. If none set, it will read from database.
|
||||
;packagers =
|
||||
; List of revoked PGP keys.
|
||||
;revoked =
|
||||
; List of master PGP keys. If none set, the sign.key value will be used.
|
||||
;trusted =
|
||||
|
||||
[mirrorlist]
|
||||
; List of configuration section names for mirrorlist generator plugin, e.g.:
|
||||
; target = mirrorlist-trigger
|
||||
target =
|
||||
|
||||
; Mirror list generator trigger sample.
|
||||
;[mirrorlist-trigger]
|
||||
; Generator type name.
|
||||
;type = mirrorlist-generator
|
||||
; Optional mirrorlist package description.
|
||||
;description=
|
||||
; Optional URL to the repository homepage.
|
||||
;homepage=
|
||||
; Mirrorlist package licenses list.
|
||||
;license = Unlicense
|
||||
; Optional mirrorlist package name.
|
||||
;package =
|
||||
; Absolute path to generated mirrorlist file, usually path inside /etc/pacman.d directory.
|
||||
;path =
|
||||
; List of repository mirrors.
|
||||
;servers =
|
||||
|
||||
[remote-pull]
|
||||
; List of configuration section names for git remote pull plugin, e.g.:
|
||||
; target = remote-pull-trigger
|
||||
target =
|
||||
|
||||
; git remote pull trigger sample.
|
||||
;[remote-pull-trigger]
|
||||
; Valid URL to pull repository, e.g.:
|
||||
; pull_url = https://github.com/arcan1s/arcanisrepo.git
|
||||
;pull_url =
|
||||
; Remote branch to pull.
|
||||
;pull_branch = master
|
||||
|
||||
[remote-push]
|
||||
; List of configuration section names for git remote push plugin, e.g.:
|
||||
; target = remote-push-trigger
|
||||
target =
|
||||
|
||||
; git remote push trigger sample.
|
||||
;[remote-push-trigger]
|
||||
; Author commit email.
|
||||
;commit_email = ahriman@localhost
|
||||
; Author commit user.
|
||||
;commit_user = ahriman
|
||||
; Valid URL to push repository, e.g.:
|
||||
; push_url = https://key:token@github.com/arcan1s/arcanisrepo.git
|
||||
; Note, that more likely authentication must be enabled.
|
||||
;push_url =
|
||||
; Remote branch to push.
|
||||
;push_branch = master
|
||||
|
||||
[report]
|
||||
; List of configuration section names for reporting plugin.
|
||||
target = console
|
||||
|
||||
; Console reporting trigger configuration sample.
|
||||
[console]
|
||||
; Trigger type name
|
||||
;type = console
|
||||
; Use utf8 symbols in output.
|
||||
use_utf = yes
|
||||
|
||||
; Email reporting trigger configuration sample.
|
||||
[email]
|
||||
; Trigger type name
|
||||
;type = email
|
||||
; Optional URL to the repository homepage.
|
||||
;homepage=
|
||||
; SMTP server address.
|
||||
;host =
|
||||
; Prefix for packages links. Link to a package will be formed as link_path / filename.
|
||||
;link_path =
|
||||
; Skip report generation if no packages were updated.
|
||||
;no_empty_report = yes
|
||||
; SMTP password.
|
||||
;password =
|
||||
; SMTP server port.
|
||||
;port =
|
||||
; List of emails to receive the reports.
|
||||
;receivers =
|
||||
; Sender email.
|
||||
;sender =
|
||||
; SMTP server SSL mode, one of ssl, starttls, disabled.
|
||||
;ssl = disabled
|
||||
; Template name to be used.
|
||||
template = email-index.jinja2
|
||||
; Template name to be used for full packages list generation (same as HTML report).
|
||||
;template_full =
|
||||
; List of directories with templates.
|
||||
templates = /usr/share/ahriman/templates
|
||||
; SMTP user.
|
||||
;user =
|
||||
|
||||
; HTML reporting trigger configuration sample.
|
||||
[html]
|
||||
; Trigger type name
|
||||
;type = html
|
||||
; Optional URL to the repository homepage.
|
||||
;homepage=
|
||||
; Prefix for packages links. Link to a package will be formed as link_path / filename.
|
||||
;link_path =
|
||||
; Output path for the HTML report.
|
||||
;path =
|
||||
; Template name to be used.
|
||||
template = repo-index.jinja2
|
||||
; List of directories with templates.
|
||||
templates = /usr/share/ahriman/templates
|
||||
|
||||
; Remote service callback trigger configuration sample.
|
||||
[remote-call]
|
||||
; Trigger type name
|
||||
;type = remote-call
|
||||
; Call for AUR packages update.
|
||||
;aur = no
|
||||
; Call for local packages update.
|
||||
;local = no
|
||||
; Call for manual packages update.
|
||||
;manual = no
|
||||
; Wait until remote process will be terminated in seconds.
|
||||
;wait_timeout = -1
|
||||
|
||||
; Telegram reporting trigger configuration sample.
|
||||
[telegram]
|
||||
; Trigger type name
|
||||
;type = telegram
|
||||
; Telegram bot API key.
|
||||
;api_key =
|
||||
; Telegram chat ID.
|
||||
;chat_id =
|
||||
; Optional URL to the repository homepage.
|
||||
;homepage=
|
||||
; Prefix for packages links. Link to a package will be formed as link_path / filename.
|
||||
;link_path =
|
||||
; Template name to be used.
|
||||
template = telegram-index.jinja2
|
||||
; Telegram specific template mode, one of MarkdownV2, HTML or Markdown.
|
||||
;template_type = HTML
|
||||
; List of directories with templates.
|
||||
templates = /usr/share/ahriman/templates
|
||||
; HTTP request timeout in seconds.
|
||||
;timeout = 30
|
||||
|
||||
[upload]
|
||||
; List of configuration section names for remote upload plugin, e.g.:
|
||||
; target = rsync s3
|
||||
target =
|
||||
|
||||
; GitHub upload trigger configuration sample.
|
||||
[github]
|
||||
; Trigger type name
|
||||
;type = github
|
||||
; GitHub repository owner username.
|
||||
;owner =
|
||||
; GitHub API key. public_repo (repo) scope is required.
|
||||
;password =
|
||||
; GitHub repository name.
|
||||
;repository =
|
||||
; HTTP request timeout in seconds.
|
||||
;timeout = 30
|
||||
; Include repository name to release name (recommended).
|
||||
;use_full_release_name = no
|
||||
; GitHub authentication username.
|
||||
;username =
|
||||
|
||||
; Remote instance upload trigger configuration sample.
|
||||
[remote-service]
|
||||
; Trigger type name
|
||||
;type = remote-service
|
||||
; HTTP request timeout in seconds.
|
||||
;timeout = 30
|
||||
|
||||
; rsync upload trigger configuration sample.
|
||||
[rsync]
|
||||
; Trigger type name
|
||||
;type = rsync
|
||||
; rsync command to run.
|
||||
command = rsync --archive --compress --partial --delete
|
||||
; Remote address and directory to sync, e.g.:
|
||||
; remote = ahriman@10.0.0.1:/srv/repo
|
||||
;remote =
|
||||
|
||||
; S3 upload trigger configuration sample.
|
||||
[s3]
|
||||
; Trigger type name
|
||||
;type = s3
|
||||
; AWS services access key.
|
||||
;access_key =
|
||||
; AWS S3 bucket name.
|
||||
;bucket =
|
||||
; Chunk size tp calculate ETags. Do not edit this value.
|
||||
;chunk_size = 8388608
|
||||
; Optional path prefix for stored objects.
|
||||
;object_path =
|
||||
; AWS S3 bucket region.
|
||||
;region =
|
||||
; AWS services secret key.
|
||||
;secret_key =
|
||||
|
||||
; Remote worker configuration sample.
|
||||
;[worker]
|
||||
; Remotely reachable address of this instance, e.g.:
|
||||
; address = http://10.0.0.1:8080
|
||||
;address =
|
||||
; Unique identifier of this instance if any.
|
||||
;identifier =
|
||||
; Maximum amount of time in seconds after which worker will be considered offline in case of no reports.
|
||||
;time_to_live = 60
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH AHRIMAN "1" "2024\-01\-02" "ahriman" "Generated Python Manual"
|
||||
.TH AHRIMAN "1" "2024\-01\-05" "ahriman" "Generated Python Manual"
|
||||
.SH NAME
|
||||
ahriman
|
||||
.SH SYNOPSIS
|
||||
|
@ -25,19 +25,19 @@ from pylint.lint import PyLinter
|
||||
from typing import Any
|
||||
|
||||
|
||||
class MethodTypeOrder(StrEnum):
|
||||
class MethodType(StrEnum):
|
||||
"""
|
||||
method type enumeration
|
||||
|
||||
Attributes:
|
||||
Class(MethodTypeOrder): (class attribute) class method
|
||||
Delete(MethodTypeOrder): (class attribute) destructor-like methods
|
||||
Init(MethodTypeOrder): (class attribute) initialization method
|
||||
Magic(MethodTypeOrder): (class attribute) other magical methods
|
||||
New(MethodTypeOrder): (class attribute) constructor method
|
||||
Normal(MethodTypeOrder): (class attribute) usual method
|
||||
Property(MethodTypeOrder): (class attribute) property method
|
||||
Static(MethodTypeOrder): (class attribute) static method
|
||||
Class(MethodType): (class attribute) class method
|
||||
Delete(MethodType): (class attribute) destructor-like methods
|
||||
Init(MethodType): (class attribute) initialization method
|
||||
Magic(MethodType): (class attribute) other magical methods
|
||||
New(MethodType): (class attribute) constructor method
|
||||
Normal(MethodType): (class attribute) usual method
|
||||
Property(MethodType): (class attribute) property method
|
||||
Static(MethodType): (class attribute) static method
|
||||
"""
|
||||
|
||||
Class = "classmethod"
|
||||
@ -59,20 +59,20 @@ class DefinitionOrder(BaseRawFileChecker):
|
||||
"""
|
||||
|
||||
DECORATED_METHODS_ORDER = {
|
||||
"cached_property": MethodTypeOrder.Property,
|
||||
"classmethod": MethodTypeOrder.Class,
|
||||
"property": MethodTypeOrder.Property,
|
||||
"staticmethod": MethodTypeOrder.Static,
|
||||
"cached_property": MethodType.Property,
|
||||
"classmethod": MethodType.Class,
|
||||
"property": MethodType.Property,
|
||||
"staticmethod": MethodType.Static,
|
||||
}
|
||||
|
||||
name = "method-ordering"
|
||||
msgs = {
|
||||
"W6001": (
|
||||
"Invalid method order %s, expected %s",
|
||||
"methods-out-of-order",
|
||||
"Methods are defined out of recommended order.",
|
||||
)
|
||||
),
|
||||
}
|
||||
name = "method-ordering"
|
||||
options = (
|
||||
(
|
||||
"method-type-order",
|
||||
@ -114,7 +114,7 @@ class DefinitionOrder(BaseRawFileChecker):
|
||||
return list(filter(is_defined_function, source))
|
||||
|
||||
@staticmethod
|
||||
def resolve_type(function: nodes.FunctionDef) -> MethodTypeOrder:
|
||||
def resolve_type(function: nodes.FunctionDef) -> MethodType:
|
||||
"""
|
||||
resolve type of the function
|
||||
|
||||
@ -122,15 +122,15 @@ class DefinitionOrder(BaseRawFileChecker):
|
||||
function(nodes.FunctionDef): function definition
|
||||
|
||||
Returns:
|
||||
MethodTypeOrder: resolved function type
|
||||
MethodType: resolved function type
|
||||
"""
|
||||
# init methods
|
||||
if function.name in ("__init__", "__post_init__"):
|
||||
return MethodTypeOrder.Init
|
||||
return MethodType.Init
|
||||
if function.name in ("__new__",):
|
||||
return MethodTypeOrder.New
|
||||
return MethodType.New
|
||||
if function.name in ("__del__",):
|
||||
return MethodTypeOrder.Delete
|
||||
return MethodType.Delete
|
||||
|
||||
# decorated methods
|
||||
decorators = []
|
||||
@ -142,10 +142,10 @@ class DefinitionOrder(BaseRawFileChecker):
|
||||
|
||||
# magic methods
|
||||
if function.name.startswith("__") and function.name.endswith("__"):
|
||||
return MethodTypeOrder.Magic
|
||||
return MethodType.Magic
|
||||
|
||||
# normal method
|
||||
return MethodTypeOrder.Normal
|
||||
return MethodType.Normal
|
||||
|
||||
def check_class(self, clazz: nodes.ClassDef) -> None:
|
||||
"""
|
||||
@ -184,7 +184,7 @@ class DefinitionOrder(BaseRawFileChecker):
|
||||
try:
|
||||
function_type_index = self.linter.config.method_type_order.index(function_type)
|
||||
except ValueError:
|
||||
function_type_index = 10 # not in the list
|
||||
function_type_index = len(self.linter.config.method_type_order) # not in the list
|
||||
|
||||
return function_type_index, function.name
|
||||
|
||||
|
196
pylint_plugins/import_order.py
Normal file
196
pylint_plugins/import_order.py
Normal file
@ -0,0 +1,196 @@
|
||||
#
|
||||
# Copyright (c) 2021-2023 ahriman team.
|
||||
#
|
||||
# This file is part of ahriman
|
||||
# (see https://github.com/arcan1s/ahriman).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from astroid import nodes
|
||||
from collections.abc import Iterable
|
||||
from enum import StrEnum
|
||||
from pylint.checkers import BaseRawFileChecker
|
||||
from pylint.lint import PyLinter
|
||||
from typing import Any
|
||||
|
||||
|
||||
class ImportType(StrEnum):
|
||||
"""
|
||||
import type enumeration
|
||||
|
||||
Attributes:
|
||||
Package(MethodTypeOrder): (class attribute) package import
|
||||
PackageFrom(MethodTypeOrder): (class attribute) package import, from clause
|
||||
System(ImportType): (class attribute) system installed packages
|
||||
SystemFrom(MethodTypeOrder): (class attribute) system installed packages, from clause
|
||||
"""
|
||||
|
||||
Package = "package"
|
||||
PackageFrom = "package-from"
|
||||
System = "system"
|
||||
SystemFrom = "system-from"
|
||||
|
||||
|
||||
class ImportOrder(BaseRawFileChecker):
|
||||
"""
|
||||
check if imports are defined in recommended order
|
||||
"""
|
||||
|
||||
msgs = {
|
||||
"W6002": (
|
||||
"Invalid import order %s, expected before %s",
|
||||
"imports-out-of-order",
|
||||
"Imports are defined out of recommended order.",
|
||||
),
|
||||
"W6003": (
|
||||
"Import contains more than one package: %s",
|
||||
"multiple-package-imports",
|
||||
"Multiple package imports are not allowed.",
|
||||
),
|
||||
"W6004": (
|
||||
"Invalid from import order %s, expected %s",
|
||||
"from-imports-out-of-order",
|
||||
"From imports are defined out of recommended order.",
|
||||
),
|
||||
}
|
||||
name = "import-ordering"
|
||||
options = (
|
||||
(
|
||||
"import-type-order",
|
||||
{
|
||||
"default": [
|
||||
"system",
|
||||
"system-from",
|
||||
"package",
|
||||
"package-from",
|
||||
],
|
||||
"type": "csv",
|
||||
"metavar": "<comma-separated types>",
|
||||
"help": "Import types order to check.",
|
||||
},
|
||||
),
|
||||
(
|
||||
"root-module",
|
||||
{
|
||||
"default": "ahriman",
|
||||
"type": "string",
|
||||
"help": "Root module name",
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def imports(source: Iterable[Any], start_lineno: int = 0) -> list[nodes.Import | nodes.ImportFrom]:
|
||||
"""
|
||||
extract import nodes from list of raw nodes
|
||||
|
||||
Args:
|
||||
source(Iterable[Any]): all available nodes
|
||||
start_lineno(int, optional): minimal allowed line number (Default value = 0)
|
||||
|
||||
Returns:
|
||||
list[nodes.Import | nodes.ImportFrom]: list of import nodes
|
||||
"""
|
||||
|
||||
def is_defined_import(imports: Any) -> bool:
|
||||
return isinstance(imports, (nodes.Import, nodes.ImportFrom)) \
|
||||
and imports.lineno is not None \
|
||||
and imports.lineno >= start_lineno
|
||||
|
||||
return list(filter(is_defined_import, source))
|
||||
|
||||
def check_from_imports(self, imports: nodes.ImportFrom) -> None:
|
||||
"""
|
||||
check import from statement
|
||||
|
||||
Args:
|
||||
imports(nodes.ImportFrom): import from node
|
||||
"""
|
||||
imported = [names for names, _ in imports.names]
|
||||
for real, expected in zip(imported, sorted(imported)):
|
||||
if real == expected:
|
||||
continue
|
||||
self.add_message("from-imports-out-of-order", line=imports.lineno, args=(real, expected))
|
||||
break
|
||||
|
||||
def check_imports(self, imports: list[nodes.Import | nodes.ImportFrom], root_package: str) -> None:
|
||||
"""
|
||||
check imports
|
||||
|
||||
Args:
|
||||
imports(list[nodes.Import | nodes.ImportFrom]): list of imports in their defined order
|
||||
root_package(str): root package name
|
||||
"""
|
||||
last_statement: tuple[int, str] | None = None
|
||||
|
||||
for statement in imports:
|
||||
# define types and perform specific checks
|
||||
if isinstance(statement, nodes.ImportFrom):
|
||||
import_name = statement.modname
|
||||
root, *_ = import_name.split(".", maxsplit=1)
|
||||
import_type = ImportType.PackageFrom if root_package == root else ImportType.SystemFrom
|
||||
# check from import itself
|
||||
self.check_from_imports(statement)
|
||||
else:
|
||||
import_name = next(name for name, _ in statement.names)
|
||||
root, *_ = import_name.split(".", maxsplit=1)[0]
|
||||
import_type = ImportType.Package if root_package == root else ImportType.System
|
||||
# check import itself
|
||||
self.check_package_imports(statement)
|
||||
|
||||
# extract index
|
||||
try:
|
||||
import_type_index = self.linter.config.import_type_order.index(import_type)
|
||||
except ValueError:
|
||||
import_type_index = len(self.linter.config.import_type_order)
|
||||
|
||||
# check ordering if possible
|
||||
if last_statement is not None:
|
||||
_, last_statement_name = last_statement
|
||||
if last_statement > (import_type_index, import_name):
|
||||
self.add_message("imports-out-of-order", line=statement.lineno,
|
||||
args=(import_name, last_statement_name))
|
||||
|
||||
# update the last value
|
||||
last_statement = import_type_index, import_name
|
||||
|
||||
def check_package_imports(self, imports: nodes.Import) -> None:
|
||||
"""
|
||||
check package import
|
||||
|
||||
Args:
|
||||
imports(nodes.Import): package import node
|
||||
"""
|
||||
if len(imports.names) != 1:
|
||||
self.add_message("multiple-package-imports", line=imports.lineno, args=(imports.names,))
|
||||
|
||||
def process_module(self, node: nodes.Module) -> None:
|
||||
"""
|
||||
process module
|
||||
|
||||
Args:
|
||||
node(nodes.Module): module node to check
|
||||
"""
|
||||
root_module, *_ = node.qname().split(".")
|
||||
self.check_imports(self.imports(node.values()), root_module)
|
||||
|
||||
|
||||
def register(linter: PyLinter) -> None:
|
||||
"""
|
||||
register custom checker
|
||||
|
||||
Args:
|
||||
linter(PyLinter): linter in which checker should be registered
|
||||
"""
|
||||
linter.register_checker(ImportOrder(linter))
|
@ -8,7 +8,8 @@ name = "ahriman"
|
||||
description = "ArcH linux ReposItory MANager"
|
||||
readme = "README.md"
|
||||
|
||||
requires-python = ">=3.11"
|
||||
# Actually we are using features from the latest python, however, ubuntu, which is used for CI doesn't have it
|
||||
requires-python = ">=3"
|
||||
|
||||
license = {file = "COPYING"}
|
||||
authors = [
|
||||
|
@ -17,4 +17,4 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
__version__ = "2.12.2"
|
||||
__version__ = "2.13.0"
|
||||
|
@ -71,7 +71,7 @@ def _parser() -> argparse.ArgumentParser:
|
||||
fromfile_prefix_chars="@", formatter_class=_formatter)
|
||||
parser.add_argument("-a", "--architecture", help="filter by target architecture")
|
||||
parser.add_argument("-c", "--configuration", help="configuration path", type=Path,
|
||||
default=Path("/etc") / "ahriman.ini")
|
||||
default=Path("/") / "etc" / "ahriman.ini")
|
||||
parser.add_argument("--force", help="force run, remove file lock", action="store_true")
|
||||
parser.add_argument("-l", "--lock", help="lock file", type=Path,
|
||||
default=Path(tempfile.gettempdir()) / "ahriman.lock")
|
||||
@ -999,7 +999,7 @@ def _set_service_setup_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||
formatter_class=_formatter)
|
||||
parser.add_argument("--build-as-user", help="force makepkg user to the specific one")
|
||||
parser.add_argument("--from-configuration", help="path to default devtools pacman configuration",
|
||||
type=Path, default=Path("/usr") / "share" / "devtools" / "pacman.conf.d" / "extra.conf")
|
||||
type=Path, default=Path("/") / "usr" / "share" / "devtools" / "pacman.conf.d" / "extra.conf")
|
||||
parser.add_argument("--generate-salt", help="generate salt for user passwords",
|
||||
action=argparse.BooleanOptionalAction, default=False)
|
||||
parser.add_argument("--makeflags-jobs", help="append MAKEFLAGS variable with parallelism set to number of cores",
|
||||
|
@ -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/>.
|
||||
#
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
|
||||
from ahriman.application.handlers.add import Add
|
||||
from ahriman.application.handlers.backup import Backup
|
||||
from ahriman.application.handlers.change import Change
|
||||
from ahriman.application.handlers.clean import Clean
|
||||
from ahriman.application.handlers.daemon import Daemon
|
||||
from ahriman.application.handlers.dump import Dump
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.application.handlers.help import Help
|
||||
from ahriman.application.handlers.key_import import KeyImport
|
||||
from ahriman.application.handlers.patch import Patch
|
||||
|
@ -20,7 +20,7 @@
|
||||
import argparse
|
||||
|
||||
from ahriman.application.application import Application
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.models.packagers import Packagers
|
||||
from ahriman.models.pkgbuild_patch import PkgbuildPatch
|
||||
|
@ -23,7 +23,7 @@ import pwd
|
||||
from pathlib import Path
|
||||
from tarfile import TarFile
|
||||
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.database import SQLite
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
|
@ -20,7 +20,7 @@
|
||||
import argparse
|
||||
|
||||
from ahriman.application.application import Application
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.formatters import ChangesPrinter
|
||||
from ahriman.models.action import Action
|
||||
|
@ -20,7 +20,7 @@
|
||||
import argparse
|
||||
|
||||
from ahriman.application.application import Application
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
|
||||
|
@ -21,7 +21,7 @@ import argparse
|
||||
|
||||
from ahriman.application.application import Application
|
||||
from ahriman.application.application.updates_iterator import FixedUpdatesIterator, UpdatesIterator
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.application.handlers.update import Update
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
|
@ -19,7 +19,7 @@
|
||||
#
|
||||
import argparse
|
||||
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.formatters import ConfigurationPathsPrinter, ConfigurationPrinter, StringPrinter
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
|
@ -19,7 +19,7 @@
|
||||
#
|
||||
import argparse
|
||||
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
import argparse
|
||||
|
||||
from ahriman.application.application import Application
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
|
||||
|
@ -23,7 +23,7 @@ import sys
|
||||
from pathlib import Path
|
||||
|
||||
from ahriman.application.application import Application
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.build_tools.sources import Sources
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.formatters import PatchPrinter
|
||||
|
@ -20,7 +20,7 @@
|
||||
import argparse
|
||||
|
||||
from ahriman.application.application import Application
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.models.build_status import BuildStatusEnum
|
||||
from ahriman.models.package import Package
|
||||
|
@ -20,7 +20,7 @@
|
||||
import argparse
|
||||
|
||||
from ahriman.application.application import Application
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
import argparse
|
||||
|
||||
from ahriman.application.application import Application
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.formatters import StringPrinter
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
|
@ -19,7 +19,7 @@
|
||||
#
|
||||
import argparse
|
||||
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.formatters import RepositoryPrinter
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
|
@ -21,7 +21,7 @@ import argparse
|
||||
|
||||
from tarfile import TarFile
|
||||
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
import argparse
|
||||
import shlex
|
||||
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
|
||||
|
@ -19,10 +19,10 @@
|
||||
#
|
||||
import argparse
|
||||
|
||||
from dataclasses import fields
|
||||
from collections.abc import Callable, Iterable
|
||||
from dataclasses import fields
|
||||
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.alpm.remote import AUR, Official
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.exceptions import OptionError
|
||||
|
@ -20,7 +20,7 @@
|
||||
import argparse
|
||||
|
||||
from ahriman import __version__
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.formatters import UpdatePrinter
|
||||
from ahriman.models.package import Package
|
||||
|
@ -24,7 +24,7 @@ from pwd import getpwuid
|
||||
from urllib.parse import quote_plus as urlencode
|
||||
|
||||
from ahriman.application.application import Application
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.exceptions import MissingArchitectureError
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
@ -44,9 +44,9 @@ class Setup(Handler):
|
||||
|
||||
ALLOW_MULTI_ARCHITECTURE_RUN = False # conflicting io
|
||||
|
||||
ARCHBUILD_COMMAND_PATH = Path("/usr") / "bin" / "archbuild"
|
||||
MIRRORLIST_PATH = Path("/etc") / "pacman.d" / "mirrorlist"
|
||||
SUDOERS_DIR_PATH = Path("/etc") / "sudoers.d"
|
||||
ARCHBUILD_COMMAND_PATH = Path("/") / "usr" / "bin" / "archbuild"
|
||||
MIRRORLIST_PATH = Path("/") / "etc" / "pacman.d" / "mirrorlist"
|
||||
SUDOERS_DIR_PATH = Path("/") / "etc" / "sudoers.d"
|
||||
|
||||
@classmethod
|
||||
def run(cls, args: argparse.Namespace, repository_id: RepositoryId, configuration: Configuration, *,
|
||||
|
@ -23,7 +23,7 @@ import sys
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.formatters import StringPrinter
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
|
@ -20,7 +20,7 @@
|
||||
import argparse
|
||||
|
||||
from ahriman.application.application import Application
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
|
||||
|
@ -22,7 +22,7 @@ import argparse
|
||||
from collections.abc import Callable
|
||||
|
||||
from ahriman.application.application import Application
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.formatters import PackagePrinter, StatusPrinter
|
||||
from ahriman.models.build_status import BuildStatus
|
||||
|
@ -20,7 +20,7 @@
|
||||
import argparse
|
||||
|
||||
from ahriman.application.application import Application
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.models.action import Action
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
|
@ -20,7 +20,7 @@
|
||||
import argparse
|
||||
|
||||
from ahriman.application.application import Application
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.formatters import StringPrinter, TreePrinter
|
||||
from ahriman.core.tree import Tree
|
||||
|
@ -19,7 +19,7 @@
|
||||
#
|
||||
import argparse
|
||||
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
from ahriman.models.repository_paths import RepositoryPaths
|
||||
|
@ -20,7 +20,7 @@
|
||||
import argparse
|
||||
|
||||
from ahriman.application.application import Application
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
from ahriman.models.result import Result
|
||||
|
@ -19,7 +19,7 @@
|
||||
#
|
||||
import argparse
|
||||
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.formatters import StringPrinter
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
|
@ -22,7 +22,7 @@ import argparse
|
||||
from collections.abc import Callable
|
||||
|
||||
from ahriman.application.application import Application
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.models.packagers import Packagers
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
|
@ -20,7 +20,7 @@
|
||||
import argparse
|
||||
import getpass
|
||||
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.database import SQLite
|
||||
from ahriman.core.exceptions import PasswordError
|
||||
|
@ -22,7 +22,7 @@ import copy
|
||||
|
||||
from typing import Any
|
||||
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.configuration.schema import CONFIGURATION_SCHEMA, ConfigurationSchema
|
||||
from ahriman.core.configuration.validator import Validator
|
||||
|
@ -25,7 +25,7 @@ from collections.abc import Generator
|
||||
from importlib import metadata
|
||||
|
||||
from ahriman import __version__
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.formatters import VersionPrinter
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
|
@ -21,7 +21,7 @@ import argparse
|
||||
|
||||
from collections.abc import Generator
|
||||
|
||||
from ahriman.application.handlers import Handler
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.spawn import Spawn
|
||||
from ahriman.core.triggers import TriggerLoader
|
||||
|
@ -17,8 +17,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from ahriman.core.alpm.remote.remote import Remote
|
||||
|
||||
from ahriman.core.alpm.remote.aur import AUR
|
||||
from ahriman.core.alpm.remote.official import Official
|
||||
from ahriman.core.alpm.remote.official_syncdb import OfficialSyncdb
|
||||
from ahriman.core.alpm.remote.remote import Remote
|
||||
|
@ -20,7 +20,7 @@
|
||||
from typing import Any
|
||||
|
||||
from ahriman.core.alpm.pacman import Pacman
|
||||
from ahriman.core.alpm.remote import Remote
|
||||
from ahriman.core.alpm.remote.remote import Remote
|
||||
from ahriman.core.exceptions import PackageInfoError, UnknownPackageError
|
||||
from ahriman.models.aur_package import AURPackage
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
from typing import Any
|
||||
|
||||
from ahriman.core.alpm.pacman import Pacman
|
||||
from ahriman.core.alpm.remote import Remote
|
||||
from ahriman.core.alpm.remote.remote import Remote
|
||||
from ahriman.core.exceptions import PackageInfoError, UnknownPackageError
|
||||
from ahriman.models.aur_package import AURPackage
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from ahriman.core.alpm.pacman import Pacman
|
||||
from ahriman.core.alpm.remote import Official
|
||||
from ahriman.core.alpm.remote.official import Official
|
||||
from ahriman.core.exceptions import UnknownPackageError
|
||||
from ahriman.models.aur_package import AURPackage
|
||||
|
||||
|
@ -17,8 +17,6 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from ahriman.core.database.operations.operations import Operations
|
||||
|
||||
from ahriman.core.database.operations.auth_operations import AuthOperations
|
||||
from ahriman.core.database.operations.build_operations import BuildOperations
|
||||
from ahriman.core.database.operations.changes_operations import ChangesOperations
|
||||
|
@ -19,7 +19,7 @@
|
||||
#
|
||||
from sqlite3 import Connection
|
||||
|
||||
from ahriman.core.database.operations import Operations
|
||||
from ahriman.core.database.operations.operations import Operations
|
||||
from ahriman.models.user import User
|
||||
from ahriman.models.user_access import UserAccess
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
#
|
||||
from sqlite3 import Connection
|
||||
|
||||
from ahriman.core.database.operations import Operations
|
||||
from ahriman.core.database.operations.operations import Operations
|
||||
from ahriman.models.package import Package
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
#
|
||||
from sqlite3 import Connection
|
||||
|
||||
from ahriman.core.database.operations import Operations
|
||||
from ahriman.core.database.operations.operations import Operations
|
||||
from ahriman.models.changes import Changes
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
#
|
||||
from sqlite3 import Connection
|
||||
|
||||
from ahriman.core.database.operations import Operations
|
||||
from ahriman.core.database.operations.operations import Operations
|
||||
from ahriman.models.log_record_id import LogRecordId
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
from collections.abc import Generator, Iterable
|
||||
from sqlite3 import Connection
|
||||
|
||||
from ahriman.core.database.operations import Operations
|
||||
from ahriman.core.database.operations.operations import Operations
|
||||
from ahriman.models.build_status import BuildStatus
|
||||
from ahriman.models.package import Package
|
||||
from ahriman.models.package_description import PackageDescription
|
||||
|
@ -20,7 +20,7 @@
|
||||
from collections import defaultdict
|
||||
from sqlite3 import Connection
|
||||
|
||||
from ahriman.core.database.operations import Operations
|
||||
from ahriman.core.database.operations.operations import Operations
|
||||
from ahriman.models.pkgbuild_patch import PkgbuildPatch
|
||||
|
||||
|
||||
|
@ -17,7 +17,6 @@
|
||||
# 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 collections import deque
|
||||
from threading import Lock, Timer
|
||||
|
||||
from ahriman.core.configuration import Configuration
|
||||
@ -47,15 +46,14 @@ class WorkerTrigger(DistributedSystem):
|
||||
self.ping_interval = configuration.getint(section, "time_to_live", fallback=60) / 4.0
|
||||
|
||||
self._lock = Lock()
|
||||
self._timers: deque[Timer] = deque() # because python doesn't have atomics
|
||||
self._timer: Timer | None = None
|
||||
|
||||
def create_timer(self) -> None:
|
||||
"""
|
||||
create timer object and put it to queue
|
||||
"""
|
||||
timer = Timer(self.ping_interval, self.ping)
|
||||
timer.start()
|
||||
self._timers.append(timer)
|
||||
self._timer = Timer(self.ping_interval, self.ping)
|
||||
self._timer.start()
|
||||
|
||||
def on_start(self) -> None:
|
||||
"""
|
||||
@ -71,21 +69,19 @@ class WorkerTrigger(DistributedSystem):
|
||||
"""
|
||||
self.logger.info("removing instance %s in %s", self.worker, self.address)
|
||||
with self._lock:
|
||||
current_timers = self._timers.copy() # will be used later
|
||||
self._timers.clear() # clear timer list
|
||||
if self._timer is None:
|
||||
return
|
||||
|
||||
for timer in current_timers:
|
||||
timer.cancel() # cancel remaining timers
|
||||
self._timer.cancel() # cancel remaining timers
|
||||
self._timer = None # reset state
|
||||
|
||||
def ping(self) -> None:
|
||||
"""
|
||||
register itself as alive worker and update the timer
|
||||
"""
|
||||
with self._lock:
|
||||
if not self._timers: # make sure that there is related specific timer
|
||||
if self._timer is None: # no active timer set, exit loop
|
||||
return
|
||||
|
||||
self._timers.popleft() # pop first timer
|
||||
|
||||
self.register()
|
||||
self.create_timer()
|
||||
|
@ -17,8 +17,6 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from ahriman.core.formatters.printer import Printer
|
||||
|
||||
from ahriman.core.formatters.aur_printer import AurPrinter
|
||||
from ahriman.core.formatters.build_printer import BuildPrinter
|
||||
from ahriman.core.formatters.changes_printer import ChangesPrinter
|
||||
@ -26,6 +24,7 @@ from ahriman.core.formatters.configuration_paths_printer import ConfigurationPat
|
||||
from ahriman.core.formatters.configuration_printer import ConfigurationPrinter
|
||||
from ahriman.core.formatters.package_printer import PackagePrinter
|
||||
from ahriman.core.formatters.patch_printer import PatchPrinter
|
||||
from ahriman.core.formatters.printer import Printer
|
||||
from ahriman.core.formatters.repository_printer import RepositoryPrinter
|
||||
from ahriman.core.formatters.status_printer import StatusPrinter
|
||||
from ahriman.core.formatters.string_printer import StringPrinter
|
||||
|
@ -17,7 +17,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from ahriman.core.formatters import Printer
|
||||
from ahriman.core.formatters.printer import Printer
|
||||
from ahriman.models.changes import Changes
|
||||
from ahriman.models.property import Property
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from ahriman.core.formatters import Printer
|
||||
from ahriman.core.formatters.printer import Printer
|
||||
|
||||
|
||||
class StringPrinter(Printer):
|
||||
|
@ -17,7 +17,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from logging import NullHandler
|
||||
from logging import NullHandler # pylint: disable=imports-out-of-order
|
||||
from typing import Any
|
||||
|
||||
|
||||
|
@ -40,7 +40,7 @@ class LogLoader:
|
||||
|
||||
DEFAULT_LOG_FORMAT = "[%(levelname)s %(asctime)s] [%(filename)s:%(lineno)d %(funcName)s]: %(message)s"
|
||||
DEFAULT_LOG_LEVEL = logging.DEBUG
|
||||
DEFAULT_SYSLOG_DEVICE = Path("/dev") / "log"
|
||||
DEFAULT_SYSLOG_DEVICE = Path("/") / "dev" / "log"
|
||||
|
||||
@staticmethod
|
||||
def handler(selected: LogHandler | None) -> LogHandler:
|
||||
|
@ -18,8 +18,8 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.triggers import Trigger
|
||||
from ahriman.core.report.report import Report
|
||||
from ahriman.core.triggers import Trigger
|
||||
from ahriman.models.package import Package
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
from ahriman.models.result import Result
|
||||
|
@ -51,7 +51,7 @@ class MirrorlistGenerator(PkgbuildGenerator):
|
||||
# configuration fields
|
||||
self.servers = configuration.getlist(section, "servers")
|
||||
self.path = configuration.getpath(
|
||||
section, "path", fallback=Path("/etc") / "pacman.d" / f"{repository_id.name}-mirrorlist")
|
||||
section, "path", fallback=Path("/") / "etc" / "pacman.d" / f"{repository_id.name}-mirrorlist")
|
||||
self.path = self.path.relative_to("/") # in pkgbuild we are always operating with relative to / path
|
||||
# pkgbuild description fields
|
||||
self.pkgbuild_pkgname = configuration.get(section, "package", fallback=f"{repository_id.name}-mirrorlist")
|
||||
|
@ -19,7 +19,7 @@
|
||||
#
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Iterable, Callable
|
||||
from collections.abc import Callable, Iterable
|
||||
from typing import Any, Self
|
||||
|
||||
from ahriman.models.package import Package
|
||||
|
@ -17,9 +17,9 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from secrets import token_urlsafe as generate_password
|
||||
from dataclasses import dataclass, replace
|
||||
from passlib.hash import sha512_crypt
|
||||
from secrets import token_urlsafe as generate_password
|
||||
from typing import Self
|
||||
|
||||
from ahriman.models.user_access import UserAccess
|
||||
|
@ -35,7 +35,7 @@ from ahriman.web.schemas.package_names_schema import PackageNamesSchema
|
||||
from ahriman.web.schemas.package_patch_schema import PackagePatchSchema
|
||||
from ahriman.web.schemas.package_properties_schema import PackagePropertiesSchema
|
||||
from ahriman.web.schemas.package_schema import PackageSchema
|
||||
from ahriman.web.schemas.package_status_schema import PackageStatusSimplifiedSchema, PackageStatusSchema
|
||||
from ahriman.web.schemas.package_status_schema import PackageStatusSchema, PackageStatusSimplifiedSchema
|
||||
from ahriman.web.schemas.pagination_schema import PaginationSchema
|
||||
from ahriman.web.schemas.patch_name_schema import PatchNameSchema
|
||||
from ahriman.web.schemas.patch_schema import PatchSchema
|
||||
|
@ -25,22 +25,6 @@ from ahriman.web.schemas.repository_id_schema import RepositoryIdSchema
|
||||
from ahriman.web.schemas.status_schema import StatusSchema
|
||||
|
||||
|
||||
class PackageStatusSimplifiedSchema(Schema):
|
||||
"""
|
||||
special request package status schema
|
||||
"""
|
||||
|
||||
package = fields.Nested(PackageSchema(), metadata={
|
||||
"description": "Package description",
|
||||
})
|
||||
status = fields.Enum(BuildStatusEnum, by_value=True, required=True, metadata={
|
||||
"description": "Current status",
|
||||
})
|
||||
repository = fields.Nested(RepositoryIdSchema(), required=True, metadata={
|
||||
"description": "Repository identifier",
|
||||
})
|
||||
|
||||
|
||||
class PackageStatusSchema(Schema):
|
||||
"""
|
||||
response package status schema
|
||||
@ -55,3 +39,19 @@ class PackageStatusSchema(Schema):
|
||||
repository = fields.Nested(RepositoryIdSchema(), required=True, metadata={
|
||||
"description": "Repository identifier",
|
||||
})
|
||||
|
||||
|
||||
class PackageStatusSimplifiedSchema(Schema):
|
||||
"""
|
||||
special request package status schema
|
||||
"""
|
||||
|
||||
package = fields.Nested(PackageSchema(), metadata={
|
||||
"description": "Package description",
|
||||
})
|
||||
status = fields.Enum(BuildStatusEnum, by_value=True, required=True, metadata={
|
||||
"description": "Current status",
|
||||
})
|
||||
repository = fields.Nested(RepositoryIdSchema(), required=True, metadata={
|
||||
"description": "Repository identifier",
|
||||
})
|
||||
|
@ -17,8 +17,8 @@
|
||||
# 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 aiohttp_cors import CorsViewMixin # type: ignore[import-untyped]
|
||||
from aiohttp.web import HTTPBadRequest, HTTPNotFound, Request, StreamResponse, View
|
||||
from aiohttp_cors import CorsViewMixin # type: ignore[import-untyped]
|
||||
from collections.abc import Awaitable, Callable
|
||||
from typing import TypeVar
|
||||
|
||||
|
@ -19,8 +19,8 @@
|
||||
#
|
||||
import aiohttp_apispec # type: ignore[import-untyped]
|
||||
|
||||
from collections.abc import Callable
|
||||
from aiohttp.web import HTTPBadRequest, HTTPNoContent, Response, json_response
|
||||
from collections.abc import Callable
|
||||
|
||||
from ahriman.models.user_access import UserAccess
|
||||
from ahriman.models.worker import Worker
|
||||
|
@ -22,7 +22,7 @@ import aiohttp_apispec # type: ignore[import-untyped]
|
||||
from aiohttp.web import HTTPBadRequest, Response, json_response
|
||||
|
||||
from ahriman.models.user_access import UserAccess
|
||||
from ahriman.web.schemas import AuthSchema, ErrorSchema, ProcessIdSchema, UpdateFlagsSchema, RepositoryIdSchema
|
||||
from ahriman.web.schemas import AuthSchema, ErrorSchema, ProcessIdSchema, RepositoryIdSchema, UpdateFlagsSchema
|
||||
from ahriman.web.views.base import BaseView
|
||||
|
||||
|
||||
|
@ -20,8 +20,8 @@
|
||||
import aiohttp_apispec # type: ignore[import-untyped]
|
||||
import itertools
|
||||
|
||||
from collections.abc import Callable
|
||||
from aiohttp.web import HTTPNoContent, Response, json_response
|
||||
from collections.abc import Callable
|
||||
|
||||
from ahriman.models.build_status import BuildStatus
|
||||
from ahriman.models.package import Package
|
||||
|
@ -26,7 +26,7 @@ from ahriman.models.build_status import BuildStatusEnum
|
||||
from ahriman.models.counters import Counters
|
||||
from ahriman.models.internal_status import InternalStatus
|
||||
from ahriman.models.user_access import UserAccess
|
||||
from ahriman.web.schemas import AuthSchema, ErrorSchema, InternalStatusSchema, StatusSchema, RepositoryIdSchema
|
||||
from ahriman.web.schemas import AuthSchema, ErrorSchema, InternalStatusSchema, RepositoryIdSchema, StatusSchema
|
||||
from ahriman.web.views.base import BaseView
|
||||
from ahriman.web.views.status_view_guard import StatusViewGuard
|
||||
|
||||
|
@ -100,7 +100,7 @@ def test_add_local_cache(application_packages: ApplicationPackages, package_ahri
|
||||
"""
|
||||
mocker.patch("ahriman.models.package.Package.from_build", return_value=package_ahriman)
|
||||
mocker.patch("pathlib.Path.is_dir", autospec=True,
|
||||
side_effect=lambda p: True if p.is_relative_to(application_packages.repository.paths.cache) else False)
|
||||
side_effect=lambda p: p.is_relative_to(application_packages.repository.paths.cache))
|
||||
init_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.init")
|
||||
copytree_mock = mocker.patch("shutil.copytree")
|
||||
build_queue_mock = mocker.patch("ahriman.core.database.SQLite.build_queue_insert")
|
||||
|
@ -47,7 +47,7 @@ def test_iter(updates_iterator: UpdatesIterator) -> None:
|
||||
"""
|
||||
must return self as iterator
|
||||
"""
|
||||
assert updates_iterator.__iter__() == updates_iterator
|
||||
assert iter(updates_iterator) == updates_iterator
|
||||
|
||||
|
||||
def test_next(updates_iterator: UpdatesIterator, package_ahriman: Package, mocker: MockerFixture) -> None:
|
||||
@ -58,7 +58,7 @@ def test_next(updates_iterator: UpdatesIterator, package_ahriman: Package, mocke
|
||||
side_effect=[([package_ahriman.base], 2), (None, 2), StopIteration])
|
||||
sleep_mock = mocker.patch("time.sleep")
|
||||
|
||||
updates = [packages for packages in updates_iterator]
|
||||
updates = list(updates_iterator)
|
||||
assert updates == [[package_ahriman.base], None]
|
||||
sleep_mock.assert_has_calls([MockCall(0.5), MockCall(0.5)])
|
||||
|
||||
|
@ -156,7 +156,7 @@ def test_configuration_create_ahriman(args: argparse.Namespace, configuration: C
|
||||
|
||||
|
||||
def test_configuration_create_ahriman_no_multilib(args: argparse.Namespace, configuration: Configuration,
|
||||
repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
|
||||
mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must create configuration for the service without multilib repository
|
||||
"""
|
||||
|
@ -558,14 +558,13 @@ def user() -> User:
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def watcher(repository_id: RepositoryId, database: SQLite, repository: Repository) -> Watcher:
|
||||
def watcher(repository_id: RepositoryId, database: SQLite) -> Watcher:
|
||||
"""
|
||||
package status watcher fixture
|
||||
|
||||
Args:
|
||||
repository_id(RepositoryId): repository identifier fixture
|
||||
database(SQLite): database fixture
|
||||
repository(Repository): repository fixture
|
||||
|
||||
Returns:
|
||||
Watcher: package status watcher test instance
|
||||
|
@ -48,7 +48,7 @@ def test_multisearch_single(aur_package_ahriman: AURPackage, pacman: Pacman, moc
|
||||
search_mock.assert_called_once_with("ahriman", pacman=pacman)
|
||||
|
||||
|
||||
def test_remote_git_url(remote: Remote, pacman: Pacman) -> None:
|
||||
def test_remote_git_url(remote: Remote) -> None:
|
||||
"""
|
||||
must raise NotImplemented for missing remote git url
|
||||
"""
|
||||
@ -56,7 +56,7 @@ def test_remote_git_url(remote: Remote, pacman: Pacman) -> None:
|
||||
remote.remote_git_url("package", "repositorys")
|
||||
|
||||
|
||||
def test_remote_web_url(remote: Remote, pacman: Pacman) -> None:
|
||||
def test_remote_web_url(remote: Remote) -> None:
|
||||
"""
|
||||
must raise NotImplemented for missing remote web url
|
||||
"""
|
||||
|
@ -1,10 +1,10 @@
|
||||
import importlib
|
||||
import sys
|
||||
|
||||
import ahriman.core.auth.helpers as helpers
|
||||
|
||||
from pytest_mock import MockerFixture
|
||||
|
||||
from ahriman.core.auth import helpers
|
||||
|
||||
|
||||
def test_import_aiohttp_security() -> None:
|
||||
"""
|
||||
|
@ -27,7 +27,7 @@ def test_changes(mocker: MockerFixture) -> None:
|
||||
diff_mock.assert_called_once_with(local, last_commit_sha)
|
||||
|
||||
|
||||
def test_changes_skip(package_ahriman: Package, mocker: MockerFixture) -> None:
|
||||
def test_changes_skip(mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must return none in case if commit sha is not available
|
||||
"""
|
||||
|
@ -1,7 +1,7 @@
|
||||
import pytest
|
||||
|
||||
from sqlite3 import Connection
|
||||
from pytest_mock import MockerFixture
|
||||
from sqlite3 import Connection
|
||||
from unittest.mock import call as MockCall
|
||||
|
||||
from ahriman.core.configuration import Configuration
|
||||
|
@ -19,7 +19,7 @@ def test_migrate(connection: Connection, configuration: Configuration, mocker: M
|
||||
run_mock.assert_called_once_with()
|
||||
|
||||
|
||||
def test_migration(migrations: Migrations, connection: Connection) -> None:
|
||||
def test_migration(migrations: Migrations) -> None:
|
||||
"""
|
||||
must perform single migration
|
||||
"""
|
||||
|
@ -1,8 +1,6 @@
|
||||
from pytest_mock import MockerFixture
|
||||
from threading import Timer
|
||||
|
||||
from pytest_mock import MockerFixture
|
||||
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.distributed import WorkerTrigger
|
||||
|
||||
|
||||
@ -11,10 +9,8 @@ def test_create_timer(worker_trigger: WorkerTrigger) -> None:
|
||||
must create a timer and put it to queue
|
||||
"""
|
||||
worker_trigger.create_timer()
|
||||
|
||||
timer = worker_trigger._timers.popleft()
|
||||
assert timer.function == worker_trigger.ping
|
||||
timer.cancel()
|
||||
assert worker_trigger._timer.function == worker_trigger.ping
|
||||
worker_trigger._timer.cancel()
|
||||
|
||||
|
||||
def test_on_start(worker_trigger: WorkerTrigger, mocker: MockerFixture) -> None:
|
||||
@ -31,7 +27,7 @@ def test_on_stop(worker_trigger: WorkerTrigger, mocker: MockerFixture) -> None:
|
||||
must unregister itself as worker
|
||||
"""
|
||||
run_mock = mocker.patch("threading.Timer.cancel")
|
||||
worker_trigger._timers.append(Timer(1, print)) # doesn't matter
|
||||
worker_trigger._timer = Timer(1, print) # doesn't matter
|
||||
|
||||
worker_trigger.on_stop()
|
||||
run_mock.assert_called_once_with()
|
||||
@ -50,7 +46,7 @@ def test_ping(worker_trigger: WorkerTrigger, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
run_mock = mocker.patch("ahriman.core.distributed.WorkerTrigger.register")
|
||||
timer_mock = mocker.patch("threading.Timer.start")
|
||||
worker_trigger._timers.append(Timer(1, print)) # doesn't matter
|
||||
worker_trigger._timer = Timer(1, print) # doesn't matter
|
||||
|
||||
worker_trigger.ping()
|
||||
run_mock.assert_called_once_with()
|
||||
|
@ -2,7 +2,7 @@ import pytest
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from ahriman.core.formatters import AurPrinter, ChangesPrinter, ConfigurationPrinter, ConfigurationPathsPrinter, \
|
||||
from ahriman.core.formatters import AurPrinter, ChangesPrinter, ConfigurationPathsPrinter, ConfigurationPrinter, \
|
||||
PackagePrinter, PatchPrinter, RepositoryPrinter, StatusPrinter, StringPrinter, TreePrinter, UpdatePrinter, \
|
||||
UserPrinter, ValidationPrinter, VersionPrinter
|
||||
from ahriman.models.aur_package import AURPackage
|
||||
|
@ -22,10 +22,7 @@ def test_package_update(database: SQLite, configuration: Configuration, package_
|
||||
patch2 = PkgbuildPatch("key", "value")
|
||||
local = Path("local")
|
||||
|
||||
mocker.patch(
|
||||
"pathlib.Path.is_file",
|
||||
autospec=True,
|
||||
side_effect=lambda p: True if p == Path(".gitignore") else False)
|
||||
mocker.patch("pathlib.Path.is_file", autospec=True, side_effect=lambda p: p == Path(".gitignore"))
|
||||
glob_mock = mocker.patch("pathlib.Path.glob", return_value=[Path(".git"), Path(".gitignore")])
|
||||
rmtree_mock = mocker.patch("shutil.rmtree")
|
||||
unlink_mock = mocker.patch("pathlib.Path.unlink")
|
||||
|
@ -29,7 +29,7 @@ def test_load_archives(package_ahriman: Package, package_python_schedule: Packag
|
||||
assert len(packages) == 2
|
||||
assert {package.base for package in packages} == {package_ahriman.base, package_python_schedule.base}
|
||||
|
||||
archives = sum([list(package.packages.keys()) for package in packages], start=[])
|
||||
archives = sum((list(package.packages.keys()) for package in packages), start=[])
|
||||
assert len(archives) == 3
|
||||
expected = set(package_ahriman.packages.keys())
|
||||
expected.update(package_python_schedule.packages.keys())
|
||||
|
@ -56,7 +56,7 @@ def test_configuration_schema_empty(configuration: Configuration) -> None:
|
||||
assert ReportTrigger.configuration_schema(repository_id, None) == ReportTrigger.CONFIGURATION_SCHEMA
|
||||
|
||||
|
||||
def test_configuration_schema_variables(configuration: Configuration) -> None:
|
||||
def test_configuration_schema_variables() -> None:
|
||||
"""
|
||||
must return empty schema
|
||||
"""
|
||||
|
@ -147,7 +147,7 @@ def test_on_result_exception(trigger_loader: TriggerLoader, package_ahriman: Pac
|
||||
log_mock.assert_called_once()
|
||||
|
||||
|
||||
def test_on_start(trigger_loader: TriggerLoader, package_ahriman: Package, mocker: MockerFixture) -> None:
|
||||
def test_on_start(trigger_loader: TriggerLoader, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must run triggers on start
|
||||
"""
|
||||
@ -187,7 +187,7 @@ def test_on_stop_without_on_start(configuration: Configuration, mocker: MockerFi
|
||||
on_stop_mock.assert_not_called()
|
||||
|
||||
|
||||
def test_on_stop(trigger_loader: TriggerLoader, package_ahriman: Package, mocker: MockerFixture) -> None:
|
||||
def test_on_stop(trigger_loader: TriggerLoader, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must run triggers on stop
|
||||
"""
|
||||
|
@ -78,7 +78,7 @@ def test_from_repo(aur_package_akonadi: AURPackage, resource_path_root: Path) ->
|
||||
assert AURPackage.from_repo(model) == aur_package_akonadi
|
||||
|
||||
|
||||
def test_convert(aur_package_ahriman: AURPackage, resource_path_root: Path) -> None:
|
||||
def test_convert(resource_path_root: Path) -> None:
|
||||
"""
|
||||
must convert fields to snakecase and also apply converters
|
||||
"""
|
||||
|
@ -249,7 +249,7 @@ def test_from_build_architecture(mocker: MockerFixture, resource_path_root: Path
|
||||
}
|
||||
|
||||
|
||||
def test_from_build_failed(package_ahriman: Package, mocker: MockerFixture) -> None:
|
||||
def test_from_build_failed(mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must raise exception if there are errors during srcinfo load
|
||||
"""
|
||||
@ -317,7 +317,7 @@ def test_local_files_empty(mocker: MockerFixture, resource_path_root: Path) -> N
|
||||
mocker.patch("ahriman.models.package.check_output", return_value=srcinfo)
|
||||
mocker.patch("ahriman.models.package.Package.supported_architectures", return_value=["any"])
|
||||
|
||||
assert list(Package.local_files(Path("path"))) == []
|
||||
assert not list(Package.local_files(Path("path")))
|
||||
|
||||
|
||||
def test_local_files_error(mocker: MockerFixture) -> None:
|
||||
@ -342,7 +342,7 @@ def test_local_files_schema(mocker: MockerFixture, resource_path_root: Path) ->
|
||||
mocker.patch("ahriman.models.package.check_output", return_value="")
|
||||
mocker.patch("ahriman.models.package.Package.supported_architectures", return_value=["any"])
|
||||
|
||||
assert list(Package.local_files(Path("path"))) == []
|
||||
assert not list(Package.local_files(Path("path")))
|
||||
|
||||
|
||||
def test_local_files_with_install(mocker: MockerFixture, resource_path_root: Path) -> None:
|
||||
|
@ -1,6 +1,6 @@
|
||||
from collections.abc import Callable
|
||||
from pytest_mock import MockerFixture
|
||||
from pathlib import Path
|
||||
from pytest_mock import MockerFixture
|
||||
|
||||
from ahriman.models.package_description import PackageDescription
|
||||
from ahriman.models.package_source import PackageSource
|
||||
|
@ -1,16 +1,15 @@
|
||||
import pytest
|
||||
|
||||
from asyncio import BaseEventLoop
|
||||
from aiohttp.web import Application, Resource, UrlMappingMatchInfo
|
||||
from aiohttp.test_utils import TestClient
|
||||
from aiohttp.web import Application, Resource, UrlMappingMatchInfo
|
||||
from asyncio import BaseEventLoop
|
||||
from collections.abc import Awaitable, Callable
|
||||
from marshmallow import Schema
|
||||
from pytest_mock import MockerFixture
|
||||
from typing import Any
|
||||
from unittest.mock import MagicMock, Mock
|
||||
|
||||
import ahriman.core.auth.helpers
|
||||
|
||||
from ahriman.core.auth import helpers
|
||||
from ahriman.core.auth.oauth import OAuth
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.database import SQLite
|
||||
@ -73,7 +72,7 @@ def request(application: Application, path: str, method: str, params: Any = None
|
||||
request_mock.match_info = UrlMappingMatchInfo({}, route_mock)
|
||||
|
||||
extra = extra or {}
|
||||
request_mock.get_extra_info.side_effect = lambda key: extra.get(key)
|
||||
request_mock.get_extra_info.side_effect = extra.get
|
||||
|
||||
return request_mock
|
||||
|
||||
@ -130,7 +129,7 @@ def application(configuration: Configuration, spawner: Spawn, database: SQLite,
|
||||
configuration.set_option("web", "port", "8080")
|
||||
mocker.patch("ahriman.core.database.SQLite.load", return_value=database)
|
||||
mocker.patch("aiohttp_apispec.setup_aiohttp_apispec")
|
||||
mocker.patch.object(ahriman.core.auth.helpers, "_has_aiohttp_security", False)
|
||||
mocker.patch.object(helpers, "_has_aiohttp_security", False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
|
||||
return setup_server(configuration, spawner, [repository_id])
|
||||
@ -156,7 +155,7 @@ def application_with_auth(configuration: Configuration, user: User, spawner: Spa
|
||||
configuration.set_option("web", "port", "8080")
|
||||
mocker.patch("ahriman.core.database.SQLite.load", return_value=database)
|
||||
mocker.patch("aiohttp_apispec.setup_aiohttp_apispec")
|
||||
mocker.patch.object(ahriman.core.auth.helpers, "_has_aiohttp_security", True)
|
||||
mocker.patch.object(helpers, "_has_aiohttp_security", True)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
application = setup_server(configuration, spawner, [repository_id])
|
||||
|
||||
@ -167,14 +166,13 @@ def application_with_auth(configuration: Configuration, user: User, spawner: Spa
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def application_with_debug(configuration: Configuration, user: User, spawner: Spawn, database: SQLite,
|
||||
def application_with_debug(configuration: Configuration, spawner: Spawn, database: SQLite,
|
||||
mocker: MockerFixture) -> Application:
|
||||
"""
|
||||
application fixture with debug enabled
|
||||
|
||||
Args:
|
||||
configuration(Configuration): configuration fixture
|
||||
user(User): user descriptor fixture
|
||||
spawner(Spawn): spawner fixture
|
||||
database(SQLite): database fixture
|
||||
mocker(MockerFixture): mocker object
|
||||
@ -186,7 +184,7 @@ def application_with_debug(configuration: Configuration, user: User, spawner: Sp
|
||||
configuration.set_option("web", "port", "8080")
|
||||
mocker.patch("ahriman.core.database.SQLite.load", return_value=database)
|
||||
mocker.patch("aiohttp_apispec.setup_aiohttp_apispec")
|
||||
mocker.patch.object(ahriman.core.auth.helpers, "_has_aiohttp_security", False)
|
||||
mocker.patch.object(helpers, "_has_aiohttp_security", False)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
|
||||
return setup_server(configuration, spawner, [repository_id])
|
||||
|
@ -3,19 +3,17 @@ import pytest
|
||||
from ahriman.core.auth import Auth
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.database import SQLite
|
||||
from ahriman.models.user import User
|
||||
from ahriman.web.middlewares.auth_handler import _AuthorizationPolicy
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def authorization_policy(configuration: Configuration, database: SQLite, user: User) -> _AuthorizationPolicy:
|
||||
def authorization_policy(configuration: Configuration, database: SQLite) -> _AuthorizationPolicy:
|
||||
"""
|
||||
fixture for authorization policy
|
||||
|
||||
Args:
|
||||
configuration(Configuration): configuration fixture
|
||||
database(SQLite): database fixture
|
||||
user(User): user fixture
|
||||
|
||||
Returns:
|
||||
AuthorizationPolicy: authorization policy fixture
|
||||
|
@ -24,7 +24,7 @@ async def test_authorized_userid(authorization_policy: _AuthorizationPolicy, use
|
||||
assert await authorization_policy.authorized_userid(user.username) == user.username
|
||||
|
||||
|
||||
async def test_authorized_userid_unknown(authorization_policy: _AuthorizationPolicy, user: User) -> None:
|
||||
async def test_authorized_userid_unknown(authorization_policy: _AuthorizationPolicy) -> None:
|
||||
"""
|
||||
must not allow unknown user id for authorization
|
||||
"""
|
||||
@ -51,7 +51,7 @@ async def test_permits(authorization_policy: _AuthorizationPolicy, user: User) -
|
||||
])
|
||||
|
||||
|
||||
async def test_auth_handler_unix_socket(client_with_auth: TestClient, mocker: MockerFixture) -> None:
|
||||
async def test_auth_handler_unix_socket(mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must allow calls via unix sockets
|
||||
"""
|
||||
|
@ -1,8 +1,8 @@
|
||||
import pytest
|
||||
|
||||
from multidict import MultiDict
|
||||
from aiohttp.test_utils import TestClient
|
||||
from aiohttp.web import HTTPBadRequest, HTTPNotFound
|
||||
from multidict import MultiDict
|
||||
from pytest_mock import MockerFixture
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
|
5
tox.ini
5
tox.ini
@ -1,9 +1,10 @@
|
||||
[tox]
|
||||
envlist = check, tests
|
||||
dependencies = -e .[journald,pacman,s3,web]
|
||||
project_name = ahriman
|
||||
isolated_build = True
|
||||
labels =
|
||||
release = version, docs, publish
|
||||
dependencies = -e .[journald,pacman,s3,web]
|
||||
project_name = ahriman
|
||||
|
||||
[mypy]
|
||||
flags = --implicit-reexport --strict --allow-untyped-decorators --allow-subclassing-any
|
||||
|
Loading…
x
Reference in New Issue
Block a user