From 365703e8a63012e36da96c51827bd3c93e355710 Mon Sep 17 00:00:00 2001 From: Jarred Wilson Date: Thu, 20 Jul 2023 13:32:32 -0400 Subject: [PATCH] Add QT extension --- extensions/desktop/qt-framework/Makefile | 34 +++ .../desktop/qt-framework/desktop-exports | 1 + extensions/desktop/qt-framework/fonts | 1 + extensions/desktop/qt-framework/init | 1 + .../desktop/qt-framework/launcher-specific | 63 +++++ extensions/desktop/qt-framework/locale-gen | 62 +++++ extensions/desktop/qt-framework/mark-and-exec | 1 + schema/snapcraft.json | 1 + snapcraft/extensions/qt_framework.py | 212 ++++++++++++++ snapcraft/extensions/registry.py | 2 + tests/unit/extensions/test_qt_framework.py | 259 ++++++++++++++++++ tests/unit/extensions/test_registry.py | 1 + 12 files changed, 638 insertions(+) create mode 100644 extensions/desktop/qt-framework/Makefile create mode 120000 extensions/desktop/qt-framework/desktop-exports create mode 120000 extensions/desktop/qt-framework/fonts create mode 120000 extensions/desktop/qt-framework/init create mode 100644 extensions/desktop/qt-framework/launcher-specific create mode 100755 extensions/desktop/qt-framework/locale-gen create mode 120000 extensions/desktop/qt-framework/mark-and-exec create mode 100644 snapcraft/extensions/qt_framework.py create mode 100644 tests/unit/extensions/test_qt_framework.py diff --git a/extensions/desktop/qt-framework/Makefile b/extensions/desktop/qt-framework/Makefile new file mode 100644 index 00000000000..cc8bd3331c1 --- /dev/null +++ b/extensions/desktop/qt-framework/Makefile @@ -0,0 +1,34 @@ +#!/usr/bin/make -f + +SRC_DIR ?= . + +DATA_DIR := $(DESTDIR)/data-dir +BIN_DIR := $(DESTDIR)/snap/command-chain +LIB_DIR := $(DESTDIR)/lib +DEST_LAUNCHER := desktop-launch +LOCALE_GENERATOR := locale-gen +DEST_CONFIGURE_HOOK := hooks-configure-desktop + +build: $(DEST_LAUNCHER) $(DEST_CONFIGURE_HOOK) + +clean: + rm -f $(DEST_LAUNCHER) + rm -f $(DEST_CONFIGURE_HOOK) + rm -f $(BINDTEXTDOMAIN) + +$(DEST_LAUNCHER): + @cat $(SRC_DIR)/init > $(DEST_LAUNCHER) + # tail -n +2 to remove the shebang + @tail -n +2 $(SRC_DIR)/desktop-exports | sed -e "s/%PLATFORM_PLUG%/$${PLATFORM_PLUG:?}/" >> $(DEST_LAUNCHER) + @tail -n +2 $(SRC_DIR)/launcher-specific >> $(DEST_LAUNCHER) + @tail -n +2 $(SRC_DIR)/mark-and-exec >> $(DEST_LAUNCHER) + +$(DEST_CONFIGURE_HOOK): + @cat $(SRC_DIR)/fonts > $(DEST_CONFIGURE_HOOK) + +install: $(DEST_LAUNCHER) $(DEST_CONFIGURE_HOOK) + install -d $(DATA_DIR) + install -d $(DATA_DIR)/kf5 + install -D -m755 $(DEST_LAUNCHER) "$(BIN_DIR)"/$(DEST_LAUNCHER) + install -D -m755 $(LOCALE_GENERATOR) "$(BIN_DIR)"/$(LOCALE_GENERATOR) + install -D -m755 $(DEST_CONFIGURE_HOOK) "$(BIN_DIR)"/$(DEST_CONFIGURE_HOOK) diff --git a/extensions/desktop/qt-framework/desktop-exports b/extensions/desktop/qt-framework/desktop-exports new file mode 120000 index 00000000000..8013267817d --- /dev/null +++ b/extensions/desktop/qt-framework/desktop-exports @@ -0,0 +1 @@ +../common/desktop-exports \ No newline at end of file diff --git a/extensions/desktop/qt-framework/fonts b/extensions/desktop/qt-framework/fonts new file mode 120000 index 00000000000..3ef54f4a979 --- /dev/null +++ b/extensions/desktop/qt-framework/fonts @@ -0,0 +1 @@ +../common/fonts \ No newline at end of file diff --git a/extensions/desktop/qt-framework/init b/extensions/desktop/qt-framework/init new file mode 120000 index 00000000000..350b7be8e18 --- /dev/null +++ b/extensions/desktop/qt-framework/init @@ -0,0 +1 @@ +../common/init \ No newline at end of file diff --git a/extensions/desktop/qt-framework/launcher-specific b/extensions/desktop/qt-framework/launcher-specific new file mode 100644 index 00000000000..322fbaca405 --- /dev/null +++ b/extensions/desktop/qt-framework/launcher-specific @@ -0,0 +1,63 @@ +#!/bin/bash +################################### +# QT launcher specific part # +################################### + +# Add paths for games +append_dir PATH "$SNAP/usr/games" +append_dir PATH "$SNAP_DESKTOP_RUNTIME/usr/games" + +# Qt Libs +prepend_dir LD_LIBRARY_PATH "$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH/qt6-5/libs" + +# Add QT_PLUGIN_PATH (Qt Modules). +append_dir QT_PLUGIN_PATH "$SNAP/usr/lib/$ARCH/qt6-5`/plugins" +append_dir QT_PLUGIN_PATH "$SNAP/usr/lib/$ARCH" +append_dir QT_PLUGIN_PATH "$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH/qt6-5/plugins" +append_dir QT_PLUGIN_PATH "$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH/" +# And QML2_IMPORT_PATH (Qt Modules). +append_dir QML2_IMPORT_PATH "$SNAP/usr/lib/$ARCH/qt6-5/qml" +append_dir QML2_IMPORT_PATH "$SNAP/lib/$ARCH" +append_dir QML2_IMPORT_PATH "$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH/qt6-5/qml" +append_dir QML2_IMPORT_PATH "$SNAP_DESKTOP_RUNTIME/lib/$ARCH" + +# Fix locating the QtWebEngineProcess executable +export QTWEBENGINEPROCESS_PATH="$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH/qt6-5/libexec/QtWebEngineProcess" + +# Removes Qt warning: Could not find a location +# of the system Compose files +export QTCOMPOSE="$SNAP_DESKTOP_RUNTIME/usr/share/X11/locale" +export QT_XKB_CONFIG_ROOT="/usr/share/X11/xkb" + +# Add path to VLC plugins +export VLC_PLUGIN_PATH="$SNAP_DESKTOP_RUNTIME/usr/lib/x86_64-linux-gnu/vlc/plugins" + +# Ensure QtChooser behaves. +export QTCHOOSER_NO_GLOBAL_DIR=1 +export QT_SELECT=5 +# qtchooser hardcodes reference paths, we'll need to rewrite them properly +ensure_dir_exists "$XDG_CONFIG_HOME/qtchooser" +echo "$SNAP/usr/lib/qt6-5/bin" > "$XDG_CONFIG_HOME/qtchooser/6.conf" +echo "$SNAP/usr/lib/$ARCH" >> "$XDG_CONFIG_HOME/qtchooser/6.conf" +echo "$SNAP/usr/lib/qt6-5/bin" > "$XDG_CONFIG_HOME/qtchooser/default.conf" +echo "$SNAP/usr/lib/$ARCH" >> "$XDG_CONFIG_HOME/qtchooser/default.conf" + +# This relies on qtbase patch +# 0001-let-qlibraryinfo-fall-back-to-locate-qt.conf-via-XDG.patch +# to make QLibraryInfo look in XDG_* locations for qt.conf. The paths configured +# here are applied to everything that uses QLibraryInfo as final fallback and +# has no XDG_* fallback before that. Currently the most interesting offender +# is QtWebEngine which will not work unless the Data path is correctly set. +cat << EOF > "$XDG_CONFIG_HOME/qt.conf" +[Paths] +Data = $SNAP_DESKTOP_RUNTIME/usr/share/qt6-5/ +Translations = $SNAP_DESKTOP_RUNTIME/usr/share/qt6-5/translations +EOF + +if [ -e "$SNAP_DESKTOP_RUNTIME/usr/share/i18n" ]; then + export I18NPATH="$SNAP_DESKTOP_RUNTIME/usr/share/i18n" + locpath="$XDG_DATA_HOME/locale" + ensure_dir_exists "$locpath" + export LOCPATH="$locpath:/usr/lib/locale" + LC_ALL=C.UTF-8 async_exec "$SNAP/snap/command-chain/locale-gen" +fi diff --git a/extensions/desktop/qt-framework/locale-gen b/extensions/desktop/qt-framework/locale-gen new file mode 100755 index 00000000000..2c8b6050f05 --- /dev/null +++ b/extensions/desktop/qt-framework/locale-gen @@ -0,0 +1,62 @@ +#!/usr/bin/perl + +use strict; + +sub uniq +{ + my %seen; + grep !$seen{$_}++, @_; +} + +# TODO support for KDE's in-app language switch feature. +sub get_languages +{ + # Initialize with sane defaults. + my @found_languages = ($ENV{'LANG'} or 'C.UTF-8'); + + # Go through LC_. + foreach (sort keys %ENV) + { + if (substr($_, 0, length("LC_")) eq "LC_") + { + push(@found_languages, $ENV{$_}); + } + } + # And finally LANGUAGE, but normalize it. + if (my $language = $ENV{'LANGUAGE'}) + { + foreach (split(':', $language)) + { + push(@found_languages, "$_.UTF-8"); + } + } + + # Remove duplicates before returning. + @found_languages = uniq(@found_languages); + + return @found_languages +} + +my $env_locpath = $ENV{'LOCPATH'} or die "LOCPATH must be set"; +my @locpaths = split(/:/, $env_locpath); + +foreach my $lang (get_languages()) +{ + my $found = 0; + foreach my $locpath (@locpaths) + { + my $loc_target = "$locpath/$lang"; + if (-e $loc_target) + { + $found = 1; + last; + } + } + next if $found; + my $target = "@locpaths[0]/$lang"; + + # localedef will exit !0 for unknown reasons, even when everything was + # generated fine. + my ($locale, $encoding) = split(/\./, $lang); + system('localedef', '-i', $locale, '-f', $encoding, $target); +} diff --git a/extensions/desktop/qt-framework/mark-and-exec b/extensions/desktop/qt-framework/mark-and-exec new file mode 120000 index 00000000000..1bf86267638 --- /dev/null +++ b/extensions/desktop/qt-framework/mark-and-exec @@ -0,0 +1 @@ +../common/mark-and-exec \ No newline at end of file diff --git a/schema/snapcraft.json b/schema/snapcraft.json index c9c61369e47..03e47939541 100644 --- a/schema/snapcraft.json +++ b/schema/snapcraft.json @@ -914,6 +914,7 @@ "gnome-3-34", "gnome-3-38", "kde-neon", + "qt-framework", "ros1-noetic", "ros2-foxy" ] diff --git a/snapcraft/extensions/qt_framework.py b/snapcraft/extensions/qt_framework.py new file mode 100644 index 00000000000..ed167b0b811 --- /dev/null +++ b/snapcraft/extensions/qt_framework.py @@ -0,0 +1,212 @@ +# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*- +# +# Copyright 2022 Canonical Ltd. +# 2023 Jarred Wilson +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +"""Generic QT Framework extension to support core22 and onwards.""" +import dataclasses +import functools +from typing import Any, Dict, List, Optional, Tuple + +from overrides import overrides + +from .extension import Extension, get_extensions_data_dir, prepend_to_env + +_SDK_SNAP = {"core22": "qt-framework-sdk"} + + +@dataclasses.dataclass +class ExtensionInfo: + """Content/SDK build information.""" + + cmake_args: str + + +@dataclasses.dataclass +class QTSnaps: + """A structure of QT related snaps.""" + + sdk: str + content: str + builtin: bool = True + + +class QTFramework(Extension): + r"""The QT Framework extension. + + This extension makes it easy to assemble QT based applications. + + It configures each application with the following plugs: + + \b + - Common Icon Themes. + - Common Sound Themes. + - The QT Frameworks runtime libraries and utilities. + + For easier desktop integration, it also configures each application + entry with these additional plugs: + + \b + - desktop (https://snapcraft.io/docs/desktop-interface) + - desktop-legacy (https://snapcraft.io/docs/desktop-legacy-interface) + - opengl (https://snapcraft.io/docs/opengl-interface) + - wayland (https://snapcraft.io/docs/wayland-interface) + - x11 (https://snapcraft.io/docs/x11-interface) + """ + + @staticmethod + @overrides + def get_supported_bases() -> Tuple[str, ...]: + return ("core22",) + + @staticmethod + @overrides + def get_supported_confinement() -> Tuple[str, ...]: + return "strict", "devmode" + + @staticmethod + @overrides + def is_experimental(base: Optional[str]) -> bool: + return False + + @overrides + def get_app_snippet(self) -> Dict[str, Any]: + return { + "command-chain": ["snap/command-chain/desktop-launch"], + "plugs": ["desktop", "desktop-legacy", "opengl", "wayland", "x11"], + } + + @functools.cached_property + def qt_snaps(self) -> QTSnaps: + """Return the QT related snaps to use to construct the environment.""" + base = self.yaml_data["base"] + sdk_snap = _SDK_SNAP[base] + + build_snaps: List[str] = [] + for part in self.yaml_data["parts"].values(): + build_snaps.extend(part.get("build-snaps", [])) + + builtin = True + + for snap in build_snaps: + if sdk_snap == snap.split('/')[0]: + builtin = False + break + + # The same except the trailing -sd + content = sdk_snap[:-4] + + return QTSnaps(sdk=sdk_snap, content=content, builtin=builtin) + + @functools.cached_property + def ext_info(self) -> ExtensionInfo: + """Return the extension info cmake_args, provider, content, build_snaps.""" + cmake_args = "-DCMAKE_FIND_ROOT_PATH=/snap/" + self.qt_snaps.sdk + "/current" + + return ExtensionInfo(cmake_args=cmake_args) + + @overrides + def get_root_snippet(self) -> Dict[str, Any]: + platform_snap = self.qt_snaps.content + content_snap = self.qt_snaps.content + "-all" + + return { + "assumes": ["snapd2.43"], # for 'snapctl is-connected' + "compression": "lzo", + "plugs": { + "desktop": {"mount-host-font-cache": False}, + "icon-themes": { + "interface": "content", + "target": "$SNAP/data-dir/icons", + "default-provider": "gtk-common-themes", + }, + "sound-themes": { + "interface": "content", + "target": "$SNAP/data-dir/sounds", + "default-provider": "gtk-common-themes", + }, + platform_snap: { + "content": content_snap, + "interface": "content", + "default-provider": platform_snap, + "target": "$SNAP/qt-framework", + }, + }, + "environment": {"SNAP_DESKTOP_RUNTIME": "$SNAP/qt-framework"}, + "hooks": { + "configure": { + "plugs": ["desktop"], + "command-chain": ["snap/command-chain/hooks-configure-desktop"], + } + }, + "layout": {"/usr/share/X11": {"symlink": "$SNAP/qt-framework/usr/share/X11"}}, + } + + @overrides + def get_part_snippet(self) -> Dict[str, Any]: + sdk_snap = self.qt_snaps.sdk + cmake_args = self.ext_info.cmake_args + + return { + "build-environment": [ + { + "PATH": prepend_to_env( + "PATH", [f"/snap/{sdk_snap}/current/usr/bin"] + ), + }, + { + "XDG_DATA_DIRS": prepend_to_env( + "XDG_DATA_DIRS", + [ + f"$CRAFT_STAGE/usr/share:/snap/{sdk_snap}/current/usr/share", + "/usr/share", + ], + ), + }, + { + "SNAPCRAFT_CMAKE_ARGS": prepend_to_env( + "SNAPCRAFT_CMAKE_ARGS", + [ + cmake_args, + ], + ), + }, + ], + } + + @overrides + def get_parts_snippet(self) -> Dict[str, Any]: + # We can change this to the lightweight command-chain when + # the content snap includes the desktop-launch from + # https://github.com/snapcore/snapcraft-desktop-integration + source = get_extensions_data_dir() / "desktop" / "qt-framework" + + if self.qt_snaps.builtin: + return { + "qt-framework/sdk": { + "source": str(source), + "plugin": "make", + "make-parameters": [f"PLATFORM_PLUG={self.qt_snaps.content}"], + "build-snaps": [self.qt_snaps.sdk], + }, + } + + return { + "qt-framework/sdk": { + "source": str(source), + "plugin": "make", + "make-parameters": [f"PLATFORM_PLUG={self.qt_snaps.content}"], + }, + } diff --git a/snapcraft/extensions/registry.py b/snapcraft/extensions/registry.py index 77ddb6ebe4d..854eeac68b0 100644 --- a/snapcraft/extensions/registry.py +++ b/snapcraft/extensions/registry.py @@ -22,6 +22,7 @@ from .gnome import GNOME from .kde_neon import KDENeon +from .qt_framework import QTFramework from .ros2_humble import ROS2HumbleExtension if TYPE_CHECKING: @@ -33,6 +34,7 @@ "gnome": GNOME, "ros2-humble": ROS2HumbleExtension, "kde-neon": KDENeon, + "qt-framework": QTFramework, } diff --git a/tests/unit/extensions/test_qt_framework.py b/tests/unit/extensions/test_qt_framework.py new file mode 100644 index 00000000000..cc33053b1bc --- /dev/null +++ b/tests/unit/extensions/test_qt_framework.py @@ -0,0 +1,259 @@ +# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*- +# +# Copyright 2023 Canonical Ltd. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import pytest + +from snapcraft.extensions import qt_framework +from snapcraft.extensions.extension import get_extensions_data_dir + +############ +# Fixtures # +############ + + +@pytest.fixture +def qt_framework_extension(): + return qt_framework.QTFramework( + yaml_data={"base": "core22", "parts": {}}, arch="amd64", target_arch="amd64" + ) + + +@pytest.fixture +def qt_framework_extension_with_build_snap(): + return qt_framework.QTFramework( + yaml_data={ + "base": "core22", + "parts": { + "part1": { + "build-snaps": ["qt-framework-sdk/latest/stable"] + } + }, + }, + arch="amd64", + target_arch="amd64", + ) + + +@pytest.fixture +def qt_framework_extension_with_default_build_snap_from_latest_edge(): + return qt_framework.QTFramework( + yaml_data={ + "base": "core22", + "parts": { + "part1": {"build-snaps": ["qt-framework-sdk/latest/edge"]} + }, + }, + arch="amd64", + target_arch="amd64", + ) + + +################### +# QTFramework Extension # +################### + + +def test_get_supported_bases(qt_framework_extension): + assert qt_framework_extension.get_supported_bases() == ("core22",) + + +def test_get_supported_confinement(qt_framework_extension): + assert qt_framework_extension.get_supported_confinement() == ("strict", "devmode") + + +def test_is_experimental(): + assert qt_framework.QTFramework.is_experimental(base="core22") is False + + +def test_get_app_snippet(qt_framework_extension): + assert qt_framework_extension.get_app_snippet() == { + "command-chain": ["snap/command-chain/desktop-launch"], + "plugs": ["desktop", "desktop-legacy", "opengl", "wayland", "x11"], + } + + +def test_get_root_snippet(qt_framework_extension): + assert qt_framework_extension.get_root_snippet() == { + "assumes": ["snapd2.43"], + "compression": "lzo", + "environment": {"SNAP_DESKTOP_RUNTIME": "$SNAP/kf5"}, + "hooks": { + "configure": { + "plugs": ["desktop"], + "command-chain": ["snap/command-chain/hooks-configure-desktop"], + } + }, + "layout": {"/usr/share/X11": {"symlink": "$SNAP/kf5/usr/share/X11"}}, + "plugs": { + "desktop": {"mount-host-font-cache": False}, + "icon-themes": { + "interface": "content", + "target": "$SNAP/data-dir/icons", + "default-provider": "gtk-common-themes", + }, + "sound-themes": { + "interface": "content", + "target": "$SNAP/data-dir/sounds", + "default-provider": "gtk-common-themes", + }, + "qt-framework": { + "content": "qt-framework-all", + "interface": "content", + "default-provider": "qt-framework", + "target": "$SNAP/kf5", + }, + }, + } + + +def test_get_root_snippet_with_external_sdk(qt_framework_extension_with_build_snap): + assert qt_framework_extension_with_build_snap.get_root_snippet() == { + "assumes": ["snapd2.43"], + "compression": "lzo", + "environment": {"SNAP_DESKTOP_RUNTIME": "$SNAP/kf5"}, + "hooks": { + "configure": { + "plugs": ["desktop"], + "command-chain": ["snap/command-chain/hooks-configure-desktop"], + } + }, + "layout": {"/usr/share/X11": {"symlink": "$SNAP/kf5/usr/share/X11"}}, + "plugs": { + "desktop": {"mount-host-font-cache": False}, + "icon-themes": { + "interface": "content", + "target": "$SNAP/data-dir/icons", + "default-provider": "gtk-common-themes", + }, + "sound-themes": { + "interface": "content", + "target": "$SNAP/data-dir/sounds", + "default-provider": "gtk-common-themes", + }, + "qt-framework": { + "content": "qt-framework-all", + "interface": "content", + "default-provider": "qt-framework", + "target": "$SNAP/kf5", + }, + }, + } + + +class TestGetPartSnippet: + """Tests for QTFramework.get_part_snippet when using the default sdk snap name.""" + + def test_get_part_snippet(self, qt_framework_extension): + self.assert_get_part_snippet(qt_framework_extension) + + def test_get_part_snippet_latest_edge( + self, qt_framework_extension_with_default_build_snap_from_latest_edge + ): + self.assert_get_part_snippet( + qt_framework_extension_with_default_build_snap_from_latest_edge + ) + + @staticmethod + def assert_get_part_snippet(qt_framework_instance): + assert qt_framework_instance.get_part_snippet() == { + "build-environment": [ + { + "PATH": ( + "/snap/qt-framework-sdk/current/usr/bin${PATH:+:$PATH}" + ) + }, + { + "XDG_DATA_DIRS": ( + "$CRAFT_STAGE/usr/share:/snap/qt-framework-sdk" + "/current/usr/share:/usr/share${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}" + ) + }, + { + "SNAPCRAFT_CMAKE_ARGS": ( + "-DCMAKE_FIND_ROOT_PATH=" + "/snap/qt-framework-sdk/current" + "${SNAPCRAFT_CMAKE_ARGS:+:$SNAPCRAFT_CMAKE_ARGS}" + ) + }, + ] + } + + +def test_get_part_snippet_with_external_sdk(qt_framework_extension_with_build_snap): + assert qt_framework_extension_with_build_snap.get_part_snippet() == { + "build-environment": [ + { + "PATH": ( + "/snap/qt-framework-sdk/current/" + "usr/bin${PATH:+:$PATH}" + ) + }, + { + "XDG_DATA_DIRS": ( + "$CRAFT_STAGE/usr/share:/snap/qt-framework-sdk" + "/current/usr/share:/usr/share${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}" + ) + }, + { + "SNAPCRAFT_CMAKE_ARGS": ( + "-DCMAKE_FIND_ROOT_PATH=" + "/snap/qt-framework-sdk/current" + "${SNAPCRAFT_CMAKE_ARGS:+:$SNAPCRAFT_CMAKE_ARGS}" + ) + }, + ] + } + + +def test_get_parts_snippet(qt_framework_extension): + source = get_extensions_data_dir() / "desktop" / "qt-framework" + + assert qt_framework_extension.get_parts_snippet() == { + "qt-framework/sdk": { + "source": str(source), + "plugin": "make", + "make-parameters": ["PLATFORM_PLUG=qt-framework"], + "build-snaps": ["qt-framework-sdk"], + } + } + + +def test_get_parts_snippet_with_external_sdk(qt_framework_extension_with_build_snap): + source = get_extensions_data_dir() / "desktop" / "qt-framework" + + assert qt_framework_extension_with_build_snap.get_parts_snippet() == { + "qt-framework/sdk": { + "source": str(source), + "plugin": "make", + "make-parameters": ["PLATFORM_PLUG=qt-framework"], + } + } + + +def test_get_parts_snippet_with_external_sdk_different_channel( + qt_framework_extension_with_default_build_snap_from_latest_edge, +): + source = get_extensions_data_dir() / "desktop" / "qt-framework" + assert ( + qt_framework_extension_with_default_build_snap_from_latest_edge.get_parts_snippet() + == { + "qt-framework/sdk": { + "source": str(source), + "plugin": "make", + "make-parameters": ["PLATFORM_PLUG=qt-framework"], + } + } + ) diff --git a/tests/unit/extensions/test_registry.py b/tests/unit/extensions/test_registry.py index 118e8151715..666d62a9ef6 100644 --- a/tests/unit/extensions/test_registry.py +++ b/tests/unit/extensions/test_registry.py @@ -27,6 +27,7 @@ def test_get_extension_names(): "gnome", "ros2-humble", "kde-neon", + "qt-framework", "fake-extension-experimental", "fake-extension-extra", "fake-extension",