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
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 <step>` 可选步骤:`mbank` / `prepare` / `obfuscate` / `pack` / `clean` / `vue`,可逗号分隔或重复传多个。
## 项目根目录定位
脚本需要在项目根目录下读写 `config/`、`src/plugins/`、`workers/` 等路径。
+90 -34
View File
@@ -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 <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
@@ -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 <step>[,<step>...] [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()