modify: 为uv run build添加仅替换mbank的参数

This commit is contained in:
2026-08-20 16:57:04 +08:00
parent 0bf60021cb
commit e11d69d1ef
2 changed files with 94 additions and 34 deletions
+4
View File
@@ -19,11 +19,15 @@ chongming 网关的命令脚本集合,独立包维护(从 `src/chongming/scr
```bash ```bash
uv run build pyinstaller # 构建打包 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 build_plugin demo # 进程插件打包 → dist/demo.zip
uv run gen_plugin myplugin # 生成插件骨架 uv run gen_plugin myplugin # 生成插件骨架
uv run gen_models config/workers/myplugin src/plugins/myplugin uv run gen_models config/workers/myplugin src/plugins/myplugin
``` ```
`build --only <step>` 可选步骤:`mbank` / `prepare` / `obfuscate` / `pack` / `clean` / `vue`,可逗号分隔或重复传多个。
## 项目根目录定位 ## 项目根目录定位
脚本需要在项目根目录下读写 `config/`、`src/plugins/`、`workers/` 等路径。 脚本需要在项目根目录下读写 `config/`、`src/plugins/`、`workers/` 等路径。
+90 -34
View File
@@ -2,14 +2,29 @@
构建脚本 - 将 chongming 应用打包为可执行文件 构建脚本 - 将 chongming 应用打包为可执行文件
功能阶段: 功能阶段:
1. 模块打包(module-bank): 加密打包 Python 模块 1. 模块打包(module-bank): 加密打包 Python 模块为 .mbank
2. 资源准备: 创建 build 目录, 复制必要文件 2. 资源准备: 创建 build 目录, 复制必要文件
3. 混淆与打包: pyarmor 混淆 + PyInstaller/Nuitka 打包 3. 混淆与打包: pyarmor 混淆 + PyInstaller/Nuitka 打包
4. 数据库初始化: 创建表结构和默认数据 4. 数据库初始化: 创建表结构和默认数据
5. 前端构建: 编译 Vue 项目并打包为 VFS 5. 前端构建: 编译 Vue 项目并打包为 VFS
用法: 用法:
uv run build [pyinstaller|nuitka] uv run build [pyinstaller|nuitka] [--only <step>[,<step>...]]
参数:
pyinstaller|nuitka 构建模式(默认 pyinstaller)
--only <step> 只执行指定步骤,跳过其余流程,可选:
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 import platform
@@ -33,6 +48,9 @@ PYINSTALLER = "pyinstaller"
NUITKA = "nuitka" NUITKA = "nuitka"
MODES = (PYINSTALLER, NUITKA) MODES = (PYINSTALLER, NUITKA)
# 可独立执行的构建步骤(--only 参数取值)
STEPS = ("mbank", "prepare", "obfuscate", "pack", "clean", "vue")
is_windows = platform.system() == "Windows" is_windows = platform.system() == "Windows"
# ── 构建结果数据结构 ───────────────────────────────────────────────────────── # ── 构建结果数据结构 ─────────────────────────────────────────────────────────
@@ -151,15 +169,41 @@ def _ensure_dir(path: str | Path):
Path(path).mkdir(parents=True, exist_ok=True) 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 <step>[,<step>...] [pyinstaller|nuitka]
only_steps 为空表示执行完整构建流程。
"""
args = sys.argv[1:]
mode = PYINSTALLER mode = PYINSTALLER
if len(sys.argv) >= 2: only_steps: set[str] = set()
mode = sys.argv[1].lower() i = 0
if mode not in MODES: while i < len(args):
print(f" ❌ 不支持的构建模式: {mode},可选: {', '.join(MODES)}") arg = args[i]
sys.exit(1) if arg == "--only":
return mode 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) ────────────────────────────────────────── # ── 阶段 1: 模块打包 (module-bank) ──────────────────────────────────────────
@@ -458,10 +502,14 @@ def _stage_build_vue() -> str:
async def main(): async def main():
"""规范化构建主流程""" """规范化构建主流程"""
mode = _resolve_mode() mode, only_steps = _parse_args()
report = BuildReport(mode=mode, start_time=time.time()) report = BuildReport(mode=mode, start_time=time.time())
config = get_config() 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: async def run_step(name: str, fn, *args, **kwargs) -> str:
"""执行一个构建步骤并记录结果(支持同步和异步函数)""" """执行一个构建步骤并记录结果(支持同步和异步函数)"""
start = time.time() start = time.time()
@@ -485,40 +533,48 @@ async def main():
print("\n" + "=" * 60) print("\n" + "=" * 60)
print(" 🏗️ CHONGMING 构建开始") print(" 🏗️ CHONGMING 构建开始")
print(f" 模式: {mode} | 平台: {platform.system()}") print(f" 模式: {mode} | 平台: {platform.system()}")
if only_steps:
print(f" 仅执行步骤: {', '.join(sorted(only_steps))}")
print("=" * 60 + "\n") print("=" * 60 + "\n")
# 阶段 1: 模块打包 # 阶段 1: 模块打包
await run_step("模块打包(module-bank)", _stage_pack_modules, config) if should_run("mbank"):
await run_step("模块打包(module-bank)", _stage_pack_modules, config)
# 阶段 2: 准备构建目录 # 阶段 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: 混淆 + 打包 # 阶段 3+4: 混淆 + 打包
if mode == PYINSTALLER: if should_run("pack"):
await run_step("PyArmor 混淆", _stage_pyarmor_obfuscate) if mode == PYINSTALLER:
start = time.time() if should_run("obfuscate"):
try: await run_step("PyArmor 混淆", _stage_pyarmor_obfuscate)
msg, exe_path = _stage_pyinstaller(config) start = time.time()
elapsed = time.time() - start try:
success = "❌" not in msg msg, exe_path = _stage_pyinstaller(config)
report.add_step( elapsed = time.time() - start
"PyInstaller 打包", success, elapsed, msg.replace("✅ PyInstaller ", "") success = "❌" not in msg
) report.add_step(
print( "PyInstaller 打包", success, elapsed, msg.replace("✅ PyInstaller ", "")
f" {'✅' if success else '❌'} PyInstaller 打包{' ' * 12} {elapsed:>7.2f}s {msg}" )
) print(
except Exception as e: f" {'✅' if success else '❌'} PyInstaller 打包{' ' * 12} {elapsed:>7.2f}s {msg}"
elapsed = time.time() - start )
report.add_step("PyInstaller 打包", False, elapsed, str(e)[:200]) except Exception as e:
print(f" ❌ PyInstaller 打包 {elapsed:>7.2f}s {str(e)[:200]}") elapsed = time.time() - start
else: report.add_step("PyInstaller 打包", False, elapsed, str(e)[:200])
await run_step("Nuitka 编译", lambda: _stage_nuitka(config)[0]) print(f" ❌ PyInstaller 打包 {elapsed:>7.2f}s {str(e)[:200]}")
else:
await run_step("Nuitka 编译", lambda: _stage_nuitka(config)[0])
# 阶段 5: 清理 # 阶段 5: 清理
await run_step("清理临时文件", _stage_cleanup, mode) if should_run("clean"):
await run_step("清理临时文件", _stage_cleanup, mode)
# 阶段 7: Vue 前端构建 # 阶段 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() report.end_time = time.time()