mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-09 21:54:13 +02:00
Merge pull request #1403 from ispyisail/fix/mcp-macos-no-copy
Linux build and tests / Build and test (Qt 6, Debug) (push) Failing after 2m1s
Linux build and tests / Build and test (Qt 6, Debug) (push) Failing after 2m1s
Fix assistant server tools failing on macOS: run the original program (#1178)
This commit is contained in:
+24
-11
@@ -896,19 +896,32 @@ def tool_element_info(path: str) -> dict:
|
||||
}
|
||||
|
||||
|
||||
def _launch_executable(src: Path, sandbox: Path, windows: bool) -> Path:
|
||||
"""The executable _run_qet() starts: a private copy, except on Windows.
|
||||
def _copies_executable(platform: str = sys.platform) -> bool:
|
||||
"""Whether _run_qet() runs a private copy of QElectroTech on @p platform:
|
||||
not on Windows or macOS (see _launch_executable())."""
|
||||
return platform not in ("win32", "darwin")
|
||||
|
||||
|
||||
def _launch_executable(src: Path, sandbox: Path, copy: bool) -> Path:
|
||||
"""The executable _run_qet() starts: a private copy when @p copy is set,
|
||||
otherwise the original.
|
||||
|
||||
The copy gives each run its own SingleApplication key, which is derived
|
||||
from the executable's path. On Windows a program loads its DLLs from its
|
||||
own folder, so a copy on its own dies before main() (0xC0000135, DLL not
|
||||
found) and nothing could ever be exported or edited there. Run the
|
||||
original instead: every flag this server passes is a CLI export flag or
|
||||
--run, and QElectroTech handles both and returns before it constructs
|
||||
SingleApplication (main.cpp), so there is no instance to be handed to.
|
||||
The copy stays elsewhere for builds from before that early return.
|
||||
from the executable's path. Two systems cannot run a copy:
|
||||
|
||||
- Windows: a program loads its DLLs from its own folder, so a copy on
|
||||
its own dies before main() (0xC0000135, DLL not found).
|
||||
- macOS: a copy taken out of the signed .app bundle is killed at launch
|
||||
(exit 137) and has lost the path to the bundle's Qt frameworks
|
||||
(qelectrotech-source-mirror#1178).
|
||||
|
||||
There, run the original instead: every flag this server passes is a CLI
|
||||
export flag or --run, and QElectroTech handles both and returns before
|
||||
it constructs SingleApplication (main.cpp), so there is no instance to
|
||||
be handed to. The copy stays elsewhere for builds from before that
|
||||
early return.
|
||||
"""
|
||||
if windows:
|
||||
if not copy:
|
||||
return src
|
||||
exe = sandbox / f"qet-mcp-{os.getpid()}"
|
||||
shutil.copy2(src, exe)
|
||||
@@ -996,7 +1009,7 @@ def _run_qet(binary: str, args: list[str], timeout: int = 180,
|
||||
raise ValueError(f"not an executable: {src}")
|
||||
with tempfile.TemporaryDirectory(prefix="qet-mcp-") as tmp:
|
||||
sandbox = Path(tmp)
|
||||
exe = _launch_executable(src, sandbox, os.name == "nt")
|
||||
exe = _launch_executable(src, sandbox, _copies_executable())
|
||||
home = sandbox / "home"
|
||||
(home / ".config").mkdir(parents=True)
|
||||
(home / ".local" / "share").mkdir(parents=True)
|
||||
|
||||
@@ -3045,7 +3045,8 @@ class BinaryPolicy(unittest.TestCase):
|
||||
|
||||
class LaunchExecutable(unittest.TestCase):
|
||||
"""Windows cannot run a lone copy of QElectroTech (F065): its DLLs sit
|
||||
beside the original. Everywhere else the private copy stays."""
|
||||
beside the original. Nor can macOS: a copy out of the signed .app is
|
||||
killed at launch (#1178). Everywhere else the private copy stays."""
|
||||
|
||||
def setUp(self):
|
||||
self.tmp = tempfile.TemporaryDirectory()
|
||||
@@ -3059,9 +3060,14 @@ class LaunchExecutable(unittest.TestCase):
|
||||
def tearDown(self):
|
||||
self.tmp.cleanup()
|
||||
|
||||
def test_windows_runs_the_original(self):
|
||||
self.assertEqual(m._launch_executable(self.src, self.sandbox, True), self.src)
|
||||
self.assertEqual(list(self.sandbox.iterdir()), [], "nothing is copied on Windows")
|
||||
def test_windows_and_macos_run_the_original(self):
|
||||
self.assertEqual(m._launch_executable(self.src, self.sandbox, False), self.src)
|
||||
self.assertEqual(list(self.sandbox.iterdir()), [], "nothing is copied")
|
||||
|
||||
def test_which_systems_copy(self):
|
||||
self.assertFalse(m._copies_executable("win32"))
|
||||
self.assertFalse(m._copies_executable("darwin"))
|
||||
self.assertTrue(m._copies_executable("linux"))
|
||||
|
||||
def test_windows_keeps_its_own_qt_platform(self):
|
||||
"""The Windows packages have no offscreen plugin; asking for it
|
||||
@@ -3083,7 +3089,7 @@ class LaunchExecutable(unittest.TestCase):
|
||||
self.assertEqual(env["QET_SETTINGS_DIR"], str(self.sandbox / ".config"))
|
||||
|
||||
def test_elsewhere_runs_a_private_copy(self):
|
||||
exe = m._launch_executable(self.src, self.sandbox, False)
|
||||
exe = m._launch_executable(self.src, self.sandbox, True)
|
||||
self.assertEqual(exe.parent, self.sandbox)
|
||||
self.assertNotEqual(exe, self.src)
|
||||
self.assertEqual(exe.read_text(), self.src.read_text())
|
||||
|
||||
Reference in New Issue
Block a user