qet-mcp: the scripts folder rule as a pure function, tested for Windows and macOS

Checked against a real Windows package under Wine: QElectroTech keeps its
data in %APPDATA%\QElectroTech\QElectroTech, next to which the scripts
folder goes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ispyisail
2026-10-02 10:05:24 +13:00
parent 55eac848df
commit cd51f39d7b
2 changed files with 36 additions and 16 deletions
+20 -10
View File
@@ -64,7 +64,7 @@ import subprocess
import sys
import tempfile
import xml.etree.ElementTree as ET
from pathlib import Path, PurePath
from pathlib import Path, PurePath, PurePosixPath, PureWindowsPath
SERVER_NAME = "qet-mcp"
SERVER_VERSION = "0.1.0"
@@ -2593,24 +2593,34 @@ SCRIPT_HEADER_HELP = (
"qet.showMessage() opens a dialog the user has to close.")
def default_scripts_dir(os_name: str, platform: str, env, home) -> PurePath:
"""QETApp::dataDir() + "/scripts" for a given platform.
dataDir() is Qt's AppDataLocation with organisation and application
both "QElectroTech" (main.cpp). Pure, so the Windows and macOS answers
are tested on any machine.
"""
if os_name == "nt":
appdata = env.get("APPDATA")
base = (PureWindowsPath(appdata) if appdata
else PureWindowsPath(home, "AppData", "Roaming"))
elif platform == "darwin":
base = PurePosixPath(home, "Library", "Application Support")
else:
base = PurePosixPath(env.get("XDG_DATA_HOME") or PurePosixPath(home, ".local", "share"))
return base / "QElectroTech" / "QElectroTech" / "scripts"
def scripts_dir() -> Path:
"""The folder QElectroTech reads stored scripts from.
QETApp::dataDir() + "/scripts", where dataDir() is Qt's
AppDataLocation for organisation and application "QElectroTech".
QET_MCP_SCRIPTS_DIR overrides it, for a QElectroTech started with
--data-dir or a test.
"""
env = os.environ.get("QET_MCP_SCRIPTS_DIR", "").strip()
if env:
return Path(env).expanduser()
if os.name == "nt":
base = Path(os.environ.get("APPDATA") or Path.home() / "AppData" / "Roaming")
elif sys.platform == "darwin":
base = Path.home() / "Library" / "Application Support"
else:
base = Path(os.environ.get("XDG_DATA_HOME") or Path.home() / ".local" / "share")
return base / "QElectroTech" / "QElectroTech" / "scripts"
return Path(str(default_scripts_dir(os.name, sys.platform, os.environ, str(Path.home()))))
def parse_script_header(text: str, script_id: str) -> dict:
+16 -6
View File
@@ -2917,12 +2917,22 @@ class ScriptStore(unittest.TestCase):
"error": "no // ==QETScript== header"}])
def test_default_folder_is_qets_data_dir(self):
with mock.patch.dict(os.environ, {"QET_MCP_SCRIPTS_DIR": "",
"XDG_DATA_HOME": "/x/share"}), \
mock.patch.object(m.os, "name", "posix"), \
mock.patch.object(m.sys, "platform", "linux"):
self.assertEqual(m.scripts_dir(),
Path("/x/share/QElectroTech/QElectroTech/scripts"))
"""QStandardPaths::AppDataLocation plus the organisation and
application names main.cpp sets, on each platform."""
from pathlib import PurePosixPath, PureWindowsPath
f = m.default_scripts_dir
self.assertEqual(f("posix", "linux", {"XDG_DATA_HOME": "/x/share"}, "/home/u"),
PurePosixPath("/x/share/QElectroTech/QElectroTech/scripts"))
self.assertEqual(f("posix", "linux", {}, "/home/u"),
PurePosixPath("/home/u/.local/share/QElectroTech/QElectroTech/scripts"))
self.assertEqual(f("nt", "win32", {"APPDATA": r"C:\Users\u\AppData\Roaming"}, r"C:\Users\u"),
PureWindowsPath(r"C:\Users\u\AppData\Roaming\QElectroTech\QElectroTech\scripts"))
self.assertEqual(f("nt", "win32", {}, r"C:\Users\u"),
PureWindowsPath(r"C:\Users\u\AppData\Roaming\QElectroTech\QElectroTech\scripts"))
self.assertEqual(f("posix", "darwin", {}, "/Users/u"),
PurePosixPath("/Users/u/Library/Application Support/QElectroTech/QElectroTech/scripts"))
with mock.patch.dict(os.environ, {"QET_MCP_SCRIPTS_DIR": "/elsewhere"}):
self.assertEqual(m.scripts_dir(), Path("/elsewhere"))
def test_install_does_not_need_a_binary_without_a_test(self):
"""Only a test run launches QElectroTech; storing a file must not be