From 917ec48be593916c90210b371065d6d872edaa3a Mon Sep 17 00:00:00 2001 From: Evgeniy Alekseev Date: Tue, 31 Jan 2023 14:34:09 +0200 Subject: [PATCH] handle architecture specific fields for dependencies This change requires srcinfo at least 0.1.2 version. Unfortunatelly aur api don't support architecture specific arrays for now, so we just leave it as is Closes #82 --- .../application/application_packages.py | 2 +- .../application/application_repository.py | 2 +- src/ahriman/application/handlers/patch.py | 7 ++-- src/ahriman/core/repository/update_handler.py | 2 +- src/ahriman/models/package.py | 14 +++++--- .../handlers/test_handler_patch.py | 6 ++-- .../core/repository/test_update_handler.py | 2 +- tests/ahriman/core/test_util.py | 1 + tests/ahriman/models/test_package.py | 36 ++++++++++++++++--- .../package_jellyfin-ffmpeg5-bin_srcinfo | 28 +++++++++++++++ 10 files changed, 81 insertions(+), 19 deletions(-) create mode 100644 tests/testresources/models/package_jellyfin-ffmpeg5-bin_srcinfo diff --git a/src/ahriman/application/application/application_packages.py b/src/ahriman/application/application/application_packages.py index 5f5edf7c..9dba0605 100644 --- a/src/ahriman/application/application/application_packages.py +++ b/src/ahriman/application/application/application_packages.py @@ -84,7 +84,7 @@ class ApplicationPackages(ApplicationProperties): without_dependencies(bool): if set, dependency check will be disabled """ source_dir = Path(source) - package = Package.from_build(source_dir) + package = Package.from_build(source_dir, self.architecture) cache_dir = self.repository.paths.cache_for(package.base) shutil.copytree(source_dir, cache_dir) # copy package to store in caches Sources.init(cache_dir) # we need to run init command in directory where we do have permissions diff --git a/src/ahriman/application/application/application_repository.py b/src/ahriman/application/application/application_repository.py index eaf30295..e6685e6a 100644 --- a/src/ahriman/application/application/application_repository.py +++ b/src/ahriman/application/application/application_repository.py @@ -111,7 +111,7 @@ class ApplicationRepository(ApplicationProperties): def unknown_local(probe: Package) -> List[str]: cache_dir = self.repository.paths.cache_for(probe.base) - local = Package.from_build(cache_dir) + local = Package.from_build(cache_dir, self.architecture) packages = set(probe.packages.keys()).difference(local.packages.keys()) return list(packages) diff --git a/src/ahriman/application/handlers/patch.py b/src/ahriman/application/handlers/patch.py index 73d16100..65e3fa9d 100644 --- a/src/ahriman/application/handlers/patch.py +++ b/src/ahriman/application/handlers/patch.py @@ -58,7 +58,7 @@ class Patch(Handler): patch = Patch.patch_create_from_function(args.variable, args.patch) Patch.patch_set_create(application, args.package, patch) elif args.action == Action.Update and args.variable is None: - package_base, patch = Patch.patch_create_from_diff(args.package, args.track) + package_base, patch = Patch.patch_create_from_diff(args.package, architecture, args.track) Patch.patch_set_create(application, package_base, patch) elif args.action == Action.List: Patch.patch_set_list(application, args.package, args.variable, args.exit_code) @@ -66,19 +66,20 @@ class Patch(Handler): Patch.patch_set_remove(application, args.package, args.variable) @staticmethod - def patch_create_from_diff(sources_dir: Path, track: List[str]) -> Tuple[str, PkgbuildPatch]: + def patch_create_from_diff(sources_dir: Path, architecture: str, track: List[str]) -> Tuple[str, PkgbuildPatch]: """ create PKGBUILD plain diff patches from sources directory Args: sources_dir(Path): path to directory with the package sources + architecture(str): repository architecture track(List[str]): track files which match the glob before creating the patch Returns: Tuple[str, PkgbuildPatch]: package base and created PKGBUILD patch based on the diff from master HEAD to current files """ - package = Package.from_build(sources_dir) + package = Package.from_build(sources_dir, architecture) patch = Sources.patch_create(sources_dir, *track) return package.base, PkgbuildPatch(None, patch) diff --git a/src/ahriman/core/repository/update_handler.py b/src/ahriman/core/repository/update_handler.py index cfa6b3a2..a7c6a697 100644 --- a/src/ahriman/core/repository/update_handler.py +++ b/src/ahriman/core/repository/update_handler.py @@ -98,7 +98,7 @@ class UpdateHandler(Cleaner): with self.in_package_context(cache_dir.name): try: Sources.fetch(cache_dir, remote=None) - remote = Package.from_build(cache_dir) + remote = Package.from_build(cache_dir, self.architecture) local = packages.get(remote.base) if local is None: diff --git a/src/ahriman/models/package.py b/src/ahriman/models/package.py index 5c43a255..9aa2e042 100644 --- a/src/ahriman/models/package.py +++ b/src/ahriman/models/package.py @@ -201,12 +201,13 @@ class Package(LazyLogging): packages={package.name: PackageDescription.from_aur(package)}) @classmethod - def from_build(cls: Type[Package], path: Path) -> Package: + def from_build(cls: Type[Package], path: Path, architecture: str) -> Package: """ construct package properties from sources directory Args: path(Path): path to package sources directory + architecture(str): load package for specific architecture Returns: Package: package properties @@ -220,13 +221,16 @@ class Package(LazyLogging): raise PackageInfoError(errors) def get_property(key: str, properties: Dict[str, Any], default: Any) -> Any: - return properties.get(key, srcinfo.get(key, default)) + return properties.get(key) or srcinfo.get(key) or default + + def get_list(key: str, properties: Dict[str, Any]) -> Any: + return get_property(key, properties, []) + get_property(f"{key}_{architecture}", properties, []) packages = { package: PackageDescription( - depends=get_property("depends", properties, []), - make_depends=get_property("makedepends", properties, []), - opt_depends=get_property("optdepends", properties, []), + depends=get_list("depends", properties), + make_depends=get_list("makedepends", properties), + opt_depends=get_list("optdepends", properties), ) for package, properties in srcinfo["packages"].items() } diff --git a/tests/ahriman/application/handlers/test_handler_patch.py b/tests/ahriman/application/handlers/test_handler_patch.py index 89b6d07d..58e2ceb0 100644 --- a/tests/ahriman/application/handlers/test_handler_patch.py +++ b/tests/ahriman/application/handlers/test_handler_patch.py @@ -45,7 +45,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository: application_mock = mocker.patch("ahriman.application.handlers.Patch.patch_set_create") Patch.run(args, "x86_64", configuration, report=False, unsafe=False) - patch_mock.assert_called_once_with(args.package, args.track) + patch_mock.assert_called_once_with(args.package, "x86_64", args.track) application_mock.assert_called_once_with(pytest.helpers.anyvar(int), args.package, PkgbuildPatch(None, "patch")) @@ -108,8 +108,8 @@ def test_patch_create_from_diff(package_ahriman: Package, mocker: MockerFixture) package_mock = mocker.patch("ahriman.models.package.Package.from_build", return_value=package_ahriman) sources_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.patch_create", return_value=patch.value) - assert Patch.patch_create_from_diff(path, ["*.diff"]) == (package_ahriman.base, patch) - package_mock.assert_called_once_with(path) + assert Patch.patch_create_from_diff(path, "x86_64", ["*.diff"]) == (package_ahriman.base, patch) + package_mock.assert_called_once_with(path, "x86_64") sources_mock.assert_called_once_with(path, "*.diff") diff --git a/tests/ahriman/core/repository/test_update_handler.py b/tests/ahriman/core/repository/test_update_handler.py index ac364aa4..b1d8690e 100644 --- a/tests/ahriman/core/repository/test_update_handler.py +++ b/tests/ahriman/core/repository/test_update_handler.py @@ -120,7 +120,7 @@ def test_updates_local(update_handler: UpdateHandler, package_ahriman: Package, assert update_handler.updates_local(vcs=True) == [package_ahriman] fetch_mock.assert_called_once_with(Path(package_ahriman.base), remote=None) - package_load_mock.assert_called_once_with(Path(package_ahriman.base)) + package_load_mock.assert_called_once_with(Path(package_ahriman.base), "x86_64") status_client_mock.assert_called_once_with(package_ahriman.base) package_is_outdated_mock.assert_called_once_with( package_ahriman, update_handler.paths, diff --git a/tests/ahriman/core/test_util.py b/tests/ahriman/core/test_util.py index a0f674ad..c10291b7 100644 --- a/tests/ahriman/core/test_util.py +++ b/tests/ahriman/core/test_util.py @@ -358,6 +358,7 @@ def test_walk(resource_path_root: Path) -> None: resource_path_root / "models" / "package_akonadi_aur", resource_path_root / "models" / "package_ahriman_srcinfo", resource_path_root / "models" / "package_gcc10_srcinfo", + resource_path_root / "models" / "package_jellyfin-ffmpeg5-bin_srcinfo", resource_path_root / "models" / "package_tpacpi-bat-git_srcinfo", resource_path_root / "models" / "package_yay_srcinfo", resource_path_root / "web" / "templates" / "build-status" / "alerts.jinja2", diff --git a/tests/ahriman/models/test_package.py b/tests/ahriman/models/test_package.py index b9d0898b..edaf9634 100644 --- a/tests/ahriman/models/test_package.py +++ b/tests/ahriman/models/test_package.py @@ -51,7 +51,7 @@ def test_depends_build_with_version_and_overlap(mocker: MockerFixture, resource_ srcinfo = (resource_path_root / "models" / "package_gcc10_srcinfo").read_text() mocker.patch("ahriman.models.package.Package._check_output", return_value=srcinfo) - package_gcc10 = Package.from_build(Path("local")) + package_gcc10 = Package.from_build(Path("local"), "x86_64") assert package_gcc10.depends_build == {"glibc", "doxygen", "binutils", "git", "libmpc", "python", "zstd"} @@ -154,7 +154,7 @@ def test_from_build(package_ahriman: Package, mocker: MockerFixture, resource_pa srcinfo = (resource_path_root / "models" / "package_ahriman_srcinfo").read_text() mocker.patch("ahriman.models.package.Package._check_output", return_value=srcinfo) - package = Package.from_build(Path("path")) + package = Package.from_build(Path("path"), "x86_64") assert package_ahriman.packages.keys() == package.packages.keys() package_ahriman.packages = package.packages # we are not going to test PackageDescription here package_ahriman.remote = None @@ -168,7 +168,7 @@ def test_from_build_multiple_packages(mocker: MockerFixture, resource_path_root: srcinfo = (resource_path_root / "models" / "package_gcc10_srcinfo").read_text() mocker.patch("ahriman.models.package.Package._check_output", return_value=srcinfo) - package = Package.from_build(Path("path")) + package = Package.from_build(Path("path"), "x86_64") assert package.packages == { "gcc10": PackageDescription( depends=["gcc10-libs=10.3.0-2", "binutils>=2.28", "libmpc", "zstd"], @@ -188,6 +188,34 @@ def test_from_build_multiple_packages(mocker: MockerFixture, resource_path_root: } +def test_from_build_architecture(mocker: MockerFixture, resource_path_root: Path) -> None: + """ + must construct package with architecture specific depends list + """ + srcinfo = (resource_path_root / "models" / "package_jellyfin-ffmpeg5-bin_srcinfo").read_text() + mocker.patch("ahriman.models.package.Package._check_output", return_value=srcinfo) + + package = Package.from_build(Path("path"), "x86_64") + assert package.packages == { + "jellyfin-ffmpeg5-bin": PackageDescription( + depends=["glibc"], + make_depends=[], + opt_depends=[ + "intel-media-driver: for Intel VAAPI support (Broadwell and newer)", + "intel-media-sdk: for Intel Quick Sync Video", + "onevpl-intel-gpu: for Intel Quick Sync Video (12th Gen and newer)", + "intel-compute-runtime: for Intel OpenCL runtime based Tonemapping", + "libva-intel-driver: for Intel legacy VAAPI support (10th Gen and older)", + "libva-mesa-driver: for AMD VAAPI support", + "nvidia-utils: for Nvidia NVDEC/NVENC support", + "opencl-amd: for AMD OpenCL runtime based Tonemapping", + "vulkan-radeon: for AMD RADV Vulkan support", + "vulkan-intel: for Intel ANV Vulkan support", + ], + ), + } + + def test_from_build_failed(package_ahriman: Package, mocker: MockerFixture) -> None: """ must raise exception if there are errors during srcinfo load @@ -196,7 +224,7 @@ def test_from_build_failed(package_ahriman: Package, mocker: MockerFixture) -> N mocker.patch("ahriman.models.package.parse_srcinfo", return_value=({"packages": {}}, ["an error"])) with pytest.raises(PackageInfoError): - Package.from_build(Path("path")) + Package.from_build(Path("path"), "x86_64") def test_from_json_view_1(package_ahriman: Package) -> None: diff --git a/tests/testresources/models/package_jellyfin-ffmpeg5-bin_srcinfo b/tests/testresources/models/package_jellyfin-ffmpeg5-bin_srcinfo new file mode 100644 index 00000000..6e8ec5b0 --- /dev/null +++ b/tests/testresources/models/package_jellyfin-ffmpeg5-bin_srcinfo @@ -0,0 +1,28 @@ +pkgbase = jellyfin-ffmpeg5-bin + pkgdesc = FFmpeg5 binary version for Jellyfin + pkgver = 5.1.2 + pkgrel = 7 + url = https://github.com/jellyfin/jellyfin-ffmpeg + arch = x86_64 + arch = aarch64 + license = GPL3 + optdepends = intel-media-driver: for Intel VAAPI support (Broadwell and newer) + optdepends = intel-media-sdk: for Intel Quick Sync Video + optdepends = onevpl-intel-gpu: for Intel Quick Sync Video (12th Gen and newer) + optdepends = intel-compute-runtime: for Intel OpenCL runtime based Tonemapping + optdepends = libva-intel-driver: for Intel legacy VAAPI support (10th Gen and older) + optdepends = libva-mesa-driver: for AMD VAAPI support + optdepends = nvidia-utils: for Nvidia NVDEC/NVENC support + optdepends = opencl-amd: for AMD OpenCL runtime based Tonemapping + optdepends = vulkan-radeon: for AMD RADV Vulkan support + optdepends = vulkan-intel: for Intel ANV Vulkan support + conflicts = jellyfin-ffmpeg + conflicts = jellyfin-ffmpeg5 + source_x86_64 = https://repo.jellyfin.org/releases/ffmpeg/5.1.2-7/jellyfin-ffmpeg_5.1.2-7_portable_linux64-gpl.tar.xz + depends_x86_64 = glibc>=2.23 + sha256sums_x86_64 = 78420fd1edbaf24a07e92938878d8582d895e009cae02c8e9d5be3f26de905e3 + source_aarch64 = https://repo.jellyfin.org/releases/ffmpeg/5.1.2-7/jellyfin-ffmpeg_5.1.2-7_portable_linuxarm64-gpl.tar.xz + depends_aarch64 = glibc>=2.27 + sha256sums_aarch64 = 8ac4066981f203c2b442754eaf7286b4e481df9692d0ff8910a824d89c831df0 + +pkgname = jellyfin-ffmpeg5-bin \ No newline at end of file