From e835668f7d0211cfa5936a0e2337004de00beff3 Mon Sep 17 00:00:00 2001 From: Evgenii Alekseev Date: Sat, 18 Jul 2026 21:55:26 +0300 Subject: [PATCH] feat: add cooldown for aur packages --- .../package/share/ahriman/settings/ahriman.ini | 2 ++ .../src/ahriman/core/build_tools/package_version.py | 10 ++++++++-- .../src/ahriman/core/configuration/schema.py | 9 +++++++-- .../src/ahriman/models/package_description.py | 1 + .../core/build_tools/test_package_version.py | 13 +++++++++++++ docs/configuration.rst | 1 + 6 files changed, 32 insertions(+), 4 deletions(-) diff --git a/ahriman-core/package/share/ahriman/settings/ahriman.ini b/ahriman-core/package/share/ahriman/settings/ahriman.ini index 2708105f..e6942879 100644 --- a/ahriman-core/package/share/ahriman/settings/ahriman.ini +++ b/ahriman-core/package/share/ahriman/settings/ahriman.ini @@ -42,6 +42,8 @@ retry_backoff = 1.0 ;include_debug_packages = yes ; List of additional flags passed to makechrootpkg command. ;makechrootpkg_flags = +; Minimal age in seconds since the latest AUR package modification before automatic updates are allowed. +;min_age = 0 ; List of additional flags passed to makepkg command. makepkg_flags = --nocolor --ignorearch ; List of paths to be used for implicit dependency scan. Regular expressions are supported. diff --git a/ahriman-core/src/ahriman/core/build_tools/package_version.py b/ahriman-core/src/ahriman/core/build_tools/package_version.py index 23982b19..44e178e1 100644 --- a/ahriman-core/src/ahriman/core/build_tools/package_version.py +++ b/ahriman-core/src/ahriman/core/build_tools/package_version.py @@ -22,6 +22,7 @@ from ahriman.core.configuration import Configuration from ahriman.core.log import LazyLogging from ahriman.core.utils import full_version, utcnow from ahriman.models.package import Package +from ahriman.models.package_source import PackageSource from ahriman.models.pkgbuild import Pkgbuild @@ -64,7 +65,7 @@ class PackageVersion(LazyLogging): return full_version(pkgbuild.get("epoch"), pkgbuild["pkgver"], pkgbuild["pkgrel"]) except Exception: - self.logger.exception("cannot determine version of VCS package") + self.logger.exception("cannot determine version of VCS package %s", self.package.base) finally: # clear log files generated by devtools for log_file in paths.cache_for(self.package.base).glob("*.log"): @@ -103,9 +104,14 @@ class PackageVersion(LazyLogging): Returns: bool: ``True`` if the package is out-of-dated and ``False`` otherwise """ + min_allowed_age = configuration.getint("build", "min_age", fallback=0) + min_build_date = utcnow().timestamp() - min_allowed_age + if remote.remote.source == PackageSource.AUR and PackageVersion(remote).is_newer_than(min_build_date): + self.logger.info("package %s was modified too recently, skip update", remote.base) + return False + vcs_allowed_age = configuration.getint("build", "vcs_allowed_age", fallback=0) min_vcs_build_date = utcnow().timestamp() - vcs_allowed_age - if calculate_version and not self.is_newer_than(min_vcs_build_date): remote_version = PackageVersion(remote).actual_version(configuration) else: diff --git a/ahriman-core/src/ahriman/core/configuration/schema.py b/ahriman-core/src/ahriman/core/configuration/schema.py index e270ac90..a56c69f0 100644 --- a/ahriman-core/src/ahriman/core/configuration/schema.py +++ b/ahriman-core/src/ahriman/core/configuration/schema.py @@ -206,7 +206,7 @@ CONFIGURATION_SCHEMA: ConfigurationSchema = { "type": "boolean", "coerce": "boolean", }, - "makepkg_flags": { + "makechrootpkg_flags": { "type": "list", "coerce": "list", "schema": { @@ -214,7 +214,12 @@ CONFIGURATION_SCHEMA: ConfigurationSchema = { "empty": False, }, }, - "makechrootpkg_flags": { + "min_age": { + "type": "integer", + "coerce": "integer", + "min": 0, + }, + "makepkg_flags": { "type": "list", "coerce": "list", "schema": { diff --git a/ahriman-core/src/ahriman/models/package_description.py b/ahriman-core/src/ahriman/models/package_description.py index ef517802..15a90050 100644 --- a/ahriman-core/src/ahriman/models/package_description.py +++ b/ahriman-core/src/ahriman/models/package_description.py @@ -113,6 +113,7 @@ class PackageDescription: Self: package properties based on source AUR package """ return cls( + build_date=int(package.last_modified.timestamp()), depends=package.depends, make_depends=package.make_depends, opt_depends=package.opt_depends, diff --git a/ahriman-core/tests/ahriman/core/build_tools/test_package_version.py b/ahriman-core/tests/ahriman/core/build_tools/test_package_version.py index d32a09bf..176d00c2 100644 --- a/ahriman-core/tests/ahriman/core/build_tools/test_package_version.py +++ b/ahriman-core/tests/ahriman/core/build_tools/test_package_version.py @@ -90,6 +90,19 @@ def test_is_outdated_true(package_ahriman: Package, configuration: Configuration actual_version_mock.assert_called_once_with(configuration) +def test_is_outdated_aur_cooldown(package_ahriman: Package, configuration: Configuration) -> None: + """ + must be not outdated if AUR package is modified too recently + """ + other = Package.from_json(package_ahriman.view()) + other.version = other.version.replace("-1", "-2") + for description in other.packages.values(): + description.build_date = int(utcnow().timestamp()) + configuration.set_option("build", "min_age", "3600") + + assert not PackageVersion(package_ahriman).is_outdated(other, configuration) + + def test_is_outdated_no_version_calculation(package_ahriman: Package, configuration: Configuration, mocker: MockerFixture) -> None: """ diff --git a/docs/configuration.rst b/docs/configuration.rst index e1248fc6..0c523731 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -136,6 +136,7 @@ Build related configuration. Group name can refer to architecture, e.g. ``build: * ``include_debug_packages`` - distribute debug packages, boolean, optional, default ``yes``. * ``makepkg_flags`` - additional flags passed to ``makepkg`` command, space separated list of strings, optional. * ``makechrootpkg_flags`` - additional flags passed to ``makechrootpkg`` command, space separated list of strings, optional. +* ``min_age`` - minimal age in seconds since the latest AUR package modification before automatic updates are allowed, integer, optional, default ``0``. * ``scan_paths`` - paths to be used for implicit dependencies scan, space separated list of strings, optional. If any of those paths is matched against the path, it will be added to the allowed list. * ``triggers`` - list of ``ahriman.core.triggers.Trigger`` class implementation (e.g. ``ahriman.core.report.ReportTrigger ahriman.core.upload.UploadTrigger``) which will be loaded and run at the end of processing, space separated list of strings, optional. You can also specify triggers by their paths, e.g. ``/usr/lib/python3.10/site-packages/ahriman/core/report/report.py.ReportTrigger``. Triggers are run in the order of definition. * ``triggers_known`` - optional list of ``ahriman.core.triggers.Trigger`` class implementations which are not run automatically and used only for trigger discovery and configuration validation.