Files
workbuddy_skills/product-planning/scripts/selftest_product_root.py
T

99 lines
3.6 KiB
Python
Raw Normal View History

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""产品根定位自检:造临时夹具验 `_common.find_product_root()` 的三态行为。
为什么要有它:目录口径换成「工作区根 / 项目 / 产品根{产品规划, 产品原型{designs, pages}}」之后,
**认错产品根**会让产物落到别的产品目录下(事后极难拆干净)。
本脚本只造临时夹具、**绝不碰任何真实工作区**,跑完自动清理。
用法:
python scripts/selftest_product_root.py
退出码:0 = 全过;1 = 有用例没过。
"""
import importlib.util
import io
import os
import shutil
import sys
import tempfile
try:
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
except Exception:
pass
SK = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
COMMON = os.path.join(SK, "references", "stage-delivery", "scripts", "_common.py")
def load_common():
spec = importlib.util.spec_from_file_location("_sm_common", COMMON)
mod = importlib.util.module_from_spec(spec)
sys.modules["_sm_common"] = mod
spec.loader.exec_module(mod)
return mod
def mkproot(p):
"""按新结构造一个产品根:产品规划/ + 产品原型/{designs,pages}/"""
for d in ("产品规划",
os.path.join("产品原型", "designs"),
os.path.join("产品原型", "pages")):
os.makedirs(os.path.join(p, d), exist_ok=True)
def main():
C = load_common()
fix = tempfile.mkdtemp(prefix="proot-selftest-")
out = []
def build_single():
mkproot(os.path.join(fix, "ws1", "项目", "only"))
def build_multi(pointer=""):
for nm in ("a", "b"):
mkproot(os.path.join(fix, "ws2", "项目", nm))
reg = os.path.join(fix, "ws2", ".registry")
os.makedirs(reg, exist_ok=True)
if pointer:
io.open(os.path.join(reg, "current-project"), "w", encoding="utf-8").write(pointer)
cases = [
("单产品·给工作区根", build_single, os.path.join(fix, "ws1"),
os.path.join(fix, "ws1", "项目", "only")),
("单产品·给产品根本身", build_single, os.path.join(fix, "ws1", "项目", "only"),
os.path.join(fix, "ws1", "项目", "only")),
("单产品·从子目录向上认", build_single,
os.path.join(fix, "ws1", "项目", "only", "产品原型", "pages"),
os.path.join(fix, "ws1", "项目", "only")),
("多产品·无指针·不许猜", build_multi, os.path.join(fix, "ws2"), ""),
("多产品·有指针·认指针", lambda: build_multi("b"), os.path.join(fix, "ws2"),
os.path.join(fix, "ws2", "项目", "b")),
]
try:
nfail = 0
for name, build, arg, expect in cases:
shutil.rmtree(fix, ignore_errors=True)
os.makedirs(fix, exist_ok=True)
build()
got = C.find_product_root(arg)
ok = os.path.normcase(os.path.abspath(got)) == os.path.normcase(os.path.abspath(expect))
out.append("%s %-26s 期望=%s | 实得=%s" % (
"[过]" if ok else "[FAIL]", name,
os.path.relpath(expect, fix) if expect else "(空)",
os.path.relpath(got, fix) if got else "(空)"))
if not ok:
nfail += 1
finally:
shutil.rmtree(fix, ignore_errors=True)
for line in out:
print(line)
print()
print("小计:%d / %d 过" % (len(cases) - nfail, len(cases)))
print("✅ 产品根定位全过。" if not nfail else "⛔ 有用例没过 —— 先修定位再跑流水线。")
return 0 if not nfail else 1
if __name__ == "__main__":
sys.exit(main())