diff --git a/flatpak_builder_lint/builddir.py b/flatpak_builder_lint/builddir.py index 5d9831ee..f994bf37 100644 --- a/flatpak_builder_lint/builddir.py +++ b/flatpak_builder_lint/builddir.py @@ -31,6 +31,12 @@ def parse_metadata(builddir: str) -> dict: environment: dict = defaultdict(set) permissions: dict = defaultdict(set) + if ( + key_file.has_group("Application") + and "required-flatpak" in key_file.get_keys("Application")[0] + ): + permissions["required-flatpak"] = key_file.get_value("Application", "required-flatpak") + if key_file.has_group("Context"): for key in key_file.get_keys("Context")[0]: permissions[key] = key_file.get_string_list("Context", key) @@ -60,6 +66,9 @@ def parse_metadata(builddir: str) -> dict: if "devices" in permissions: permissions["device"] = permissions.pop("devices") + if "required-flatpak" in permissions: + permissions["required-flatpak"] = permissions.pop("required-flatpak") + metadata["permissions"] = permissions if key_file.has_group("Environment"): diff --git a/flatpak_builder_lint/checks/finish_args.py b/flatpak_builder_lint/checks/finish_args.py index 44960b9d..1931653e 100644 --- a/flatpak_builder_lint/checks/finish_args.py +++ b/flatpak_builder_lint/checks/finish_args.py @@ -2,12 +2,25 @@ import tempfile from collections import defaultdict +import gi + from .. import builddir, ostree from . import Check +gi.require_version("AppStream", "1.0") +from gi.repository import AppStream # noqa: E402 + class FinishArgsCheck(Check): def _validate(self, appid: str | None, finish_args: dict[str, set[str]]) -> None: + flatpak_version = None + if "required-flatpak" in finish_args: + in_ver = finish_args["required-flatpak"] + if isinstance(in_ver, str): + flatpak_version = in_ver + if isinstance(in_ver, set): + flatpak_version = next(iter(in_ver)) + if "x11" in finish_args["socket"] and "fallback-x11" in finish_args["socket"]: self.errors.add("finish-args-contains-both-x11-and-fallback") @@ -49,6 +62,25 @@ def _validate(self, appid: str | None, finish_args: dict[str, set[str]]) -> None if dev.startswith("!"): dv = dev.removeprefix("!") self.errors.add(f"finish-args-has-nodevice-{dv}") + if dev in ("input", "usb"): + if "required-flatpak" not in finish_args: + self.errors.add("finish-args-no-required-flatpak") + self.info.add( + "finish-args-no-required-flatpak: finish-args has newly introduced" + + " Flatpak metadata but no require-version" + ) + if flatpak_version is not None and not AppStream.vercmp_test_match( + flatpak_version, + AppStream.RelationCompare.GE, + "1.16.0", + AppStream.VercmpFlags.NONE, + ): + self.errors.add("finish-args-device-input-usb-wrong-required-flatpak") + self.info.add( + "finish-args-device-input-usb-wrong-required-flatpak:" + + " finish-args has newly introduced Flatpak devices input or" + + " usb but require-version is not set to 1.16.0" + ) modes = (":ro", ":rw", ":create") xdgdirs = ("xdg-data", "xdg-config", "xdg-cache") @@ -261,6 +293,8 @@ def check_manifest(self, manifest: dict) -> None: split = arg.split("=") key = split[0].removeprefix("--") value = "=".join(split[1:]) + if key == "require-version": + key = "required-flatpak" if key == "nodevice": key = "device" value = "!" + value diff --git a/tests/builddir/finish_args_new_metadata/metadata b/tests/builddir/finish_args_new_metadata/metadata new file mode 100644 index 00000000..cdcca8c1 --- /dev/null +++ b/tests/builddir/finish_args_new_metadata/metadata @@ -0,0 +1,5 @@ +[Application] +name=org.flathub.finish_args_new_metadata + +[Context] +devices=usb; diff --git a/tests/manifests/finish_args-new-metadata.json b/tests/manifests/finish_args-new-metadata.json new file mode 100644 index 00000000..53ef6db0 --- /dev/null +++ b/tests/manifests/finish_args-new-metadata.json @@ -0,0 +1,7 @@ +{ + "app-id": "org.flathub.finish_args_new_metadata", + "finish-args": [ + "--device=input", + "--require-version=1.11.0" + ] +} diff --git a/tests/test_builddir.py b/tests/test_builddir.py index cedd1faf..cb07f854 100644 --- a/tests/test_builddir.py +++ b/tests/test_builddir.py @@ -56,6 +56,12 @@ def test_builddir_finish_args() -> None: assert not err.startswith(("finish-args-arbitrary-xdg-", "finish-args-unnecessary-xdg-")) +def test_builddir_finish_args_new_metadata() -> None: + ret = run_checks("tests/builddir/finish_args_new_metadata") + found_errors = set(ret["errors"]) + assert "finish-args-no-required-flatpak" in found_errors + + def test_builddir_display_supported() -> None: absents = { "finish-args-fallback-x11-without-wayland", diff --git a/tests/test_manifest.py b/tests/test_manifest.py index 33c7dac5..d09c0c5a 100644 --- a/tests/test_manifest.py +++ b/tests/test_manifest.py @@ -158,6 +158,8 @@ def test_manifest_finish_args() -> None: "finish-args-absolute-run-media-path", "finish-args-has-nodevice-shm", "finish-args-has-nosocket-fallback-x11", + "finish-args-no-required-flatpak", + "finish-args-device-input-usb-wrong-required-flatpak", } ret = run_checks("tests/manifests/finish_args.json") @@ -170,6 +172,12 @@ def test_manifest_finish_args() -> None: assert not err.startswith(("finish-args-arbitrary-xdg-", "finish-args-unnecessary-xdg-")) +def test_manifest_finish_args_new_metadata() -> None: + ret = run_checks("tests/manifests/finish_args-new-metadata.json") + found_errors = set(ret["errors"]) + assert "finish-args-device-input-usb-wrong-required-flatpak" in found_errors + + def test_manifest_finish_args_issue_wayland_x11() -> None: ret = run_checks("tests/manifests/finish_args-wayland-x11.json") found_errors = set(ret["errors"])