From 99f4e855dbcf43d4b249ddfa51273c7e7cf98292 Mon Sep 17 00:00:00 2001 From: Soumyadeep Ghosh Date: Fri, 22 Nov 2024 22:28:05 +0530 Subject: [PATCH] desktop: stop renaming desktop file With snapd 2.66, it supports custom desktop file names. This patch allows it to happen from snapcraft side. --- snapcraft/parts/desktop_file.py | 14 ++++-- tests/conftest.py | 10 ++++ .../spread/core24/appstream-desktop/task.yaml | 4 +- .../general/appstream-desktop/task.yaml | 4 +- .../appstream-icon-from-desktop/task.yaml | 4 +- .../general/appstream-remote-gfx/task.yaml | 4 +- tests/unit/parts/test_desktop_file.py | 48 ++++++++++++++----- tests/unit/parts/test_setup_assets.py | 6 +-- 8 files changed, 66 insertions(+), 28 deletions(-) diff --git a/snapcraft/parts/desktop_file.py b/snapcraft/parts/desktop_file.py index 7db5bd085a..afa7ba3c33 100644 --- a/snapcraft/parts/desktop_file.py +++ b/snapcraft/parts/desktop_file.py @@ -32,7 +32,7 @@ class DesktopFile: :param snap_name: The snap package name. :param app_name: The name of the app using the desktop file. - :param filename: The desktop file name. + :param filename: The desktop file path. :param prime_dir: The prime directory path. :raises DesktopFileError: If the desktop file does not exist. @@ -116,9 +116,15 @@ def write(self, *, gui_dir: Path, icon_path: Optional[str] = None) -> None: gui_dir.mkdir(parents=True, exist_ok=True) - # Rename the desktop file to match the app name. This will help - # unity8 associate them (https://launchpad.net/bugs/1659330). - target = gui_dir / f"{self._app_name}.desktop" + desktop_filename = os.path.basename(self._filename) + + # Stop renaming the desktop file. From snapd 2.66 onwards, + # users can declare custom desktop file names which snapd will not rename + # in the format of {SNAP_NAME}_{APP_NAME}.desktop + # https://snapcraft.io/docs/desktop-interface + target = gui_dir / desktop_filename + if not (desktop_filename.endswith(".desktop")): + target = gui_dir / f"{desktop_filename}.desktop" if target.exists(): # Unlikely. A desktop file in meta/gui/ already existed for diff --git a/tests/conftest.py b/tests/conftest.py index a09e205e6f..2755e539eb 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -15,6 +15,7 @@ # along with this program. If not, see . import os +from pathlib import Path import keyring import pytest @@ -52,6 +53,15 @@ def new_dir(tmp_path): os.chdir(cwd) +@pytest.fixture +def prime_dir(new_dir): + """Create a subdirectory structure 'new_dir/meta/gui'.""" + + prime_dir = Path(f"{new_dir}/meta/gui") + + yield prime_dir + + @pytest.fixture def memory_keyring(): """In memory keyring backend for testing.""" diff --git a/tests/spread/core24/appstream-desktop/task.yaml b/tests/spread/core24/appstream-desktop/task.yaml index b8a98eff75..ecd567e2ec 100644 --- a/tests/spread/core24/appstream-desktop/task.yaml +++ b/tests/spread/core24/appstream-desktop/task.yaml @@ -30,7 +30,7 @@ execute: | exit 1 fi - if ! diff -U10 prime/meta/gui/appstream-desktop.desktop expected_appstream-desktop.desktop; then - echo "The formatting for appstream-desktop.desktop is incorrect" + if ! diff -U10 prime/meta/gui/io.snapcraft.appstream.desktop expected_appstream-desktop.desktop; then + echo "The formatting for io.snapcraft.appstream.desktop is incorrect" exit 1 fi diff --git a/tests/spread/general/appstream-desktop/task.yaml b/tests/spread/general/appstream-desktop/task.yaml index 9906d67c2e..2adca1ae6c 100644 --- a/tests/spread/general/appstream-desktop/task.yaml +++ b/tests/spread/general/appstream-desktop/task.yaml @@ -44,7 +44,7 @@ execute: | expected_desktop="$PWD/../../appstream-desktop/expected_appstream-desktop.desktop" - if ! diff -U10 prime/meta/gui/appstream-desktop.desktop "$expected_desktop"; then - echo "The formatting for appstream-desktop.desktop is incorrect" + if ! diff -U10 prime/meta/gui/io.snapcraft.appstream.desktop "$expected_desktop"; then + echo "The formatting for io.snapcraft.appstream.desktop is incorrect" exit 1 fi diff --git a/tests/spread/general/appstream-icon-from-desktop/task.yaml b/tests/spread/general/appstream-icon-from-desktop/task.yaml index 6baf7220f6..27004274f0 100644 --- a/tests/spread/general/appstream-icon-from-desktop/task.yaml +++ b/tests/spread/general/appstream-icon-from-desktop/task.yaml @@ -40,7 +40,7 @@ execute: | expected_desktop="$PWD/../../appstream-desktop/expected_appstream-desktop.desktop" - if ! diff -U10 prime/meta/gui/appstream-desktop.desktop "$expected_desktop"; then - echo "The formatting for appstream-desktop.desktop is incorrect" + if ! diff -U10 prime/meta/gui/io.snapcraft.appstream.desktop "$expected_desktop"; then + echo "The formatting for io.snapcraft.appstream.desktop is incorrect" exit 1 fi diff --git a/tests/spread/general/appstream-remote-gfx/task.yaml b/tests/spread/general/appstream-remote-gfx/task.yaml index ec7cd9c0e2..fcf0a9c1e1 100644 --- a/tests/spread/general/appstream-remote-gfx/task.yaml +++ b/tests/spread/general/appstream-remote-gfx/task.yaml @@ -36,8 +36,8 @@ execute: | expected_desktop="$PWD/../../appstream-remote-gfx/expected_appstream-desktop.desktop" - if ! diff -U10 prime/meta/gui/appstream-desktop.desktop "$expected_desktop"; then - echo "The formatting for appstream-desktop.desktop is incorrect" + if ! diff -U10 prime/meta/gui/io.snapcraft.appstream.desktop "$expected_desktop"; then + echo "The formatting for io.snapcraft.appstream.desktop is incorrect" exit 1 fi diff --git a/tests/unit/parts/test_desktop_file.py b/tests/unit/parts/test_desktop_file.py index 78470c069d..08c9d2789e 100644 --- a/tests/unit/parts/test_desktop_file.py +++ b/tests/unit/parts/test_desktop_file.py @@ -14,7 +14,6 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from pathlib import Path from textwrap import dedent import pytest @@ -39,7 +38,9 @@ class TestDesktopExec: ("bar", "--arg", "foo.bar --arg"), ], ) - def test_generate_desktop_file(self, new_dir, app_name, app_args, expected_exec): + def test_generate_desktop_file( + self, new_dir, prime_dir, app_name, app_args, expected_exec + ): snap_name = "foo" desktop_file_path = new_dir / "app.desktop" @@ -53,9 +54,9 @@ def test_generate_desktop_file(self, new_dir, app_name, app_args, expected_exec) filename=desktop_file_path, prime_dir=new_dir.as_posix(), ) - d.write(gui_dir=Path()) + d.write(gui_dir=prime_dir) - expected_desktop_file = new_dir / f"{app_name}.desktop" + expected_desktop_file = prime_dir / "app.desktop" assert expected_desktop_file.exists() with expected_desktop_file.open() as desktop_file: assert desktop_file.read() == dedent( @@ -83,7 +84,9 @@ class TestDesktopIcon: ("foo", None, "foo"), ], ) - def test_generate_desktop_file(self, new_dir, icon, icon_path, expected_icon): + def test_generate_desktop_file( + self, new_dir, prime_dir, icon, icon_path, expected_icon + ): snap_name = app_name = "foo" desktop_file_path = new_dir / "app.desktop" @@ -101,14 +104,14 @@ def test_generate_desktop_file(self, new_dir, icon, icon_path, expected_icon): filename=desktop_file_path, prime_dir=new_dir, ) - d.write(gui_dir=Path()) + d.write(gui_dir=prime_dir) if icon_path is not None: - d.write(icon_path=icon_path, gui_dir=Path()) + d.write(icon_path=icon_path, gui_dir=prime_dir) else: - d.write(gui_dir=Path()) + d.write(gui_dir=prime_dir) - expected_desktop_file = new_dir / f"{app_name}.desktop" + expected_desktop_file = prime_dir / "app.desktop" assert expected_desktop_file.exists() with expected_desktop_file.open() as desktop_file: assert ( @@ -137,7 +140,7 @@ def test_generate_desktop_file(self, new_dir, icon, icon_path, expected_icon): ], ) def test_generate_desktop_file_multisection( - self, new_dir, icon, icon_path, expected_icon + self, new_dir, prime_dir, icon, icon_path, expected_icon ): snap_name = app_name = "foo" @@ -161,11 +164,11 @@ def test_generate_desktop_file_multisection( ) if icon_path is not None: - d.write(icon_path=icon_path, gui_dir=Path()) + d.write(icon_path=icon_path, gui_dir=prime_dir) else: - d.write(gui_dir=Path()) + d.write(gui_dir=prime_dir) - expected_desktop_file = new_dir / f"{app_name}.desktop" + expected_desktop_file = prime_dir / "app.desktop" assert expected_desktop_file.exists() with expected_desktop_file.open() as desktop_file: assert desktop_file.read() == dedent( @@ -223,3 +226,22 @@ def test_missing_exec_entry(new_dir): with pytest.raises(errors.DesktopFileError): d.write(gui_dir=new_dir) + + +def test_desktop_without_extension(new_dir, prime_dir): + desktop_file_path = new_dir / "app" + app_args = "" + with desktop_file_path.open("w") as desktop_file: + print("[Desktop Entry]", file=desktop_file) + print(f"Exec={' '.join(['in-snap-exe', app_args])}", file=desktop_file) + + d = DesktopFile( + snap_name="snap", + app_name="app1", + filename=desktop_file_path, + prime_dir=new_dir.as_posix(), + ) + d.write(gui_dir=prime_dir) + + expected_desktop_file = prime_dir / "app.desktop" + assert expected_desktop_file.exists() diff --git a/tests/unit/parts/test_setup_assets.py b/tests/unit/parts/test_setup_assets.py index 34efdc318e..30d5b96bec 100644 --- a/tests/unit/parts/test_setup_assets.py +++ b/tests/unit/parts/test_setup_assets.py @@ -247,7 +247,7 @@ def test_setup_assets_happy(self, desktop_file, yaml_data, new_dir): ) # desktop file should be in meta/gui and named after app - desktop_path = Path("prime/meta/gui/app1.desktop") + desktop_path = Path("prime/meta/gui/test.desktop") assert desktop_path.is_file() # desktop file content should make icon relative to ${SNAP} @@ -379,7 +379,7 @@ def test_setup_assets_icon_in_assets_dir(self, desktop_file, yaml_data, new_dir) ) # desktop file should be in meta/gui and named after app - desktop_path = Path("prime/meta/gui/app1.desktop") + desktop_path = Path("prime/meta/gui/test.desktop") assert desktop_path.is_file() # desktop file content should make icon relative to ${SNAP} @@ -449,7 +449,7 @@ def test_setup_assets_remote_icon(self, desktop_file, yaml_data, new_dir): ) # desktop file should be in meta/gui and named after app - desktop_path = Path("prime/meta/gui/app1.desktop") + desktop_path = Path("prime/meta/gui/test.desktop") assert desktop_path.is_file() # desktop file content should make icon relative to ${SNAP}