fix(jlcpcb): use platform user data dir for parts database (#167)
JLCPCBPartsManager defaulted db_path to a "data/" directory computed relative to __file__, which fails with read-only filesystems when the package is installed to a system-managed prefix (e.g. /nix/store, an immutable container image, or /usr/lib). The same pattern in download_jlcpcb.py would silently scatter the ~1.5 GB JLCPCB cache inside the install tree even when it is writable. The original integration plan (docs/archive/JLCPCB_INTEGRATION_PLAN.md) called for a per-user database under ~/.kicad-mcp/. This change moves the default to the platform-appropriate user data directory by adding a new PlatformHelper.get_data_dir() helper that mirrors the existing get_config_dir() / get_cache_dir() conventions: - Linux: XDG_DATA_HOME/kicad-mcp or ~/.local/share/kicad-mcp - macOS: ~/Library/Application Support/kicad-mcp - Windows: %USERPROFILE%\.kicad-mcp\data Both JLCPCBPartsManager and download_jlcpcb.py now resolve their database paths through this helper. ensure_directories() and detect_platform() include the new directory. Unit tests parallel to the existing config_dir/cache_dir cases cover platform-appropriate paths and the relative-XDG_DATA_HOME edge case.
This commit is contained in:
@@ -261,6 +261,37 @@ class PlatformHelper:
|
||||
else:
|
||||
return PlatformHelper.get_config_dir() / "cache"
|
||||
|
||||
@staticmethod
|
||||
def get_data_dir() -> Path:
|
||||
r"""
|
||||
Get appropriate data directory for current platform
|
||||
|
||||
Used for application state that should persist across runs and is not
|
||||
a transient cache (e.g. the JLCPCB parts database).
|
||||
|
||||
Follows platform conventions:
|
||||
- Windows: %USERPROFILE%\.kicad-mcp\data
|
||||
- Linux: $XDG_DATA_HOME/kicad-mcp or ~/.local/share/kicad-mcp
|
||||
- macOS: ~/Library/Application Support/kicad-mcp
|
||||
|
||||
Returns:
|
||||
Path to data directory
|
||||
"""
|
||||
if PlatformHelper.is_windows():
|
||||
return PlatformHelper.get_config_dir() / "data"
|
||||
elif PlatformHelper.is_linux():
|
||||
xdg_data = os.environ.get("XDG_DATA_HOME")
|
||||
if xdg_data:
|
||||
xdg_data_path = Path(xdg_data).expanduser()
|
||||
if xdg_data_path.is_absolute():
|
||||
return xdg_data_path / "kicad-mcp"
|
||||
logger.warning("Ignoring relative XDG_DATA_HOME: %s", xdg_data)
|
||||
return Path.home() / ".local" / "share" / "kicad-mcp"
|
||||
elif PlatformHelper.is_macos():
|
||||
return Path.home() / "Library" / "Application Support" / "kicad-mcp"
|
||||
else:
|
||||
return PlatformHelper.get_config_dir() / "data"
|
||||
|
||||
@staticmethod
|
||||
def ensure_directories() -> None:
|
||||
"""Create all necessary directories if they don't exist"""
|
||||
@@ -268,6 +299,7 @@ class PlatformHelper:
|
||||
PlatformHelper.get_config_dir(),
|
||||
PlatformHelper.get_log_dir(),
|
||||
PlatformHelper.get_cache_dir(),
|
||||
PlatformHelper.get_data_dir(),
|
||||
]
|
||||
|
||||
for directory in dirs_to_create:
|
||||
@@ -317,6 +349,7 @@ def detect_platform() -> dict:
|
||||
"config_dir": str(PlatformHelper.get_config_dir()),
|
||||
"log_dir": str(PlatformHelper.get_log_dir()),
|
||||
"cache_dir": str(PlatformHelper.get_cache_dir()),
|
||||
"data_dir": str(PlatformHelper.get_data_dir()),
|
||||
"kicad_python_paths": [str(p) for p in PlatformHelper.get_kicad_python_paths()],
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user