mirror of
https://github.com/arcan1s/ahriman.git
synced 2026-02-24 13:49:48 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 49ebbc34fa | |||
| e376f1307f | |||
| 415fcf58ce | |||
| 17a2d6362c | |||
| e6275de4ed | |||
| 4d009cba6d | |||
| f6defbf90d |
@@ -2,7 +2,7 @@
|
||||
|
||||
pkgbase='ahriman'
|
||||
pkgname=('ahriman' 'ahriman-core' 'ahriman-triggers' 'ahriman-web')
|
||||
pkgver=2.20.0rc2
|
||||
pkgver=2.20.0rc4
|
||||
pkgrel=1
|
||||
pkgdesc="ArcH linux ReposItory MANager"
|
||||
arch=('any')
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.TH AHRIMAN "1" "2026\-02\-20" "ahriman 2.20.0rc2" "ArcH linux ReposItory MANager"
|
||||
.TH AHRIMAN "1" "2026\-02\-21" "ahriman 2.20.0rc4" "ArcH linux ReposItory MANager"
|
||||
.SH NAME
|
||||
ahriman \- ArcH linux ReposItory MANager
|
||||
.SH SYNOPSIS
|
||||
|
||||
@@ -245,7 +245,7 @@ _shtab_ahriman_init_options=(
|
||||
{--makeflags-jobs,--no-makeflags-jobs}"[append MAKEFLAGS variable with parallelism set to number of cores (default\: True)]:makeflags_jobs:"
|
||||
"--mirror[use the specified explicitly mirror instead of including mirrorlist (default\: None)]:mirror:"
|
||||
{--multilib,--no-multilib}"[add or do not multilib repository (default\: True)]:multilib:"
|
||||
"--packager[packager name and email]:packager:"
|
||||
"--packager[packager name and email (default\: None)]:packager:"
|
||||
"--server[server to be used for devtools. If none set, local files will be used (default\: None)]:server:"
|
||||
"--sign-key[sign key id (default\: None)]:sign_key:"
|
||||
"*--sign-target[sign options (default\: None)]:sign_target:(disabled packages repository)"
|
||||
@@ -526,7 +526,7 @@ _shtab_ahriman_repo_init_options=(
|
||||
{--makeflags-jobs,--no-makeflags-jobs}"[append MAKEFLAGS variable with parallelism set to number of cores (default\: True)]:makeflags_jobs:"
|
||||
"--mirror[use the specified explicitly mirror instead of including mirrorlist (default\: None)]:mirror:"
|
||||
{--multilib,--no-multilib}"[add or do not multilib repository (default\: True)]:multilib:"
|
||||
"--packager[packager name and email]:packager:"
|
||||
"--packager[packager name and email (default\: None)]:packager:"
|
||||
"--server[server to be used for devtools. If none set, local files will be used (default\: None)]:server:"
|
||||
"--sign-key[sign key id (default\: None)]:sign_key:"
|
||||
"*--sign-target[sign options (default\: None)]:sign_target:(disabled packages repository)"
|
||||
@@ -583,7 +583,7 @@ _shtab_ahriman_repo_setup_options=(
|
||||
{--makeflags-jobs,--no-makeflags-jobs}"[append MAKEFLAGS variable with parallelism set to number of cores (default\: True)]:makeflags_jobs:"
|
||||
"--mirror[use the specified explicitly mirror instead of including mirrorlist (default\: None)]:mirror:"
|
||||
{--multilib,--no-multilib}"[add or do not multilib repository (default\: True)]:multilib:"
|
||||
"--packager[packager name and email]:packager:"
|
||||
"--packager[packager name and email (default\: None)]:packager:"
|
||||
"--server[server to be used for devtools. If none set, local files will be used (default\: None)]:server:"
|
||||
"--sign-key[sign key id (default\: None)]:sign_key:"
|
||||
"*--sign-target[sign options (default\: None)]:sign_target:(disabled packages repository)"
|
||||
@@ -757,7 +757,7 @@ _shtab_ahriman_service_setup_options=(
|
||||
{--makeflags-jobs,--no-makeflags-jobs}"[append MAKEFLAGS variable with parallelism set to number of cores (default\: True)]:makeflags_jobs:"
|
||||
"--mirror[use the specified explicitly mirror instead of including mirrorlist (default\: None)]:mirror:"
|
||||
{--multilib,--no-multilib}"[add or do not multilib repository (default\: True)]:multilib:"
|
||||
"--packager[packager name and email]:packager:"
|
||||
"--packager[packager name and email (default\: None)]:packager:"
|
||||
"--server[server to be used for devtools. If none set, local files will be used (default\: None)]:server:"
|
||||
"--sign-key[sign key id (default\: None)]:sign_key:"
|
||||
"*--sign-target[sign options (default\: None)]:sign_target:(disabled packages repository)"
|
||||
@@ -792,7 +792,7 @@ _shtab_ahriman_setup_options=(
|
||||
{--makeflags-jobs,--no-makeflags-jobs}"[append MAKEFLAGS variable with parallelism set to number of cores (default\: True)]:makeflags_jobs:"
|
||||
"--mirror[use the specified explicitly mirror instead of including mirrorlist (default\: None)]:mirror:"
|
||||
{--multilib,--no-multilib}"[add or do not multilib repository (default\: True)]:multilib:"
|
||||
"--packager[packager name and email]:packager:"
|
||||
"--packager[packager name and email (default\: None)]:packager:"
|
||||
"--server[server to be used for devtools. If none set, local files will be used (default\: None)]:server:"
|
||||
"--sign-key[sign key id (default\: None)]:sign_key:"
|
||||
"*--sign-target[sign options (default\: None)]:sign_target:(disabled packages repository)"
|
||||
|
||||
@@ -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.20.0rc2"
|
||||
__version__ = "2.20.0rc4"
|
||||
|
||||
@@ -251,7 +251,7 @@ class Setup(Handler):
|
||||
|
||||
content = f"PACKAGER='{packager}'\n"
|
||||
if makeflags_jobs:
|
||||
content += """MAKEFLAGS="-j$(nproc)"\n"""
|
||||
content += "MAKEFLAGS=\"-j$(nproc)\"\n"
|
||||
|
||||
uid, _ = paths.root_owner
|
||||
home_dir = Path(getpwuid(uid).pw_dir)
|
||||
|
||||
@@ -69,8 +69,8 @@ class OAuth(Mapping):
|
||||
Returns:
|
||||
str: login control as html code to insert
|
||||
"""
|
||||
return f"""<a class="nav-link" href="/api/v1/login" title="login via OAuth2"><i class="bi bi-{
|
||||
self.icon}"></i> login</a>"""
|
||||
return f"<a class=\"nav-link\" href=\"/api/v1/login\" title=\"login via OAuth2\"><i class=\"bi bi-{
|
||||
self.icon}\"></i> login</a>"
|
||||
|
||||
@staticmethod
|
||||
def get_provider(name: str) -> type[aioauth_client.OAuth2Client]:
|
||||
|
||||
@@ -292,6 +292,7 @@ class PackageOperations(Operations):
|
||||
(:package_base, :status, :last_updated, :repository)
|
||||
on conflict (package_base, repository) do update set
|
||||
status = :status, last_updated = :last_updated
|
||||
where status != :status
|
||||
""",
|
||||
{
|
||||
"package_base": package_base,
|
||||
|
||||
@@ -22,7 +22,7 @@ import sys
|
||||
|
||||
from functools import cached_property
|
||||
from requests.adapters import BaseAdapter, HTTPAdapter
|
||||
from typing import Any, IO, Literal
|
||||
from typing import Any, ClassVar, IO, Literal
|
||||
from urllib3.util.retry import Retry
|
||||
|
||||
from ahriman import __version__
|
||||
@@ -39,14 +39,18 @@ class SyncHttpClient(LazyLogging):
|
||||
wrapper around requests library to reduce boilerplate
|
||||
|
||||
Attributes:
|
||||
DEFAULT_MAX_RETRIES(int): (class attribute) default maximum amount of retries
|
||||
DEFAULT_RETRY_BACKOFF(float): (class attribute) default retry exponential backoff
|
||||
DEFAULT_TIMEOUT(int | None): (class attribute) default HTTP request timeout in seconds
|
||||
auth(tuple[str, str] | None): HTTP basic auth object if set
|
||||
retry(Retry): retry policy of the HTTP client. Disabled by default
|
||||
retry(Retry): retry policy of the HTTP client
|
||||
suppress_errors(bool): suppress logging of request errors
|
||||
timeout(int | None): HTTP request timeout in seconds
|
||||
"""
|
||||
|
||||
retry: Retry = Retry()
|
||||
timeout: int | None = None
|
||||
DEFAULT_MAX_RETRIES: ClassVar[int] = 0
|
||||
DEFAULT_RETRY_BACKOFF: ClassVar[float] = 0.0
|
||||
DEFAULT_TIMEOUT: ClassVar[int | None] = 30
|
||||
|
||||
def __init__(self, configuration: Configuration | None = None, section: str | None = None, *,
|
||||
suppress_errors: bool = False) -> None:
|
||||
@@ -65,10 +69,10 @@ class SyncHttpClient(LazyLogging):
|
||||
|
||||
self.suppress_errors = suppress_errors
|
||||
|
||||
self.timeout = configuration.getint(section, "timeout", fallback=30)
|
||||
self.timeout = configuration.getint(section, "timeout", fallback=self.DEFAULT_TIMEOUT)
|
||||
self.retry = SyncHttpClient.retry_policy(
|
||||
max_retries=configuration.getint(section, "max_retries", fallback=0),
|
||||
retry_backoff=configuration.getfloat(section, "retry_backoff", fallback=0.0),
|
||||
max_retries=configuration.getint(section, "max_retries", fallback=self.DEFAULT_MAX_RETRIES),
|
||||
retry_backoff=configuration.getfloat(section, "retry_backoff", fallback=self.DEFAULT_RETRY_BACKOFF),
|
||||
)
|
||||
|
||||
@cached_property
|
||||
|
||||
@@ -131,7 +131,6 @@ class ReportTrigger(Trigger):
|
||||
"template_full": {
|
||||
"type": "string",
|
||||
"dependencies": ["templates"],
|
||||
"required": True,
|
||||
"empty": False,
|
||||
},
|
||||
"templates": {
|
||||
|
||||
@@ -88,11 +88,9 @@ class Repository(Executor, UpdateHandler):
|
||||
Args:
|
||||
configuration(Configuration): configuration instance
|
||||
"""
|
||||
AUR.timeout = configuration.getint("aur", "timeout", fallback=30)
|
||||
AUR.retry = AUR.retry_policy(
|
||||
max_retries=configuration.getint("aur", "max_retries", fallback=0),
|
||||
retry_backoff=configuration.getfloat("aur", "retry_backoff", fallback=0.0),
|
||||
)
|
||||
AUR.DEFAULT_MAX_RETRIES = configuration.getint("aur", "max_retries", fallback=0)
|
||||
AUR.DEFAULT_RETRY_BACKOFF = configuration.getfloat("aur", "retry_backoff", fallback=0.0)
|
||||
AUR.DEFAULT_TIMEOUT = configuration.getint("aur", "timeout", fallback=30)
|
||||
|
||||
def _set_context(self) -> None:
|
||||
"""
|
||||
|
||||
@@ -375,7 +375,7 @@ class Package(LazyLogging):
|
||||
Returns:
|
||||
str: print-friendly string
|
||||
"""
|
||||
details = "" if self.is_single_package else f""" ({" ".join(sorted(self.packages.keys()))})"""
|
||||
details = "" if self.is_single_package else f" ({" ".join(sorted(self.packages.keys()))})"
|
||||
return f"{self.base}{details}"
|
||||
|
||||
def vercmp(self, version: str) -> int:
|
||||
|
||||
@@ -147,7 +147,7 @@ class PkgbuildPatch:
|
||||
"""
|
||||
if "$" in source:
|
||||
# copy from library method with double quotes instead
|
||||
return f"""\"{source.replace("\"", "'\"'")}\""""
|
||||
return f"\"{source.replace("\"", "'\"'")}\""
|
||||
# otherwise just return normal call
|
||||
return shlex.quote(source)
|
||||
|
||||
@@ -195,13 +195,13 @@ class PkgbuildPatch:
|
||||
"""
|
||||
if isinstance(self.value, list): # list like
|
||||
value = " ".join(map(self.quote, self.value))
|
||||
return f"""{self.key}=({value})"""
|
||||
return f"{self.key}=({value})"
|
||||
if self.is_plain_diff: # no additional logic for plain diffs
|
||||
return self.value
|
||||
# we suppose that function values are only supported in string-like values
|
||||
if self.is_function:
|
||||
return f"{self.key} {self.value}" # no quoting enabled here
|
||||
return f"""{self.key}={self.quote(self.value)}"""
|
||||
return f"{self.key}={self.quote(self.value)}"
|
||||
|
||||
def substitute(self, variables: dict[str, str]) -> str | list[str]:
|
||||
"""
|
||||
|
||||
@@ -154,7 +154,7 @@ def setup_auth(application: Application, configuration: Configuration, validator
|
||||
cookie_name="AHRIMAN",
|
||||
max_age=validator.max_age,
|
||||
httponly=True,
|
||||
samesite="Strict",
|
||||
samesite="Lax",
|
||||
)
|
||||
setup_session(application, storage)
|
||||
|
||||
|
||||
@@ -157,8 +157,7 @@ def test_package_update_get(database: SQLite, package_ahriman: Package) -> None:
|
||||
database.package_update(package_ahriman)
|
||||
database.status_update(package_ahriman.base, status)
|
||||
assert next((db_package, db_status)
|
||||
for db_package, db_status in database.packages_get()
|
||||
if db_package.base == package_ahriman.base) == (package_ahriman, status)
|
||||
for db_package, db_status in database.packages_get()) == (package_ahriman, status)
|
||||
|
||||
|
||||
def test_package_update_remove_get(database: SQLite, package_ahriman: Package) -> None:
|
||||
@@ -176,10 +175,10 @@ def test_package_update_update(database: SQLite, package_ahriman: Package) -> No
|
||||
"""
|
||||
database.package_update(package_ahriman)
|
||||
package_ahriman.version = "1.0.0"
|
||||
|
||||
database.package_update(package_ahriman)
|
||||
assert next(db_package.version
|
||||
for db_package, _ in database.packages_get()
|
||||
if db_package.base == package_ahriman.base) == package_ahriman.version
|
||||
for db_package, _ in database.packages_get()) == package_ahriman.version
|
||||
|
||||
|
||||
def test_status_update(database: SQLite, package_ahriman: Package) -> None:
|
||||
@@ -188,6 +187,19 @@ def test_status_update(database: SQLite, package_ahriman: Package) -> None:
|
||||
"""
|
||||
status = BuildStatus()
|
||||
|
||||
database.package_update(package_ahriman, database._repository_id)
|
||||
database.status_update(package_ahriman.base, status, database._repository_id)
|
||||
assert database.packages_get(database._repository_id) == [(package_ahriman, status)]
|
||||
database.package_update(package_ahriman)
|
||||
database.status_update(package_ahriman.base, status)
|
||||
assert database.packages_get() == [(package_ahriman, status)]
|
||||
|
||||
|
||||
def test_status_update_skip_same_status(database: SQLite, package_ahriman: Package) -> None:
|
||||
"""
|
||||
must preserve original timestamp when status is unchanged
|
||||
"""
|
||||
status = BuildStatus(timestamp=42)
|
||||
database.package_update(package_ahriman)
|
||||
|
||||
database.status_update(package_ahriman.base, status)
|
||||
database.status_update(package_ahriman.base, BuildStatus())
|
||||
assert next(db_status.timestamp
|
||||
for _, db_status in database.packages_get()) == status.timestamp
|
||||
|
||||
@@ -49,14 +49,18 @@ def test_retry_policy() -> None:
|
||||
"""
|
||||
must set retry policy
|
||||
"""
|
||||
SyncHttpClient.retry = SyncHttpClient.retry_policy(1, 2.0)
|
||||
AUR.retry = AUR.retry_policy(3, 4.0)
|
||||
SyncHttpClient.DEFAULT_MAX_RETRIES = 1
|
||||
SyncHttpClient.DEFAULT_RETRY_BACKOFF = 2.0
|
||||
AUR.DEFAULT_MAX_RETRIES = 3
|
||||
AUR.DEFAULT_RETRY_BACKOFF = 4.0
|
||||
|
||||
assert SyncHttpClient.retry.connect == 1
|
||||
assert SyncHttpClient.retry.backoff_factor == 2.0
|
||||
client = SyncHttpClient()
|
||||
assert client.retry.connect == 1
|
||||
assert client.retry.backoff_factor == 2.0
|
||||
|
||||
assert AUR.retry.connect == 3
|
||||
assert AUR.retry.backoff_factor == 4.0
|
||||
aur = AUR()
|
||||
assert aur.retry.connect == 3
|
||||
assert aur.retry.backoff_factor == 4.0
|
||||
|
||||
|
||||
def test_exception_response_text() -> None:
|
||||
|
||||
@@ -31,8 +31,9 @@ def test_set_globals(configuration: Configuration) -> None:
|
||||
configuration.set_option("aur", "max_retries", "10")
|
||||
|
||||
Repository._set_globals(configuration)
|
||||
assert AUR.timeout == 42
|
||||
assert AUR.retry.connect == 10
|
||||
aur = AUR()
|
||||
assert aur.timeout == 42
|
||||
assert aur.retry.connect == 10
|
||||
|
||||
|
||||
def test_set_context(configuration: Configuration, database: SQLite, mocker: MockerFixture) -> None:
|
||||
|
||||
Reference in New Issue
Block a user