diff --git a/README.md b/README.md index 230b0c5..4f44168 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ source .venv/bin/activate # Windows: .venv\Scripts\activate uv pip install . # install ICRS and dependencies uv run icrs # launches the GUI ``` +The launcher copies Tcl/Tk resources into the virtualenv on first run, so no manual environment tweaks are needed. To include the optional ttkbootstrap theme pack: ```bash uv pip install '.[ui]' diff --git a/app/launcher.py b/app/launcher.py new file mode 100644 index 0000000..80c61d4 --- /dev/null +++ b/app/launcher.py @@ -0,0 +1,50 @@ +"""Launcher ensuring Tcl/Tk resources are available before starting ICRS.""" + +from __future__ import annotations + +import os +import shutil +import subprocess +import sys +from pathlib import Path + + +def _copy_tcl_runtime(venv_root: Path) -> tuple[Path, Path] | None: + """Copy Tcl/Tk directories from the base interpreter into the venv if needed.""" + + base_prefix = Path(getattr(sys, "base_prefix", sys.prefix)) + base_tcl_dir = base_prefix / "tcl" + if not base_tcl_dir.exists(): + return None + + tcl_src = base_tcl_dir / "tcl8.6" + tk_src = base_tcl_dir / "tk8.6" + if not tcl_src.exists() or not tk_src.exists(): + return None + + target_root = venv_root / "tcl" + tcl_dest = target_root / "tcl8.6" + tk_dest = target_root / "tk8.6" + + if not tcl_dest.exists(): + shutil.copytree(tcl_src, tcl_dest, dirs_exist_ok=True) + if not tk_dest.exists(): + shutil.copytree(tk_src, tk_dest, dirs_exist_ok=True) + + return tcl_dest, tk_dest + + +def main() -> int: + venv_root = Path(sys.prefix) + tcl_paths = _copy_tcl_runtime(venv_root) + + env = os.environ.copy() + if tcl_paths: + env.setdefault("TCL_LIBRARY", str(tcl_paths[0])) + env.setdefault("TK_LIBRARY", str(tcl_paths[1])) + + return subprocess.call([sys.executable, "main.py"], env=env) + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/pyproject.toml b/pyproject.toml index eec0cc1..7981976 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,7 @@ dependencies = [ ui = ["ttkbootstrap>=1.10.0"] [project.scripts] -icrs = "app.app:start_app" +icrs = "app.launcher:main" [tool.uv] package = true