#!/usr/bin/env python3 """一次性补丁脚本:在 apps/pbls/build.sh 第 7 步后插入「7b. 测试前置依赖(DISC.2)」。 为什么用脚本而不是 sed:build.sh 里含 `${...}` 与引号,shell 内嵌补丁容易吃掉转义。 本脚本幂等——已存在 7b 标记时直接退出,不重复插入。 """ import io import os import sys BUILD = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "build.sh") ANCHOR = '# ---- 8. 本地安装 15 个 pbl_* 模块 + 复用模块(可编辑模式)----' MARK = '# ---- 7b. 测试前置依赖(DISC.2)----' BLOCK = '''# ---- 7b. 测试前置依赖(DISC.2)---- # 运行时依赖(requirements.txt)刻意不含 pytest;测试依赖单列 requirements-test.txt, # 由本步装进同一个 venv,使 # source venv/bin/activate && python3 -m pytest tests/test_m5a_idempotency.py -v # 在**不手工注入 PYTHONPATH** 的前提下可直接执行(此前靠 PYTHONPATH=/.pylibs # 临时注入跑通,换机器/换角色即失效,test 角色会误判为环境不可用)。 # 只要运行时依赖的场景(如生产镜像)用 PBL_SKIP_TEST_DEPS=1 显式跳过。 REQ_TEST="${APP_DIR}/requirements-test.txt" if [ "${PBL_SKIP_TEST_DEPS:-0}" = "1" ]; then log "PBL_SKIP_TEST_DEPS=1:跳过测试前置依赖(venv 内将没有 pytest,测试角色需自行引导)" elif [ ! -f "${REQ_TEST}" ]; then die "缺测试依赖清单 ${REQ_TEST}(DISC.2 要求显式声明;确要跳过请设 PBL_SKIP_TEST_DEPS=1)" else log "安装测试前置依赖: ${REQ_TEST}" "${PY}" -m pip install -r "${REQ_TEST}" # 自证:装完必须真能 import + 跑 --version,否则本步等于没做(不让注释与事实矛盾) "${PY}" -c 'import pytest' >/dev/null 2>&1 \\ || die "安装后 venv 内仍无法 import pytest(${PY})" log "7b 自证通过: $("${PY}" -m pytest --version 2>&1 | head -1) @ ${PY}" fi ''' def main(): build = os.path.abspath(BUILD) with io.open(build, "r", encoding="utf-8") as f: text = f.read() if MARK in text: print("SKIP: 7b 已存在,未重复插入") return 0 if ANCHOR not in text: print("FAIL: 找不到第 8 步锚点,拒绝盲目修改") return 1 patched = text.replace(ANCHOR, BLOCK + ANCHOR, 1) with io.open(build, "w", encoding="utf-8") as f: f.write(patched) print("OK: 已在 %s 第 8 步前插入 7b(+%d 字符)" % (build, len(patched) - len(text))) return 0 if __name__ == "__main__": sys.exit(main())