From e11d69d1ef49b5bec84f9dd7efdbc2259dac37d1 Mon Sep 17 00:00:00 2001 From: chakcy <947105045@qq.com> Date: Thu, 20 Aug 2026 16:57:04 +0800 Subject: [PATCH] =?UTF-8?q?modify:=20=E4=B8=BAuv=20run=20build=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E4=BB=85=E6=9B=BF=E6=8D=A2mbank=E7=9A=84=E5=8F=82?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++ src/chongming_cli/build.py | 124 +++++++++++++++++++++++++++---------- 2 files changed, 94 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index ab80bd5..1ae3934 100644 --- a/README.md +++ b/README.md @@ -19,11 +19,15 @@ chongming 网关的命令脚本集合,独立包维护(从 `src/chongming/scr ```bash uv run build pyinstaller # 构建打包 +uv run build --only mbank # 仅重新打包 .mbank 模块文件(跳过其余流程) +uv run build --only mbank,vue # 只执行指定步骤 uv run build_plugin demo # 进程插件打包 → dist/demo.zip uv run gen_plugin myplugin # 生成插件骨架 uv run gen_models config/workers/myplugin src/plugins/myplugin ``` +`build --only ` 可选步骤:`mbank` / `prepare` / `obfuscate` / `pack` / `clean` / `vue`,可逗号分隔或重复传多个。 + ## 项目根目录定位 脚本需要在项目根目录下读写 `config/`、`src/plugins/`、`workers/` 等路径。 diff --git a/src/chongming_cli/build.py b/src/chongming_cli/build.py index 6c1b23b..d60264c 100644 --- a/src/chongming_cli/build.py +++ b/src/chongming_cli/build.py @@ -2,14 +2,29 @@ 构建脚本 - 将 chongming 应用打包为可执行文件 功能阶段: - 1. 模块打包(module-bank): 加密打包 Python 模块 + 1. 模块打包(module-bank): 加密打包 Python 模块为 .mbank 2. 资源准备: 创建 build 目录, 复制必要文件 3. 混淆与打包: pyarmor 混淆 + PyInstaller/Nuitka 打包 4. 数据库初始化: 创建表结构和默认数据 5. 前端构建: 编译 Vue 项目并打包为 VFS 用法: - uv run build [pyinstaller|nuitka] + uv run build [pyinstaller|nuitka] [--only [,...]] + +参数: + pyinstaller|nuitka 构建模式(默认 pyinstaller) + --only 只执行指定步骤,跳过其余流程,可选: + mbank 模块打包(重新生成 .mbank 文件) + prepare 准备构建目录 + obfuscate PyArmor 混淆(仅 pyinstaller 模式) + pack PyInstaller/Nuitka 打包 + clean 清理临时文件 + vue Vue 前端构建 + 可传多个: --only mbank,vue 或 --only mbank --only vue + + 示例: + uv run build --only mbank # 依赖未变时,仅重新打包 .mbank 模块文件 + uv run build nuitka --only mbank,prepare """ import platform @@ -33,6 +48,9 @@ PYINSTALLER = "pyinstaller" NUITKA = "nuitka" MODES = (PYINSTALLER, NUITKA) +# 可独立执行的构建步骤(--only 参数取值) +STEPS = ("mbank", "prepare", "obfuscate", "pack", "clean", "vue") + is_windows = platform.system() == "Windows" # ── 构建结果数据结构 ───────────────────────────────────────────────────────── @@ -151,15 +169,41 @@ def _ensure_dir(path: str | Path): Path(path).mkdir(parents=True, exist_ok=True) -def _resolve_mode() -> str: - """解析构建模式""" +def _parse_args() -> tuple[str, set[str]]: + """解析命令行参数,返回 (构建模式, 需执行的步骤子集) + + 支持: + uv run build [pyinstaller|nuitka] + uv run build --only [,...] [pyinstaller|nuitka] + only_steps 为空表示执行完整构建流程。 + """ + args = sys.argv[1:] mode = PYINSTALLER - if len(sys.argv) >= 2: - mode = sys.argv[1].lower() - if mode not in MODES: - print(f" ❌ 不支持的构建模式: {mode},可选: {', '.join(MODES)}") - sys.exit(1) - return mode + only_steps: set[str] = set() + i = 0 + while i < len(args): + arg = args[i] + if arg == "--only": + if i + 1 >= len(args): + print(f" ❌ 参数 --only 缺少步骤名称,可选: {', '.join(STEPS)}") + sys.exit(1) + for step in args[i + 1].split(","): + step = step.strip().lower() + if step not in STEPS: + print(f" ❌ 不支持的步骤: {step},可选: {', '.join(STEPS)}") + sys.exit(1) + only_steps.add(step) + i += 2 + elif arg.startswith("--"): + print(f" ❌ 未知参数: {arg}") + sys.exit(1) + else: + mode = arg.lower() + if mode not in MODES: + print(f" ❌ 不支持的构建模式: {mode},可选: {', '.join(MODES)}") + sys.exit(1) + i += 1 + return mode, only_steps # ── 阶段 1: 模块打包 (module-bank) ────────────────────────────────────────── @@ -458,10 +502,14 @@ def _stage_build_vue() -> str: async def main(): """规范化构建主流程""" - mode = _resolve_mode() + mode, only_steps = _parse_args() report = BuildReport(mode=mode, start_time=time.time()) config = get_config() + def should_run(name: str) -> bool: + """--only 模式下仅执行指定步骤""" + return not only_steps or name in only_steps + async def run_step(name: str, fn, *args, **kwargs) -> str: """执行一个构建步骤并记录结果(支持同步和异步函数)""" start = time.time() @@ -485,40 +533,48 @@ async def main(): print("\n" + "=" * 60) print(" 🏗️ CHONGMING 构建开始") print(f" 模式: {mode} | 平台: {platform.system()}") + if only_steps: + print(f" 仅执行步骤: {', '.join(sorted(only_steps))}") print("=" * 60 + "\n") # 阶段 1: 模块打包 - await run_step("模块打包(module-bank)", _stage_pack_modules, config) + if should_run("mbank"): + await run_step("模块打包(module-bank)", _stage_pack_modules, config) # 阶段 2: 准备构建目录 - await run_step("准备构建目录", _stage_prepare_build_dir, config, mode) + if should_run("prepare"): + await run_step("准备构建目录", _stage_prepare_build_dir, config, mode) # 阶段 3+4: 混淆 + 打包 - if mode == PYINSTALLER: - await run_step("PyArmor 混淆", _stage_pyarmor_obfuscate) - start = time.time() - try: - msg, exe_path = _stage_pyinstaller(config) - elapsed = time.time() - start - success = "❌" not in msg - report.add_step( - "PyInstaller 打包", success, elapsed, msg.replace("✅ PyInstaller ", "") - ) - print( - f" {'✅' if success else '❌'} PyInstaller 打包{' ' * 12} {elapsed:>7.2f}s {msg}" - ) - except Exception as e: - elapsed = time.time() - start - report.add_step("PyInstaller 打包", False, elapsed, str(e)[:200]) - print(f" ❌ PyInstaller 打包 {elapsed:>7.2f}s {str(e)[:200]}") - else: - await run_step("Nuitka 编译", lambda: _stage_nuitka(config)[0]) + if should_run("pack"): + if mode == PYINSTALLER: + if should_run("obfuscate"): + await run_step("PyArmor 混淆", _stage_pyarmor_obfuscate) + start = time.time() + try: + msg, exe_path = _stage_pyinstaller(config) + elapsed = time.time() - start + success = "❌" not in msg + report.add_step( + "PyInstaller 打包", success, elapsed, msg.replace("✅ PyInstaller ", "") + ) + print( + f" {'✅' if success else '❌'} PyInstaller 打包{' ' * 12} {elapsed:>7.2f}s {msg}" + ) + except Exception as e: + elapsed = time.time() - start + report.add_step("PyInstaller 打包", False, elapsed, str(e)[:200]) + print(f" ❌ PyInstaller 打包 {elapsed:>7.2f}s {str(e)[:200]}") + else: + await run_step("Nuitka 编译", lambda: _stage_nuitka(config)[0]) # 阶段 5: 清理 - await run_step("清理临时文件", _stage_cleanup, mode) + if should_run("clean"): + await run_step("清理临时文件", _stage_cleanup, mode) # 阶段 7: Vue 前端构建 - await run_step("Vue 前端构建", _stage_build_vue) + if should_run("vue"): + await run_step("Vue 前端构建", _stage_build_vue) # 总结 report.end_time = time.time()