102 lines
2.7 KiB
Python
102 lines
2.7 KiB
Python
"""Build CadHubManage as a standalone Windows executable using PyInstaller."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import os
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
def ensure_pyinstaller() -> None:
|
|
try:
|
|
import PyInstaller # noqa: F401 pylint: disable=unused-import
|
|
except ImportError as exc: # pragma: no cover - runtime guard
|
|
raise SystemExit(
|
|
"PyInstaller 未安装,请先运行 'pip install pyinstaller'."
|
|
) from exc
|
|
|
|
|
|
def build_executable(*, clean: bool) -> Path:
|
|
project_root = Path(__file__).resolve().parents[1]
|
|
dist_dir = project_root / "dist"
|
|
build_dir = project_root / "build"
|
|
temp_dist = dist_dir / "tmp_pyinstaller"
|
|
exe_name = "CadHubManage.exe"
|
|
output_exe = dist_dir / exe_name
|
|
|
|
if clean:
|
|
if build_dir.exists():
|
|
shutil.rmtree(build_dir)
|
|
if temp_dist.exists():
|
|
shutil.rmtree(temp_dist)
|
|
if output_exe.exists():
|
|
output_exe.unlink()
|
|
|
|
ensure_pyinstaller()
|
|
|
|
dist_dir.mkdir(parents=True, exist_ok=True)
|
|
temp_dist.mkdir(parents=True, exist_ok=True)
|
|
|
|
entry_script = project_root / "launcher.py"
|
|
|
|
command = [
|
|
sys.executable,
|
|
"-m",
|
|
"PyInstaller",
|
|
"--noconfirm",
|
|
"--clean",
|
|
"--onefile",
|
|
"--name",
|
|
"CadHubManage",
|
|
"--distpath",
|
|
str(temp_dist),
|
|
"--workpath",
|
|
str(build_dir),
|
|
"--specpath",
|
|
str(project_root / "scripts"),
|
|
]
|
|
|
|
configs_src = project_root / "configs"
|
|
if configs_src.exists():
|
|
command += ["--add-data", f"{configs_src}{os.pathsep}configs"]
|
|
|
|
env_example = project_root / ".env.example"
|
|
if env_example.exists():
|
|
command += ["--add-data", f"{env_example}{os.pathsep}."]
|
|
|
|
command.append(str(entry_script))
|
|
|
|
subprocess.check_call(command)
|
|
|
|
built_exe = temp_dist / exe_name
|
|
if not built_exe.exists():
|
|
raise FileNotFoundError(f"未找到 PyInstaller 生成的可执行文件: {built_exe}")
|
|
|
|
if output_exe.exists():
|
|
output_exe.unlink()
|
|
shutil.move(str(built_exe), str(output_exe))
|
|
|
|
shutil.rmtree(temp_dist)
|
|
|
|
return output_exe
|
|
|
|
|
|
def parse_args() -> argparse.Namespace:
|
|
parser = argparse.ArgumentParser(description="打包 CadHubManage 为单文件 exe")
|
|
parser.add_argument("--clean", action="store_true", help="构建前清理旧产物")
|
|
return parser.parse_args()
|
|
|
|
|
|
def main() -> None:
|
|
args = parse_args()
|
|
exe_path = build_executable(clean=args.clean)
|
|
print(f"构建完成: {exe_path}")
|
|
print("将 dist/CadHubManage.exe 单文件分发到目标机器即可运行")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|