diff --git a/extensions/desktop/command-chain-kde/Makefile b/extensions/desktop/command-chain-kde/Makefile index e72336be49..b49007db6b 100644 --- a/extensions/desktop/command-chain-kde/Makefile +++ b/extensions/desktop/command-chain-kde/Makefile @@ -10,3 +10,4 @@ scripts = hooks-configure-desktop hooks-configure-fonts desktop-launch run install: $(scripts) .PHONY: $(scripts) +.NOTPARALLEL: diff --git a/extensions/desktop/command-chain/Makefile b/extensions/desktop/command-chain/Makefile index c8062f6da3..7aac1eb5ec 100644 --- a/extensions/desktop/command-chain/Makefile +++ b/extensions/desktop/command-chain/Makefile @@ -10,3 +10,4 @@ scripts = hooks-configure-fonts desktop-launch run install: $(scripts) .PHONY: $(scripts) +.NOTPARALLEL: diff --git a/snapcraft/extensions/gnome.py b/snapcraft/extensions/gnome.py index 49aa6ea547..82c71e7807 100644 --- a/snapcraft/extensions/gnome.py +++ b/snapcraft/extensions/gnome.py @@ -26,7 +26,11 @@ from .extension import get_extensions_data_dir, prepend_to_env from .gpu_extension import GPUExtension -_SDK_SNAP = {"core22": "gnome-42-2204-sdk", "core24": "gnome-46-2404-sdk"} +_SDK_SNAP = { + "core22": "gnome-42-2204-sdk", + "core24": "gnome-46-2404-sdk", + "core26": "gnome-core26-sdk", +} _PLATFORM_TRANSLATION = {"core22": "2204", "core24": "2404"} @@ -74,7 +78,7 @@ class GNOME(GPUExtension): @staticmethod @override def get_supported_bases() -> tuple[str, ...]: - return ("core22", "core24") + return ("core22", "core24", "core26") @staticmethod @override @@ -88,7 +92,10 @@ def is_experimental(base: str | None) -> bool: @override def get_app_snippet(self, *, app_name: str) -> dict[str, Any]: - if self.yaml_data["base"] == "core24": + base_str = self.yaml_data["base"] + base = int(base_str.removeprefix("core")) + + if base >= 24: snippet = super().get_app_snippet(app_name=app_name) else: snippet = {} @@ -119,7 +126,9 @@ def gnome_snaps(self) -> GNOMESnaps: # use the sdk snap if it is defined in any part's build-snaps # otherwise, assume it is built into the content snap - matcher = re.compile(r"gnome-\d+-" + _PLATFORM_TRANSLATION[base] + r"-sdk.*") + matcher = re.compile( + r"gnome-(?:\d+-)?" + _PLATFORM_TRANSLATION.get(base, base) + r"-sdk.*" + ) sdk_snap_candidates = [s for s in build_snaps if matcher.match(s)] if sdk_snap_candidates: sdk_snap = sdk_snap_candidates[0].split("/")[0] @@ -134,10 +143,11 @@ def gnome_snaps(self) -> GNOMESnaps: @override def get_root_snippet(self) -> dict[str, Any]: platform_snap = self.gnome_snaps.content - base = self.yaml_data["base"] + base_str = self.yaml_data["base"] + base = int(base_str.removeprefix("core")) snippet: dict[str, Any] - if base == "core24": + if base >= 24: snippet = super().get_root_snippet() else: snippet = { @@ -207,6 +217,14 @@ def get_root_snippet(self) -> dict[str, Any]: "bind": "$SNAP/gnome-platform/usr/share/xml/iso-codes" }, } + + if base >= 26: + snippet["layout"] = { + **snippet.get("layout", {}), + "/usr/libexec/glycin-loaders": { + "bind": "$SNAP/gnome-platform/usr/libexec/glycin-loaders" + }, + } return snippet @override @@ -327,8 +345,10 @@ def get_parts_snippet(self) -> dict[str, Any]: """ source = get_extensions_data_dir() / "desktop" / "command-chain" - base = self.yaml_data["base"] - if base != "core22": + base_str = self.yaml_data["base"] + base = int(base_str.removeprefix("core")) + + if base >= 24: parts = {f"gnome/{k}": v for k, v in super().get_parts_snippet().items()} else: parts = {} @@ -336,7 +356,29 @@ def get_parts_snippet(self) -> dict[str, Any]: parts["gnome/sdk"] = { "source": str(source), "plugin": "make", - **({"build-snaps": [_SDK_SNAP[base]]} if self.gnome_snaps.builtin else {}), + **( + {"build-snaps": [_SDK_SNAP[base_str]]} + if self.gnome_snaps.builtin + else {} + ), } + if base >= 26: + cleanup_srcs = [ + self.gnome_snaps.sdk, + "gtk-common-themes", + ] + escaped_srcs = [f'"{w}"' for w in cleanup_srcs] + parts["gnome/cleanup"] = { + "after": list(self.yaml_data.get("parts", {}).keys()), + "plugin": "nil", + "build-snaps": cleanup_srcs, + "override-prime": ( + "set -eux\n" + f"for snap in {' '.join(escaped_srcs)}; do\n" + ' cd "/snap/$snap/current" && find . -type f,l -name "*.so.*" -exec rm -f "$CRAFT_PRIME/{}" \\;\n' + "done\n" + ), + } + return parts diff --git a/tests/unit/commands/test_list_extensions.py b/tests/unit/commands/test_list_extensions.py index e29706f3a8..05a0195a90 100644 --- a/tests/unit/commands/test_list_extensions.py +++ b/tests/unit/commands/test_list_extensions.py @@ -41,7 +41,7 @@ def test_command(emitter, fake_app_config): dotnet9 core24 env-injector core24 fake-extension core22, core24, core26 - gnome core22, core24 + gnome core22, core24, core26 gpu core22, core24, core26 kde-neon core22, core24 kde-neon-6 core22, core24 diff --git a/tests/unit/extensions/test_gnome.py b/tests/unit/extensions/test_gnome.py index 56be47fc70..1c8256c4dc 100644 --- a/tests/unit/extensions/test_gnome.py +++ b/tests/unit/extensions/test_gnome.py @@ -38,6 +38,13 @@ def gnome_extension_core24(): ) +@pytest.fixture +def gnome_extension_core26(): + return gnome.GNOME( + yaml_data={"base": "core26", "parts": {}}, arch="amd64", target_arch="amd64" + ) + + @pytest.fixture def gnome_extension_with_build_snap(): return gnome.GNOME( @@ -68,14 +75,14 @@ def gnome_extension_with_default_build_snap_from_latest_edge(): def test_get_supported_bases(): - assert gnome.GNOME.get_supported_bases() == ("core22", "core24") + assert gnome.GNOME.get_supported_bases() == ("core22", "core24", "core26") def test_get_supported_confinement(): assert gnome.GNOME.get_supported_confinement() == ("strict", "devmode") -@pytest.mark.parametrize("base", ["core22", "core24"]) +@pytest.mark.parametrize("base", ["core22", "core24", "core26"]) def test_is_experimental(base): assert gnome.GNOME.is_experimental(base=base) is False @@ -97,6 +104,16 @@ def test_get_app_snippet_core24(gnome_extension_core24): } +def test_get_app_snippet_core26(gnome_extension_core26): + assert gnome_extension_core26.get_app_snippet(app_name="test-app") == { + "command-chain": [ + "snap/command-chain/gpu-2604-wrapper", + "snap/command-chain/desktop-launch", + ], + "plugs": ["desktop", "desktop-legacy", "gsettings", "opengl", "wayland", "x11"], + } + + def test_get_root_snippet(gnome_extension): assert gnome_extension.get_root_snippet() == { "assumes": ["snapd2.43"], @@ -173,6 +190,14 @@ def test_get_root_snippet_with_gpu(gnome_extension_core24): } +def test_get_root_snippet_with_glycin(gnome_extension_core26): + snippet = gnome_extension_core26.get_root_snippet() + + assert snippet["layout"]["/usr/libexec/glycin-loaders"] == { + "bind": "$SNAP/gnome-platform/usr/libexec/glycin-loaders", + } + + def test_get_root_snippet_with_external_sdk(gnome_extension_with_build_snap): assert gnome_extension_with_build_snap.get_root_snippet() == { "assumes": ["snapd2.43"], @@ -451,6 +476,40 @@ def test_get_parts_snippet_core24(gnome_extension_core24): } +def test_get_parts_snippet_core26(gnome_extension_core26): + assert gnome_extension_core26.get_parts_snippet() == { + "gnome/gpu/wrapper": { + "source": str(get_extensions_data_dir() / "gpu" / "command-chain"), + "plugin": "make", + "make-parameters": ["GPU_INTERFACE=gpu-2604"], + }, + "gnome/gpu/cleanup": { + "after": [], + "source": "https://github.com/canonical/gpu-snap.git", + "plugin": "nil", + "override-prime": ( + "craftctl default\n${CRAFT_PART_SRC}/bin/gpu-2604-cleanup mesa-2604\n" + ), + }, + "gnome/sdk": { + "source": str(get_extensions_data_dir() / "desktop" / "command-chain"), + "plugin": "make", + "build-snaps": ["gnome-core26-sdk"], + }, + "gnome/cleanup": { + "after": [], + "plugin": "nil", + "build-snaps": ["gnome-core26-sdk", "gtk-common-themes"], + "override-prime": ( + "set -eux\n" + 'for snap in "gnome-core26-sdk" "gtk-common-themes"; do\n' + ' cd "/snap/$snap/current" && find . -type f,l -name "*.so.*" -exec rm -f "$CRAFT_PRIME/{}" \\;\n' + "done\n" + ), + }, + } + + def test_get_parts_snippet_with_external_sdk(gnome_extension_with_build_snap): assert gnome_extension_with_build_snap.get_parts_snippet() == { "gnome/sdk": {