mirror of
https://github.com/arcan1s/ahriman.git
synced 2025-04-24 07:17:17 +00:00
style: fix some typos and warnings
This commit is contained in:
parent
4b5a645f8d
commit
20e7ba3b1d
@ -44,7 +44,7 @@ The main functionality of the class is already described, but command is still n
|
|||||||
|
|
||||||
arguments = set_parser
|
arguments = set_parser
|
||||||
|
|
||||||
In addition, ``ahriman.application.handlers.handler.Handler.ALLOW_MULTI_ARCHITECTURE_RUN`` can be set to ``False`` in order to disable multiprocess run (e.g. in case if there are conflicting operations, like writting to stdout).
|
In addition, ``ahriman.application.handlers.handler.Handler.ALLOW_MULTI_ARCHITECTURE_RUN`` can be set to ``False`` in order to disable multiprocess run (e.g. in case if there are conflicting operations, like writing to stdout).
|
||||||
|
|
||||||
Save the file above as ``/usr/lib/python3.12/site-packages/ahriman/application/handlers/help_web.py`` (replace ``python3.12`` with actual python version) and you are set.
|
Save the file above as ``/usr/lib/python3.12/site-packages/ahriman/application/handlers/help_web.py`` (replace ``python3.12`` with actual python version) and you are set.
|
||||||
|
|
||||||
|
@ -394,7 +394,7 @@ All extracted fields are packed as ``ahriman.models.pkgbuild_patch.PkgbuildPatch
|
|||||||
|
|
||||||
The PKGBUILD class also provides some additional functions on top of that:
|
The PKGBUILD class also provides some additional functions on top of that:
|
||||||
|
|
||||||
* Ability to extract fields defined inside ``package*()`` functions, which are in particular used for the multipackages.
|
* Ability to extract fields defined inside ``package*()`` functions, which are in particular used for the multi-packages.
|
||||||
* Shell substitution, which supports constructions ``$var`` (including ``${var}``), ``${var#(#)pattern}``, ``${var%(%)pattern}`` and ``${var/(/)pattern/replacement}`` (including ``#pattern`` and ``%pattern``).
|
* Shell substitution, which supports constructions ``$var`` (including ``${var}``), ``${var#(#)pattern}``, ``${var%(%)pattern}`` and ``${var/(/)pattern/replacement}`` (including ``#pattern`` and ``%pattern``).
|
||||||
|
|
||||||
Additional features
|
Additional features
|
||||||
|
@ -97,7 +97,7 @@ Otherwise, you would need to pass ``AHRIMAN_PORT`` and mount container network t
|
|||||||
|
|
||||||
Simple server with authentication can be found in `examples <https://github.com/arcan1s/ahriman/tree/master/recipes/web>`__ too.
|
Simple server with authentication can be found in `examples <https://github.com/arcan1s/ahriman/tree/master/recipes/web>`__ too.
|
||||||
|
|
||||||
Mutli-repository web service
|
Multi-repository web service
|
||||||
""""""""""""""""""""""""""""
|
""""""""""""""""""""""""""""
|
||||||
|
|
||||||
Idea is pretty same as to just run web service. However, it is required to run setup commands for each repository, except for one which is specified by ``AHRIMAN_REPOSITORY`` and ``AHRIMAN_ARCHITECTURE`` variables.
|
Idea is pretty same as to just run web service. However, it is required to run setup commands for each repository, except for one which is specified by ``AHRIMAN_REPOSITORY`` and ``AHRIMAN_ARCHITECTURE`` variables.
|
||||||
|
@ -3,7 +3,7 @@ To 2.16.0
|
|||||||
|
|
||||||
This release replaces ``passlib`` dependency with ``bcrypt``.
|
This release replaces ``passlib`` dependency with ``bcrypt``.
|
||||||
|
|
||||||
The reason behind this change is that python developers have deprecated and scheduled for removal ``crypt`` module, which is used by ``passlib``. (By the way, they recommend to use ``passlib`` as a replacement.) Unfortunately, it appears that ``passlib`` is unmaintained (see `the issue <https://foss.heptapod.net/python-libs/passlib/-/issues/187>`__), so the only solution is to migrate to anoher library.
|
The reason behind this change is that python developers have deprecated and scheduled for removal ``crypt`` module, which is used by ``passlib``. (By the way, they recommend to use ``passlib`` as a replacement.) Unfortunately, it appears that ``passlib`` is unmaintained (see `the issue <https://foss.heptapod.net/python-libs/passlib/-/issues/187>`__), so the only solution is to migrate to another library.
|
||||||
|
|
||||||
Because passwords are stored as hashes, it is near to impossible to shadow change passwords in database, the manual intervention is required if:
|
Because passwords are stored as hashes, it is near to impossible to shadow change passwords in database, the manual intervention is required if:
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ import argparse
|
|||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from pwd import getpwuid
|
from pwd import getpwuid
|
||||||
from urllib.parse import quote_plus as urlencode
|
from urllib.parse import quote_plus as url_encode
|
||||||
|
|
||||||
from ahriman.application.application import Application
|
from ahriman.application.application import Application
|
||||||
from ahriman.application.handlers.handler import Handler, SubParserAction
|
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||||
@ -174,7 +174,7 @@ class Setup(Handler):
|
|||||||
if args.web_unix_socket is not None:
|
if args.web_unix_socket is not None:
|
||||||
unix_socket = str(args.web_unix_socket)
|
unix_socket = str(args.web_unix_socket)
|
||||||
configuration.set_option("web", "unix_socket", unix_socket)
|
configuration.set_option("web", "unix_socket", unix_socket)
|
||||||
configuration.set_option("status", "address", f"http+unix://{urlencode(unix_socket)}")
|
configuration.set_option("status", "address", f"http+unix://{url_encode(unix_socket)}")
|
||||||
|
|
||||||
if args.generate_salt:
|
if args.generate_salt:
|
||||||
configuration.set_option("auth", "salt", User.generate_password(20))
|
configuration.set_option("auth", "salt", User.generate_password(20))
|
||||||
|
@ -146,7 +146,7 @@ class PkgbuildParser(shlex.shlex):
|
|||||||
# reset state
|
# reset state
|
||||||
buffer, prefix = [], None
|
buffer, prefix = [], None
|
||||||
|
|
||||||
# we have already prefix string, so we are in progress of expansion
|
# we have already got prefix string, so we are in progress of expansion
|
||||||
# we always operate the last element, so this matches ",", "next"
|
# we always operate the last element, so this matches ",", "next"
|
||||||
case (PkgbuildToken.Comma, _) if prefix is not None:
|
case (PkgbuildToken.Comma, _) if prefix is not None:
|
||||||
buffer.append(f"{prefix}{second}")
|
buffer.append(f"{prefix}{second}")
|
||||||
@ -168,7 +168,7 @@ class PkgbuildParser(shlex.shlex):
|
|||||||
def _is_escaped(self) -> bool:
|
def _is_escaped(self) -> bool:
|
||||||
"""
|
"""
|
||||||
check if the last element was quoted. ``shlex.shlex`` parser doesn't provide information about was the token
|
check if the last element was quoted. ``shlex.shlex`` parser doesn't provide information about was the token
|
||||||
quoted or not, thus there is no difference between "'#'" (diez in quotes) and "#" (diez without quotes). This
|
quoted or not, thus there is no difference between "'#'" (sharp in quotes) and "#" (sharp without quotes). This
|
||||||
method simply rolls back to the last non-space character and check if it is a quotation mark
|
method simply rolls back to the last non-space character and check if it is a quotation mark
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
@ -58,8 +58,8 @@ class EventStatsPrinter(StringPrinter):
|
|||||||
mean = statistics.mean(self.events)
|
mean = statistics.mean(self.events)
|
||||||
|
|
||||||
if len(self.events) > 1:
|
if len(self.events) > 1:
|
||||||
stdev = statistics.stdev(self.events)
|
st_dev = statistics.stdev(self.events)
|
||||||
average = f"{mean:.3f} ± {stdev:.3f}"
|
average = f"{mean:.3f} ± {st_dev:.3f}"
|
||||||
else:
|
else:
|
||||||
average = f"{mean:.3f}"
|
average = f"{mean:.3f}"
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
#
|
#
|
||||||
import contextlib
|
import contextlib
|
||||||
|
|
||||||
from urllib.parse import quote_plus as urlencode
|
from urllib.parse import quote_plus as url_encode
|
||||||
|
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
from ahriman.core.http import SyncAhrimanClient
|
from ahriman.core.http import SyncAhrimanClient
|
||||||
@ -75,7 +75,7 @@ class WebClient(Client, SyncAhrimanClient):
|
|||||||
# legacy-style section
|
# legacy-style section
|
||||||
if (unix_socket := configuration.get("web", "unix_socket", fallback=None)) is not None:
|
if (unix_socket := configuration.get("web", "unix_socket", fallback=None)) is not None:
|
||||||
# special pseudo-protocol which is used for unix sockets
|
# special pseudo-protocol which is used for unix sockets
|
||||||
return "web", f"http+unix://{urlencode(unix_socket)}"
|
return "web", f"http+unix://{url_encode(unix_socket)}"
|
||||||
address = configuration.get("web", "address", fallback=None)
|
address = configuration.get("web", "address", fallback=None)
|
||||||
if not address:
|
if not address:
|
||||||
# build address from host and port directly
|
# build address from host and port directly
|
||||||
@ -94,7 +94,7 @@ class WebClient(Client, SyncAhrimanClient):
|
|||||||
Returns:
|
Returns:
|
||||||
str: full url for web service for changes
|
str: full url for web service for changes
|
||||||
"""
|
"""
|
||||||
return f"{self.address}/api/v1/packages/{urlencode(package_base)}/changes"
|
return f"{self.address}/api/v1/packages/{url_encode(package_base)}/changes"
|
||||||
|
|
||||||
def _dependencies_url(self, package_base: str) -> str:
|
def _dependencies_url(self, package_base: str) -> str:
|
||||||
"""
|
"""
|
||||||
@ -106,7 +106,7 @@ class WebClient(Client, SyncAhrimanClient):
|
|||||||
Returns:
|
Returns:
|
||||||
str: full url for web service for dependencies
|
str: full url for web service for dependencies
|
||||||
"""
|
"""
|
||||||
return f"{self.address}/api/v1/packages/{urlencode(package_base)}/dependencies"
|
return f"{self.address}/api/v1/packages/{url_encode(package_base)}/dependencies"
|
||||||
|
|
||||||
def _events_url(self) -> str:
|
def _events_url(self) -> str:
|
||||||
"""
|
"""
|
||||||
@ -127,7 +127,7 @@ class WebClient(Client, SyncAhrimanClient):
|
|||||||
Returns:
|
Returns:
|
||||||
str: full url for web service for logs
|
str: full url for web service for logs
|
||||||
"""
|
"""
|
||||||
return f"{self.address}/api/v1/packages/{urlencode(package_base)}/logs"
|
return f"{self.address}/api/v1/packages/{url_encode(package_base)}/logs"
|
||||||
|
|
||||||
def _package_url(self, package_base: str = "") -> str:
|
def _package_url(self, package_base: str = "") -> str:
|
||||||
"""
|
"""
|
||||||
@ -139,7 +139,7 @@ class WebClient(Client, SyncAhrimanClient):
|
|||||||
Returns:
|
Returns:
|
||||||
str: full url of web service for specific package base
|
str: full url of web service for specific package base
|
||||||
"""
|
"""
|
||||||
suffix = f"/{urlencode(package_base)}" if package_base else ""
|
suffix = f"/{url_encode(package_base)}" if package_base else ""
|
||||||
return f"{self.address}/api/v1/packages{suffix}"
|
return f"{self.address}/api/v1/packages{suffix}"
|
||||||
|
|
||||||
def _patches_url(self, package_base: str, variable: str = "") -> str:
|
def _patches_url(self, package_base: str, variable: str = "") -> str:
|
||||||
@ -153,8 +153,8 @@ class WebClient(Client, SyncAhrimanClient):
|
|||||||
Returns:
|
Returns:
|
||||||
str: full url of web service for the package patch
|
str: full url of web service for the package patch
|
||||||
"""
|
"""
|
||||||
suffix = f"/{urlencode(variable)}" if variable else ""
|
suffix = f"/{url_encode(variable)}" if variable else ""
|
||||||
return f"{self.address}/api/v1/packages/{urlencode(package_base)}/patches{suffix}"
|
return f"{self.address}/api/v1/packages/{url_encode(package_base)}/patches{suffix}"
|
||||||
|
|
||||||
def _status_url(self) -> str:
|
def _status_url(self) -> str:
|
||||||
"""
|
"""
|
||||||
|
@ -107,8 +107,8 @@ class Pkgbuild(Mapping[str, Any]):
|
|||||||
|
|
||||||
def __getitem__(self, item: str) -> Any:
|
def __getitem__(self, item: str) -> Any:
|
||||||
"""
|
"""
|
||||||
get the field of the PKGBUILD. This method tries to get exact key value if possible; if none found, it tries to
|
get the field of the PKGBUILD. This method tries to get exact key value if possible; if none was found,
|
||||||
fetch function with the same name
|
it tries to fetch function with the same name
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
item(str): key name
|
item(str): key name
|
||||||
|
@ -53,7 +53,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
|
|||||||
def test_run_remove(args: argparse.Namespace, configuration: Configuration, repository: Repository,
|
def test_run_remove(args: argparse.Namespace, configuration: Configuration, repository: Repository,
|
||||||
package_ahriman: Package, mocker: MockerFixture) -> None:
|
package_ahriman: Package, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must run command and remove packages afterwards
|
must run command and remove packages afterward
|
||||||
"""
|
"""
|
||||||
args = _default_args(args)
|
args = _default_args(args)
|
||||||
args.remove = True
|
args.remove = True
|
||||||
|
@ -191,7 +191,7 @@ def test_extract_packages_by_status(application: Application, mocker: MockerFixt
|
|||||||
|
|
||||||
def test_extract_packages_from_database(application: Application, mocker: MockerFixture) -> None:
|
def test_extract_packages_from_database(application: Application, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must extract packages from database from database
|
must extract packages from database
|
||||||
"""
|
"""
|
||||||
packages_mock = mocker.patch("ahriman.core.database.SQLite.packages_get")
|
packages_mock = mocker.patch("ahriman.core.database.SQLite.packages_get")
|
||||||
Rebuild.extract_packages(application, None, from_database=True)
|
Rebuild.extract_packages(application, None, from_database=True)
|
||||||
|
@ -5,7 +5,7 @@ from pathlib import Path
|
|||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from unittest.mock import call as MockCall
|
from unittest.mock import call as MockCall
|
||||||
from urllib.parse import quote_plus as urlencode
|
from urllib.parse import quote_plus as url_encode
|
||||||
|
|
||||||
from ahriman.application.handlers.setup import Setup
|
from ahriman.application.handlers.setup import Setup
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
@ -148,7 +148,7 @@ def test_configuration_create_ahriman(args: argparse.Namespace, configuration: C
|
|||||||
MockCall("web", "port", str(args.web_port)),
|
MockCall("web", "port", str(args.web_port)),
|
||||||
MockCall("status", "address", f"http://127.0.0.1:{str(args.web_port)}"),
|
MockCall("status", "address", f"http://127.0.0.1:{str(args.web_port)}"),
|
||||||
MockCall("web", "unix_socket", str(args.web_unix_socket)),
|
MockCall("web", "unix_socket", str(args.web_unix_socket)),
|
||||||
MockCall("status", "address", f"http+unix://{urlencode(str(args.web_unix_socket))}"),
|
MockCall("status", "address", f"http+unix://{url_encode(str(args.web_unix_socket))}"),
|
||||||
MockCall("auth", "salt", pytest.helpers.anyvar(str, strict=True)),
|
MockCall("auth", "salt", pytest.helpers.anyvar(str, strict=True)),
|
||||||
])
|
])
|
||||||
write_mock.assert_called_once_with(pytest.helpers.anyvar(int))
|
write_mock.assert_called_once_with(pytest.helpers.anyvar(int))
|
||||||
|
@ -392,7 +392,7 @@ def test_subparsers_package_status_update(parser: argparse.ArgumentParser) -> No
|
|||||||
|
|
||||||
def test_subparsers_package_status_update_option_status(parser: argparse.ArgumentParser) -> None:
|
def test_subparsers_package_status_update_option_status(parser: argparse.ArgumentParser) -> None:
|
||||||
"""
|
"""
|
||||||
package-status-update command must convert status option to buildstatusenum instance
|
package-status-update command must convert status option to BuildStatusEnum instance
|
||||||
"""
|
"""
|
||||||
args = parser.parse_args(["-a", "x86_64", "-r", "repo", "package-status-update"])
|
args = parser.parse_args(["-a", "x86_64", "-r", "repo", "package-status-update"])
|
||||||
assert isinstance(args.status, BuildStatusEnum)
|
assert isinstance(args.status, BuildStatusEnum)
|
||||||
|
@ -115,7 +115,7 @@ def test_write_skip(lock: Lock) -> None:
|
|||||||
|
|
||||||
def test_write_locked(lock: Lock, mocker: MockerFixture) -> None:
|
def test_write_locked(lock: Lock, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must raise DuplicateRunError if cannot lock file
|
must raise DuplicateRunError if it cannot lock file
|
||||||
"""
|
"""
|
||||||
mocker.patch("ahriman.application.lock.Lock.perform_lock", return_value=False)
|
mocker.patch("ahriman.application.lock.Lock.perform_lock", return_value=False)
|
||||||
with pytest.raises(DuplicateRunError):
|
with pytest.raises(DuplicateRunError):
|
||||||
|
@ -287,6 +287,7 @@ def local_client(database: SQLite, configuration: Configuration) -> Client:
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
database(SQLite): database fixture
|
database(SQLite): database fixture
|
||||||
|
configuration(Configuration): configuration fixture
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Client: local status client test instance
|
Client: local status client test instance
|
||||||
|
@ -32,6 +32,7 @@ def test_process_build(executor: Executor, package_ahriman: Package, passwd: Any
|
|||||||
|
|
||||||
executor.process_build([package_ahriman], Packagers("packager"), bump_pkgrel=False)
|
executor.process_build([package_ahriman], Packagers("packager"), bump_pkgrel=False)
|
||||||
init_mock.assert_called_once_with(pytest.helpers.anyvar(int), pytest.helpers.anyvar(int), None)
|
init_mock.assert_called_once_with(pytest.helpers.anyvar(int), pytest.helpers.anyvar(int), None)
|
||||||
|
changes_mock.assert_called_once_with(package_ahriman.base)
|
||||||
depends_on_mock.assert_called_once_with()
|
depends_on_mock.assert_called_once_with()
|
||||||
dependencies_mock.assert_called_once_with(package_ahriman.base, Dependencies())
|
dependencies_mock.assert_called_once_with(package_ahriman.base, Dependencies())
|
||||||
# must move files (once)
|
# must move files (once)
|
||||||
|
@ -136,7 +136,7 @@ def test_event_add_failed_http_error(web_client: WebClient, mocker: MockerFixtur
|
|||||||
|
|
||||||
def test_event_add_failed_suppress(web_client: WebClient, mocker: MockerFixture) -> None:
|
def test_event_add_failed_suppress(web_client: WebClient, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must suppress any exception happened during events creaton and don't log
|
must suppress any exception happened during events creation and don't log
|
||||||
"""
|
"""
|
||||||
web_client.suppress_errors = True
|
web_client.suppress_errors = True
|
||||||
mocker.patch("requests.Session.request", side_effect=Exception())
|
mocker.patch("requests.Session.request", side_effect=Exception())
|
||||||
|
@ -5,7 +5,7 @@ from ahriman.models.scan_paths import ScanPaths
|
|||||||
|
|
||||||
def test_is_allowed() -> None:
|
def test_is_allowed() -> None:
|
||||||
"""
|
"""
|
||||||
must check if path is subpath of one in allowed list
|
must check if path is sub-path of one in allowed list
|
||||||
"""
|
"""
|
||||||
assert ScanPaths(["usr"]).is_allowed(Path("usr"))
|
assert ScanPaths(["usr"]).is_allowed(Path("usr"))
|
||||||
assert ScanPaths(["usr"]).is_allowed(Path("usr") / "lib")
|
assert ScanPaths(["usr"]).is_allowed(Path("usr") / "lib")
|
||||||
|
@ -252,6 +252,6 @@ async def test_username_request(base: BaseView) -> None:
|
|||||||
|
|
||||||
async def test_username_request_exception(base: BaseView) -> None:
|
async def test_username_request_exception(base: BaseView) -> None:
|
||||||
"""
|
"""
|
||||||
must not fail in case if cannot read request
|
must not fail in case if it cannot read request
|
||||||
"""
|
"""
|
||||||
assert await base.username() is None
|
assert await base.username() is None
|
||||||
|
Loading…
Reference in New Issue
Block a user