diff --git a/snapcraft/parts/desktop_file.py b/snapcraft/parts/desktop_file.py index c3f5ec737c..2d6dc6e857 100644 --- a/snapcraft/parts/desktop_file.py +++ b/snapcraft/parts/desktop_file.py @@ -77,10 +77,12 @@ def _parse_and_reformat_section_exec(self, section: str): def _parse_and_reformat_section( self, *, section: str, icon_path: str | None = None ): - if "Exec" not in self._parser[section]: - raise errors.DesktopFileError(self._filename, "missing 'Exec' key") - - self._parse_and_reformat_section_exec(section) + # Exec is not required: desktop entries that are D-Bus- or + # systemd-activated (often with NoDisplay=true) are valid without it, + # per the Desktop Entry specification and desktop-file-validate. Only + # reformat the Exec line when it is present. + if "Exec" in self._parser[section]: + self._parse_and_reformat_section_exec(section) if "Icon" in self._parser[section]: icon = self._parser[section]["Icon"] diff --git a/tests/unit/parts/test_desktop_file.py b/tests/unit/parts/test_desktop_file.py index ea1fb5339a..b2669cbfaf 100644 --- a/tests/unit/parts/test_desktop_file.py +++ b/tests/unit/parts/test_desktop_file.py @@ -207,9 +207,16 @@ def test_no_desktop_section(new_dir): def test_missing_exec_entry(new_dir): + """A desktop entry without an Exec key is written through unchanged. + + Exec is not required for D-Bus- or systemd-activated entries (regression + test for https://github.com/canonical/snapcraft/issues/5799). + """ with open("foo.desktop", "w") as desktop_file: print("[Desktop Entry]", file=desktop_file) - print("Icon=foo", file=desktop_file) + print("Type=Application", file=desktop_file) + print("Name=Foo", file=desktop_file) + print("NoDisplay=true", file=desktop_file) d = DesktopFile( snap_name="foo", @@ -217,6 +224,17 @@ def test_missing_exec_entry(new_dir): filename="foo.desktop", prime_dir=new_dir, ) + d.write(gui_dir=new_dir) - with pytest.raises(errors.DesktopFileError): - d.write(gui_dir=new_dir) + written = new_dir / "foo.desktop" + assert written.exists() + with written.open() as desktop_file: + assert desktop_file.read() == dedent( + """\ + [Desktop Entry] + Type=Application + Name=Foo + NoDisplay=true + + """ + )