Merge branch 'fix-k-field-code-expansion' into 'main'

gio-tool-launch: fix %k field code expansion

See merge request GNOME/glib!4682
This commit is contained in:
Philip Withnall
2025-07-09 13:10:28 +00:00
3 changed files with 84 additions and 6 deletions

View File

@@ -88,12 +88,12 @@ handle_launch (int argc, char *argv[], gboolean do_help)
retval = 1; retval = 1;
#else #else
retval = 0; retval = 0;
desktop_file = argv[1]; desktop_file = g_canonicalize_filename (argv[1], NULL);
/* Use keyfile api for loading desktop app in order to check for /* Use g_key_file_load_from_file() to give better user feedback (missing vs.
* - not existing file. * malformed file), then load it with g_desktop_app_info_new_from_filename()
* - invalid keyfile format. * to set the constructor-only filename property required for expanding %k.
*/ */
keyfile = g_key_file_new (); keyfile = g_key_file_new ();
if (!g_key_file_load_from_file (keyfile, desktop_file, G_KEY_FILE_NONE, &error)) if (!g_key_file_load_from_file (keyfile, desktop_file, G_KEY_FILE_NONE, &error))
{ {
@@ -103,7 +103,7 @@ handle_launch (int argc, char *argv[], gboolean do_help)
} }
else else
{ {
app = (GAppInfo*)g_desktop_app_info_new_from_keyfile (keyfile); app = (GAppInfo *)g_desktop_app_info_new_from_filename (desktop_file);
if (!app) if (!app)
{ {
print_error (_("Unable to load application information for %s"), desktop_file); print_error (_("Unable to load application information for %s"), desktop_file);

View File

@@ -23,11 +23,14 @@
"""Integration tests for the gio utility.""" """Integration tests for the gio utility."""
import platform
import subprocess import subprocess
import sys import sys
import tempfile import tempfile
import unittest import unittest
from pathlib import Path
import taptestrunner import taptestrunner
import testprogramrunner import testprogramrunner
@@ -79,5 +82,75 @@ class TestGioTool(testprogramrunner.TestProgramRunner):
) )
@unittest.skipIf(platform.system() == "Darwin", "gio launch not supported on darwin")
class TestGioLaunchExpandsDesktopEntry(testprogramrunner.TestProgramRunner):
"""Integration test for `gio launch` with field code %k in the Exec line.
This can be run when installed or uninstalled. When uninstalled, it
requires G_TEST_BUILDDIR and G_TEST_SRCDIR to be set.
The idea with this test harness is to test that the `gio launch` command
expands the `%k` field code in a desktop entry's Exec line to its location,
i.e. its absolute path.
"""
PROGRAM_NAME = "gio"
PROGRAM_TYPE = testprogramrunner.ProgramType.NATIVE
TEMPLATE = """
[Desktop Entry]
Type = Application
Name = Test
Exec = {python} -c 'print("%k")'
"""
def setUp(self):
super().setUp()
self.parent = Path(self.tmpdir.name).resolve()
self.folder = self.parent / "folder"
self.entry = self.folder / "desktop.entry"
self.sibling = self.parent / "sibling"
self.folder.mkdir(exist_ok=True, parents=True)
self.sibling.mkdir(exist_ok=True, parents=True)
with self.entry.open("w", encoding="utf-8") as fd:
fd.write(self.TEMPLATE.format(python=sys.executable))
def launchAndCheck(self, entry: Path, cwd: Path = None):
result = self.runTestProgram(["launch", str(entry)], cwd=str(cwd))
self.assertEqual(result.out, str(self.entry))
def test_absolute_from_folder(self):
"""Test with absolute path, with changing working directory to folder."""
self.launchAndCheck(self.entry, cwd=self.folder)
def test_absolute_from_parent(self):
"""Test with absolute path, with changing working directory to parent."""
self.launchAndCheck(self.entry, cwd=self.parent)
def test_absolute_from_sibling(self):
"""Test with absolute path, with changing working directory to sibling."""
self.launchAndCheck(self.entry, cwd=self.sibling)
def test_relative_from_folder(self):
"""Test with relative path, with changing working directory to folder."""
self.launchAndCheck(self.entry.relative_to(self.folder), cwd=self.folder)
def test_relative_from_parent(self):
"""Test with relative path, with changing working directory to parent."""
self.launchAndCheck(self.entry.relative_to(self.parent), cwd=self.parent)
def test_relative_from_sibling(self):
"""Test with relative path, with changing working directory to sibling."""
self.launchAndCheck(
Path("..") / self.entry.relative_to(self.parent), cwd=self.sibling
)
if __name__ == "__main__": if __name__ == "__main__":
unittest.main(testRunner=taptestrunner.TAPTestRunner()) unittest.main(testRunner=taptestrunner.TAPTestRunner())

View File

@@ -104,6 +104,7 @@ class TestProgramRunner(unittest.TestCase):
timeout_seconds=10, timeout_seconds=10,
wrapper_args=[], wrapper_args=[],
environment={}, environment={},
cwd=None,
) -> Result: ) -> Result:
argv = [self.__program] argv = [self.__program]
@@ -123,6 +124,9 @@ class TestProgramRunner(unittest.TestCase):
print("Running:", argv) print("Running:", argv)
if cwd is not None:
print("Working Directory:", cwd)
# We want to ensure consistent line endings... # We want to ensure consistent line endings...
info = subprocess.run( info = subprocess.run(
argv, argv,
@@ -134,6 +138,7 @@ class TestProgramRunner(unittest.TestCase):
text=True, text=True,
encoding="utf-8", encoding="utf-8",
check=False, check=False,
cwd=cwd,
) )
result = Result( result = Result(