from __future__ import annotations import argparse import os import sys from pathlib import Path def _add_data_arg(src: Path, dest: str) -> str: """ Format a PyInstaller --add-data argument with the correct path separator for the current platform. """ sep = ";" if os.name == "nt" else ":" return f"{src}{sep}{dest}" def build(onefile: bool) -> None: root = Path(__file__).resolve().parent.parent entry = root / "script" / "auto_run.py" flash_dir = root / "Flash" if not entry.exists(): sys.exit(f"Entry script missing: {entry}") if not flash_dir.exists(): sys.exit(f"Flash folder missing: {flash_dir}") # Keep PyInstaller searches predictable. os.chdir(root) try: import PyInstaller.__main__ as pyinstaller except ImportError: sys.exit("PyInstaller is not installed. Run `python -m pip install PyInstaller` first.") args = [ "--noconfirm", "--clean", "--onefile" if onefile else "--onedir", "--name=AmebaControlPanel", f"--distpath={root / 'dist'}", f"--workpath={root / 'build'}", "--paths", str(root), "--collect-all", "PySide6", "--hidden-import=serial", "--hidden-import=serial.tools.list_ports", "--hidden-import=pyDes", "--hidden-import=colorama", "--add-data", _add_data_arg(flash_dir, "Flash"), str(entry), ] pyinstaller.run(args) if __name__ == "__main__": parser = argparse.ArgumentParser(description="Build Ameba Control Panel executable with PyInstaller") parser.add_argument( "--onedir", action="store_true", help="Create an onedir bundle instead of a single-file exe", ) build(onefile=not parser.parse_args().onedir)