mirror of
				https://github.com/arcan1s/ahriman.git
				synced 2025-10-30 21:33:43 +00:00 
			
		
		
		
	add more tests
This commit is contained in:
		| @ -30,6 +30,8 @@ class Dump(Handler): | ||||
|     dump config handler | ||||
|     """ | ||||
|  | ||||
|     _print = print | ||||
|  | ||||
|     @classmethod | ||||
|     def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, config: Configuration) -> None: | ||||
|         """ | ||||
| @ -40,7 +42,7 @@ class Dump(Handler): | ||||
|         """ | ||||
|         config_dump = config.dump(architecture) | ||||
|         for section, values in sorted(config_dump.items()): | ||||
|             print(f"[{section}]") | ||||
|             Dump._print(f"[{section}]") | ||||
|             for key, value in sorted(values.items()): | ||||
|                 print(f"{key} = {value}") | ||||
|             print() | ||||
|                 Dump._print(f"{key} = {value}") | ||||
|             Dump._print() | ||||
|  | ||||
| @ -25,7 +25,7 @@ from typing import Dict, Iterable, List, Optional | ||||
| from ahriman.core.build_tools.task import Task | ||||
| from ahriman.core.report.report import Report | ||||
| from ahriman.core.repository.cleaner import Cleaner | ||||
| from ahriman.core.upload.uploader import Uploader | ||||
| from ahriman.core.upload.upload import Upload | ||||
| from ahriman.models.package import Package | ||||
|  | ||||
|  | ||||
| @ -118,7 +118,7 @@ class Executor(Cleaner): | ||||
|         if targets is None: | ||||
|             targets = self.config.getlist("upload", "target") | ||||
|         for target in targets: | ||||
|             Uploader.run(self.architecture, self.config, target, self.paths.repository) | ||||
|             Upload.run(self.architecture, self.config, target, self.paths.repository) | ||||
|  | ||||
|     def process_update(self, packages: Iterable[Path]) -> Path: | ||||
|         """ | ||||
|  | ||||
| @ -20,11 +20,11 @@ | ||||
| from pathlib import Path | ||||
|  | ||||
| from ahriman.core.configuration import Configuration | ||||
| from ahriman.core.upload.uploader import Uploader | ||||
| from ahriman.core.upload.upload import Upload | ||||
| from ahriman.core.util import check_output | ||||
|  | ||||
|  | ||||
| class Rsync(Uploader): | ||||
| class Rsync(Upload): | ||||
|     """ | ||||
|     rsync wrapper | ||||
|     :ivar remote: remote address to sync | ||||
| @ -38,7 +38,7 @@ class Rsync(Uploader): | ||||
|         :param architecture: repository architecture | ||||
|         :param config: configuration instance | ||||
|         """ | ||||
|         Uploader.__init__(self, architecture, config) | ||||
|         Upload.__init__(self, architecture, config) | ||||
|         section = config.get_section_name("rsync", architecture) | ||||
|         self.remote = config.get(section, "remote") | ||||
|  | ||||
|  | ||||
| @ -20,11 +20,11 @@ | ||||
| from pathlib import Path | ||||
|  | ||||
| from ahriman.core.configuration import Configuration | ||||
| from ahriman.core.upload.uploader import Uploader | ||||
| from ahriman.core.upload.upload import Upload | ||||
| from ahriman.core.util import check_output | ||||
|  | ||||
|  | ||||
| class S3(Uploader): | ||||
| class S3(Upload): | ||||
|     """ | ||||
|     aws-cli wrapper | ||||
|     :ivar bucket: full bucket name | ||||
| @ -38,7 +38,7 @@ class S3(Uploader): | ||||
|         :param architecture: repository architecture | ||||
|         :param config: configuration instance | ||||
|         """ | ||||
|         Uploader.__init__(self, architecture, config) | ||||
|         Upload.__init__(self, architecture, config) | ||||
|         section = config.get_section_name("s3", architecture) | ||||
|         self.bucket = config.get(section, "bucket") | ||||
|  | ||||
|  | ||||
| @ -26,7 +26,7 @@ from ahriman.core.exceptions import SyncFailed | ||||
| from ahriman.models.upload_settings import UploadSettings | ||||
| 
 | ||||
| 
 | ||||
| class Uploader: | ||||
| class Upload: | ||||
|     """ | ||||
|     base remote sync class | ||||
|     :ivar architecture: repository architecture | ||||
| @ -56,17 +56,17 @@ class Uploader: | ||||
|         provider = UploadSettings.from_option(target) | ||||
|         if provider == UploadSettings.Rsync: | ||||
|             from ahriman.core.upload.rsync import Rsync | ||||
|             uploader: Uploader = Rsync(architecture, config) | ||||
|             upload: Upload = Rsync(architecture, config) | ||||
|         elif provider == UploadSettings.S3: | ||||
|             from ahriman.core.upload.s3 import S3 | ||||
|             uploader = S3(architecture, config) | ||||
|             upload = S3(architecture, config) | ||||
|         else: | ||||
|             uploader = Uploader(architecture, config) | ||||
|             upload = Upload(architecture, config) | ||||
| 
 | ||||
|         try: | ||||
|             uploader.sync(path) | ||||
|             upload.sync(path) | ||||
|         except Exception: | ||||
|             uploader.logger.exception(f"remote sync failed for {provider.name}") | ||||
|             upload.logger.exception(f"remote sync failed for {provider.name}") | ||||
|             raise SyncFailed() | ||||
| 
 | ||||
|     def sync(self, path: Path) -> None: | ||||
| @ -31,7 +31,7 @@ from typing import Any, Dict, List, Optional, Set, Type, Union | ||||
| from ahriman.core.alpm.pacman import Pacman | ||||
| from ahriman.core.exceptions import InvalidPackageInfo | ||||
| from ahriman.core.util import check_output | ||||
| from ahriman.models.package_desciption import PackageDescription | ||||
| from ahriman.models.package_description import PackageDescription | ||||
| from ahriman.models.repository_paths import RepositoryPaths | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -11,7 +11,10 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc | ||||
|     must run command | ||||
|     """ | ||||
|     mocker.patch("pathlib.Path.mkdir") | ||||
|     application_mock = mocker.patch("ahriman.core.configuration.Configuration.dump") | ||||
|     print_mock = mocker.patch("ahriman.application.handlers.dump.Dump._print") | ||||
|     application_mock = mocker.patch("ahriman.core.configuration.Configuration.dump", | ||||
|                                     return_value=configuration.dump("x86_64")) | ||||
|  | ||||
|     Dump.run(args, "x86_64", configuration) | ||||
|     application_mock.assert_called_once() | ||||
|     print_mock.assert_called() | ||||
|  | ||||
| @ -7,7 +7,7 @@ from typing import Any, Type, TypeVar | ||||
| from ahriman.core.configuration import Configuration | ||||
| from ahriman.core.status.watcher import Watcher | ||||
| from ahriman.models.package import Package | ||||
| from ahriman.models.package_desciption import PackageDescription | ||||
| from ahriman.models.package_description import PackageDescription | ||||
| from ahriman.models.repository_paths import RepositoryPaths | ||||
|  | ||||
| T = TypeVar("T") | ||||
|  | ||||
| @ -0,0 +1,16 @@ | ||||
| from pytest_mock import MockerFixture | ||||
|  | ||||
| from ahriman.core.configuration import Configuration | ||||
| from ahriman.core.report.html import HTML | ||||
| from ahriman.models.package import Package | ||||
|  | ||||
|  | ||||
| def test_generate(configuration: Configuration, package_ahriman: Package, mocker: MockerFixture) -> None: | ||||
|     """ | ||||
|     must generate report | ||||
|     """ | ||||
|     write_mock = mocker.patch("pathlib.Path.write_text") | ||||
|  | ||||
|     report = HTML("x86_64", configuration) | ||||
|     report.generate([package_ahriman]) | ||||
|     write_mock.assert_called_once() | ||||
|  | ||||
| @ -0,0 +1,27 @@ | ||||
| import pytest | ||||
|  | ||||
| from pathlib import Path | ||||
| from pytest_mock import MockerFixture | ||||
|  | ||||
| from ahriman.core.configuration import Configuration | ||||
| from ahriman.core.exceptions import ReportFailed | ||||
| from ahriman.core.report.report import Report | ||||
| from ahriman.models.report_settings import ReportSettings | ||||
|  | ||||
|  | ||||
| def test_report_failure(configuration: Configuration, mocker: MockerFixture) -> None: | ||||
|     """ | ||||
|     must raise ReportFailed on errors | ||||
|     """ | ||||
|     mocker.patch("ahriman.core.report.html.HTML.generate", side_effect=Exception()) | ||||
|     with pytest.raises(ReportFailed): | ||||
|         Report.run("x86_64", configuration, ReportSettings.HTML.name, Path("path")) | ||||
|  | ||||
|  | ||||
| def test_report_html(configuration: Configuration, mocker: MockerFixture) -> None: | ||||
|     """ | ||||
|     must generate html report | ||||
|     """ | ||||
|     report_mock = mocker.patch("ahriman.core.report.html.HTML.generate") | ||||
|     Report.run("x86_64", configuration, ReportSettings.HTML.name, Path("path")) | ||||
|     report_mock.assert_called_once() | ||||
|  | ||||
| @ -0,0 +1,16 @@ | ||||
| from pathlib import Path | ||||
| from pytest_mock import MockerFixture | ||||
|  | ||||
| from ahriman.core.configuration import Configuration | ||||
| from ahriman.core.upload.rsync import Rsync | ||||
|  | ||||
|  | ||||
| def test_sync(configuration: Configuration, mocker: MockerFixture) -> None: | ||||
|     """ | ||||
|     must run sync command | ||||
|     """ | ||||
|     check_output_mock = mocker.patch("ahriman.core.upload.rsync.Rsync._check_output") | ||||
|  | ||||
|     upload = Rsync("x86_64", configuration) | ||||
|     upload.sync(Path("path")) | ||||
|     check_output_mock.assert_called_once() | ||||
|  | ||||
| @ -0,0 +1,16 @@ | ||||
| from pathlib import Path | ||||
| from pytest_mock import MockerFixture | ||||
|  | ||||
| from ahriman.core.configuration import Configuration | ||||
| from ahriman.core.upload.s3 import S3 | ||||
|  | ||||
|  | ||||
| def test_sync(configuration: Configuration, mocker: MockerFixture) -> None: | ||||
|     """ | ||||
|     must run sync command | ||||
|     """ | ||||
|     check_output_mock = mocker.patch("ahriman.core.upload.s3.S3._check_output") | ||||
|  | ||||
|     upload = S3("x86_64", configuration) | ||||
|     upload.sync(Path("path")) | ||||
|     check_output_mock.assert_called_once() | ||||
|  | ||||
| @ -0,0 +1,36 @@ | ||||
| import pytest | ||||
|  | ||||
| from pathlib import Path | ||||
| from pytest_mock import MockerFixture | ||||
|  | ||||
| from ahriman.core.configuration import Configuration | ||||
| from ahriman.core.exceptions import SyncFailed | ||||
| from ahriman.core.upload.upload import Upload | ||||
| from ahriman.models.upload_settings import UploadSettings | ||||
|  | ||||
|  | ||||
| def test_upload_failure(configuration: Configuration, mocker: MockerFixture) -> None: | ||||
|     """ | ||||
|     must raise SyncFailed on errors | ||||
|     """ | ||||
|     mocker.patch("ahriman.core.upload.rsync.Rsync.sync", side_effect=Exception()) | ||||
|     with pytest.raises(SyncFailed): | ||||
|         Upload.run("x86_64", configuration, UploadSettings.Rsync.name, Path("path")) | ||||
|  | ||||
|  | ||||
| def test_upload_rsync(configuration: Configuration, mocker: MockerFixture) -> None: | ||||
|     """ | ||||
|     must upload via rsync | ||||
|     """ | ||||
|     upload_mock = mocker.patch("ahriman.core.upload.rsync.Rsync.sync") | ||||
|     Upload.run("x86_64", configuration, UploadSettings.Rsync.name, Path("path")) | ||||
|     upload_mock.assert_called_once() | ||||
|  | ||||
|  | ||||
| def test_upload_s3(configuration: Configuration, mocker: MockerFixture) -> None: | ||||
|     """ | ||||
|     must upload via s3 | ||||
|     """ | ||||
|     upload_mock = mocker.patch("ahriman.core.upload.s3.S3.sync") | ||||
|     Upload.run("x86_64", configuration, UploadSettings.S3.name, Path("path")) | ||||
|     upload_mock.assert_called_once() | ||||
|  | ||||
| @ -1,8 +1,10 @@ | ||||
| import pytest | ||||
|  | ||||
| from unittest.mock import MagicMock, PropertyMock | ||||
|  | ||||
| from ahriman.models.build_status import BuildStatus, BuildStatusEnum | ||||
| from ahriman.models.package import Package | ||||
| from ahriman.models.package_desciption import PackageDescription | ||||
| from ahriman.models.package_description import PackageDescription | ||||
|  | ||||
|  | ||||
| @pytest.fixture | ||||
| @ -17,3 +19,33 @@ def package_tpacpi_bat_git() -> Package: | ||||
|         version="3.1.r12.g4959b52-1", | ||||
|         aur_url="https://aur.archlinux.org", | ||||
|         packages={"tpacpi-bat-git": PackageDescription()}) | ||||
|  | ||||
|  | ||||
| @pytest.fixture | ||||
| def pyalpm_handle(pyalpm_package_ahriman: MagicMock) -> MagicMock: | ||||
|     mock = MagicMock() | ||||
|     mock.handle.load_pkg.return_value = pyalpm_package_ahriman | ||||
|     return mock | ||||
|  | ||||
|  | ||||
| @pytest.fixture | ||||
| def pyalpm_package_ahriman(package_ahriman: Package) -> MagicMock: | ||||
|     mock = MagicMock() | ||||
|     type(mock).base = PropertyMock(return_value=package_ahriman.base) | ||||
|     type(mock).name = PropertyMock(return_value=package_ahriman.base) | ||||
|     type(mock).version = PropertyMock(return_value=package_ahriman.version) | ||||
|     return mock | ||||
|  | ||||
|  | ||||
| @pytest.fixture | ||||
| def pyalpm_package_description_ahriman(package_description_ahriman: PackageDescription) -> MagicMock: | ||||
|     mock = MagicMock() | ||||
|     type(mock).arch = PropertyMock(return_value=package_description_ahriman.architecture) | ||||
|     type(mock).builddate = PropertyMock(return_value=package_description_ahriman.build_date) | ||||
|     type(mock).desc = PropertyMock(return_value=package_description_ahriman.description) | ||||
|     type(mock).groups = PropertyMock(return_value=package_description_ahriman.groups) | ||||
|     type(mock).isize = PropertyMock(return_value=package_description_ahriman.installed_size) | ||||
|     type(mock).licenses = PropertyMock(return_value=package_description_ahriman.licenses) | ||||
|     type(mock).size = PropertyMock(return_value=package_description_ahriman.archive_size) | ||||
|     type(mock).url = PropertyMock(return_value=package_description_ahriman.url) | ||||
|     return mock | ||||
|  | ||||
| @ -1,6 +1,10 @@ | ||||
| import pytest | ||||
|  | ||||
| from pathlib import Path | ||||
| from pytest_mock import MockerFixture | ||||
| from unittest.mock import MagicMock, PropertyMock | ||||
|  | ||||
| from ahriman.core.exceptions import InvalidPackageInfo | ||||
| from ahriman.models.package import Package | ||||
| from ahriman.models.repository_paths import RepositoryPaths | ||||
|  | ||||
| @ -72,6 +76,44 @@ def test_web_url(package_ahriman: Package) -> None: | ||||
|     assert package_ahriman.base in package_ahriman.web_url | ||||
|  | ||||
|  | ||||
| def test_from_archive(package_ahriman: Package, pyalpm_handle: MagicMock, mocker: MockerFixture) -> None: | ||||
|     """ | ||||
|     must construct package from alpm library | ||||
|     """ | ||||
|     mocker.patch("ahriman.models.package_description.PackageDescription.from_package", | ||||
|                  return_value=package_ahriman.packages[package_ahriman.base]) | ||||
|     assert Package.from_archive(Path("path"), pyalpm_handle, package_ahriman.aur_url) == package_ahriman | ||||
|  | ||||
|  | ||||
| def test_from_aur(package_ahriman: Package, mocker: MockerFixture) -> None: | ||||
|     """ | ||||
|     must construct package from aur | ||||
|     """ | ||||
|     mock = MagicMock() | ||||
|     type(mock).name = PropertyMock(return_value=package_ahriman.base) | ||||
|     type(mock).package_base = PropertyMock(return_value=package_ahriman.base) | ||||
|     type(mock).version = PropertyMock(return_value=package_ahriman.version) | ||||
|     mocker.patch("aur.info", return_value=mock) | ||||
|  | ||||
|     package = Package.from_aur(package_ahriman.base, package_ahriman.aur_url) | ||||
|     assert package_ahriman.base == package.base | ||||
|     assert package_ahriman.version == package.version | ||||
|     assert package_ahriman.packages.keys() == package.packages.keys() | ||||
|  | ||||
|  | ||||
| def test_from_build(package_ahriman: Package, mocker: MockerFixture, resource_path_root: Path) -> None: | ||||
|     """ | ||||
|     must construct package from srcinfo | ||||
|     """ | ||||
|     srcinfo = (resource_path_root / "models" / "package_ahriman_srcinfo").read_text() | ||||
|     mocker.patch("pathlib.Path.read_text", return_value=srcinfo) | ||||
|  | ||||
|     package = Package.from_build(Path("path"), package_ahriman.aur_url) | ||||
|     assert package_ahriman.packages.keys() == package.packages.keys() | ||||
|     package_ahriman.packages = package.packages  # we are not going to test PackageDescription here | ||||
|     assert package_ahriman == package | ||||
|  | ||||
|  | ||||
| def test_from_json_view_1(package_ahriman: Package) -> None: | ||||
|     """ | ||||
|     must construct same object from json | ||||
| @ -98,12 +140,64 @@ def test_dependencies_with_version(mocker: MockerFixture, resource_path_root: Pa | ||||
|     must load correct list of dependencies with version | ||||
|     """ | ||||
|     srcinfo = (resource_path_root / "models" / "package_yay_srcinfo").read_text() | ||||
|  | ||||
|     mocker.patch("pathlib.Path.read_text", return_value=srcinfo) | ||||
|  | ||||
|     assert Package.dependencies(Path("path")) == {"git", "go", "pacman"} | ||||
|  | ||||
|  | ||||
| def test_full_version() -> None: | ||||
|     """ | ||||
|     must construct full version | ||||
|     """ | ||||
|     assert Package.full_version("1", "r2388.d30e3201", "1") == "1:r2388.d30e3201-1" | ||||
|     assert Package.full_version(None, "0.12.1", "1") == "0.12.1-1" | ||||
|  | ||||
|  | ||||
| def test_load_from_archive(package_ahriman: Package, pyalpm_handle: MagicMock, mocker: MockerFixture) -> None: | ||||
|     """ | ||||
|     must load package from package archive | ||||
|     """ | ||||
|     mocker.patch("pathlib.Path.is_file", return_value=True) | ||||
|     load_mock = mocker.patch("ahriman.models.package.Package.from_archive") | ||||
|  | ||||
|     Package.load(Path("path"), pyalpm_handle, package_ahriman.aur_url) | ||||
|     load_mock.assert_called_once() | ||||
|  | ||||
|  | ||||
| def test_load_from_aur(package_ahriman: Package, pyalpm_handle: MagicMock, mocker: MockerFixture) -> None: | ||||
|     """ | ||||
|     must load package from AUR | ||||
|     """ | ||||
|     load_mock = mocker.patch("ahriman.models.package.Package.from_aur") | ||||
|  | ||||
|     Package.load(Path("path"), pyalpm_handle, package_ahriman.aur_url) | ||||
|     load_mock.assert_called_once() | ||||
|  | ||||
|  | ||||
| def test_load_from_build(package_ahriman: Package, pyalpm_handle: MagicMock, mocker: MockerFixture) -> None: | ||||
|     """ | ||||
|     must load package from build directory | ||||
|     """ | ||||
|     mocker.patch("pathlib.Path.is_dir", return_value=True) | ||||
|     load_mock = mocker.patch("ahriman.models.package.Package.from_build") | ||||
|  | ||||
|     Package.load(Path("path"), pyalpm_handle, package_ahriman.aur_url) | ||||
|     load_mock.assert_called_once() | ||||
|  | ||||
|  | ||||
| def test_load_failure(package_ahriman: Package, pyalpm_handle: MagicMock, mocker: MockerFixture) -> None: | ||||
|     """ | ||||
|     must raise InvalidPackageInfo on exception | ||||
|     """ | ||||
|     mocker.patch("pathlib.Path.is_dir", side_effect=InvalidPackageInfo("exception!")) | ||||
|     with pytest.raises(InvalidPackageInfo): | ||||
|         Package.load(Path("path"), pyalpm_handle, package_ahriman.aur_url) | ||||
|  | ||||
|     mocker.patch("pathlib.Path.is_dir", side_effect=Exception()) | ||||
|     with pytest.raises(InvalidPackageInfo): | ||||
|         Package.load(Path("path"), pyalpm_handle, package_ahriman.aur_url) | ||||
|  | ||||
|  | ||||
| def test_actual_version(package_ahriman: Package, repository_paths: RepositoryPaths) -> None: | ||||
|     """ | ||||
|     must return same actual_version as version is | ||||
| @ -117,7 +211,6 @@ def test_actual_version_vcs(package_tpacpi_bat_git: Package, repository_paths: R | ||||
|     must return valid actual_version for VCS package | ||||
|     """ | ||||
|     srcinfo = (resource_path_root / "models" / "package_tpacpi-bat-git_srcinfo").read_text() | ||||
|  | ||||
|     mocker.patch("ahriman.models.package.Package._check_output", return_value=srcinfo) | ||||
|     mocker.patch("ahriman.core.build_tools.task.Task.fetch") | ||||
|  | ||||
|  | ||||
| @ -1,4 +1,6 @@ | ||||
| from ahriman.models.package_desciption import PackageDescription | ||||
| from unittest.mock import MagicMock | ||||
|  | ||||
| from ahriman.models.package_description import PackageDescription | ||||
|  | ||||
|  | ||||
| def test_filepath(package_description_ahriman: PackageDescription) -> None: | ||||
| @ -15,3 +17,13 @@ def test_filepath_empty(package_description_ahriman: PackageDescription) -> None | ||||
|     """ | ||||
|     package_description_ahriman.filename = None | ||||
|     assert package_description_ahriman.filepath is None | ||||
|  | ||||
|  | ||||
| def test_from_package(package_description_ahriman: PackageDescription, | ||||
|                       pyalpm_package_description_ahriman: MagicMock) -> None: | ||||
|     """ | ||||
|     must construct description from package object | ||||
|     """ | ||||
|     package_description = PackageDescription.from_package(pyalpm_package_description_ahriman, | ||||
|                                                           package_description_ahriman.filepath) | ||||
|     assert package_description_ahriman == package_description | ||||
|  | ||||
							
								
								
									
										34
									
								
								tests/testresources/models/package_ahriman_srcinfo
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								tests/testresources/models/package_ahriman_srcinfo
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | ||||
| pkgbase = ahriman | ||||
|         pkgdesc = ArcHlinux ReposItory MANager | ||||
|         pkgver = 0.12.1 | ||||
|         pkgrel = 1 | ||||
|         url = https://github.com/arcan1s/ahriman | ||||
|         arch = any | ||||
|         license = GPL3 | ||||
|         makedepends = python-pip | ||||
|         depends = devtools | ||||
|         depends = git | ||||
|         depends = pyalpm | ||||
|         depends = python-aur | ||||
|         depends = python-srcinfo | ||||
|         optdepends = aws-cli: sync to s3 | ||||
|         optdepends = breezy: -bzr packages support | ||||
|         optdepends = darcs: -darcs packages support | ||||
|         optdepends = gnupg: package and repository sign | ||||
|         optdepends = mercurial: -hg packages support | ||||
|         optdepends = python-aiohttp: web server | ||||
|         optdepends = python-aiohttp-jinja2: web server | ||||
|         optdepends = python-jinja: html report generation | ||||
|         optdepends = python-requests: web server | ||||
|         optdepends = rsync: sync by using rsync | ||||
|         optdepends = subversion: -svn packages support | ||||
|         backup = etc/ahriman.ini | ||||
|         backup = etc/ahriman.ini.d/logging.ini | ||||
|         source = https://github.com/arcan1s/ahriman/releases/download/0.12.1/ahriman-0.12.1-src.tar.xz | ||||
|         source = ahriman.sysusers | ||||
|         source = ahriman.tmpfiles | ||||
|         sha512sums = 8acc57f937d587ca665c29092cadddbaf3ba0b80e870b80d1551e283aba8f21306f9030a26fec8c71ab5863316f5f5f061b7ddc63cdff9e6d5a885f28ef1893d | ||||
|         sha512sums = 13718afec2c6786a18f0b223ef8e58dccf0688bca4cdbe203f14071f5031ed20120eb0ce38b52c76cfd6e8b6581a9c9eaa2743eb11abbaca637451a84c33f075 | ||||
|         sha512sums = 55b20f6da3d66e7bbf2add5d95a3b60632df121717d25a993e56e737d14f51fe063eb6f1b38bd81cc32e05db01c0c1d80aaa720c45cde87f238d8b46cdb8cbc4 | ||||
|  | ||||
| pkgname = ahriman | ||||
		Reference in New Issue
	
	Block a user