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