pbl_blueprint/tools/patch_m1b_init.py
2026-09-16 17:17:53 +08:00

132 lines
5.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
"""M1b 补丁脚本 2/2init.py 的 env 注册(三处同步第三环)。
patch_m1b.py 已完成 m1b_init.py 与 __init__.py本脚本只改 init.py可重复执行——
已打过补丁时检测到锚点缺失即跳过并报告,不重复插入。)
执行python3 tools/patch_m1b_init.py
"""
import io
import os
REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
P = os.path.join(REPO, "pbl_blueprint", "init.py")
def read(p):
with io.open(p, "r", encoding="utf-8") as f:
return f.read()
def write(p, s):
with io.open(p, "w", encoding="utf-8") as f:
f.write(s)
print("WROTE %s (%d chars)" % (os.path.relpath(p, REPO), len(s)))
t = read(P)
if "M1B_TABLE_NAMES" in t:
print("SKIP: init.py 已含 M1b 注册(幂等,不重复打补丁)")
raise SystemExit(0)
# ---- 1) import + 表清单
old = ('MODULE_NAME = "pbl_blueprint"\n'
'TABLE_NAMES = list(_tables.TABLES.keys()) # 11 表\n'
'SUBOBJECT_TYPES = _tables.SUBOBJECT_TYPES # 7 类\n')
new = ('from . import m1b_init as _m1b_init\n'
'from .m1b_api import M1B_ROUTES, register_m1b_routes\n'
'from .m1b_init import (M1B_CRUD_FILES, M1B_DDL, M1B_MODEL_FILES, M1B_TABLES,\n'
' ensure_m1b_tables, init_m1b, load_m1b_crud_defs,\n'
' load_m1b_models, seed_platform_data)\n'
'\n'
'MODULE_NAME = "pbl_blueprint"\n'
'TABLE_NAMES = list(_tables.TABLES.keys()) # M1a 11 表\n'
'SUBOBJECT_TYPES = _tables.SUBOBJECT_TYPES # 7 类\n'
'M1B_TABLE_NAMES = list(M1B_TABLES) # M1b 4 表\n'
'ALL_TABLE_NAMES = TABLE_NAMES + [x for x in M1B_TABLE_NAMES\n'
' if x not in TABLE_NAMES]\n')
assert t.count(old) == 1, "anchor1 not unique: %d" % t.count(old)
t = t.replace(old, new)
# ---- 2) __all__
old = ('__all__ = [\n'
' "load_pbl_blueprint", "ensure_tables", "MODULE_NAME", "TABLE_NAMES",\n'
' "SUBOBJECT_TYPES", "BUILTIN_SCHEMA",')
new = ('__all__ = [\n'
' "load_pbl_blueprint", "ensure_tables", "MODULE_NAME", "TABLE_NAMES",\n'
' "SUBOBJECT_TYPES", "BUILTIN_SCHEMA",\n'
' # ---- M1b 三处同步之「init.py env 注册」环节\n'
' "M1B_TABLES", "M1B_TABLE_NAMES", "ALL_TABLE_NAMES", "M1B_MODEL_FILES",\n'
' "M1B_CRUD_FILES", "M1B_DDL", "M1B_ROUTES",\n'
' "init_m1b", "ensure_m1b_tables", "register_m1b_routes",\n'
' "load_m1b_models", "load_m1b_crud_defs", "seed_platform_data",')
assert t.count(old) == 1, "anchor2 not unique: %d" % t.count(old)
t = t.replace(old, new)
# ---- 3) load_pbl_blueprintM1b 挂载 + env 注册
old = ('def load_pbl_blueprint(app=None, sor=None, ensure=False, **kw):\n'
' dbname = get_module_dbname(_MODULE_NAME) # noqa: F841 库名由应用注入\n'
' if ensure:\n'
' ensure_tables(sor)\n'
' if app is not None:\n'
' try:\n'
' app.register_module(MODULE_NAME, {\n'
' "tables": TABLE_NAMES,')
new = ('def _m1b_register_callback(app):\n'
' """解析应用层路由注册回调register_route / register / route / add_route 四选一。"""\n'
' if app is None:\n'
' return None\n'
' for name in ("register_route", "register", "route", "add_route"):\n'
' fn = getattr(app, name, None)\n'
' if callable(fn):\n'
' return fn\n'
' return None\n'
'\n'
'\n'
'def load_pbl_blueprint(app=None, sor=None, ensure=False, **kw):\n'
' dbname = get_module_dbname(_MODULE_NAME) # noqa: F841 库名由应用注入\n'
' if ensure:\n'
' ensure_tables(sor)\n'
'\n'
' # -------------------------------------------------------- M1b 挂载\n'
' # 三处同步m1b_api.register_m1b_routes定义+ __init__.py导出+ 此处env 注册)\n'
' # Q-OPEN-3init_m1b 只建 M1b 自有 4 表,绝不触碰 world/scene/entity/script 基表。\n'
' m1b_result = {"ok": False, "skipped": True}\n'
' if kw.get("m1b", True):\n'
' try:\n'
' m1b_result = init_m1b(\n'
' db=kw.get("m1b_db"),\n'
' env=kw.get("env"),\n'
' register=_m1b_register_callback(app),\n'
' executor=kw.get("m1b_executor"),\n'
' seed=bool(kw.get("m1b_seed", ensure)),\n'
' )\n'
' except Exception as e: # M1b 失败不拖垮 M1a 挂载\n'
' m1b_result = {"ok": False,\n'
' "error": "%s: %s" % (type(e).__name__, e)}\n'
'\n'
' if app is not None:\n'
' try:\n'
' app.register_module(MODULE_NAME, {\n'
' "tables": ALL_TABLE_NAMES,\n'
' "m1b": {\n'
' "tables": M1B_TABLE_NAMES,\n'
' "model_files": M1B_MODEL_FILES,\n'
' "crud_files": M1B_CRUD_FILES,\n'
' "ddl": M1B_DDL,\n'
' "routes": [(m, p) for m, p, _ in M1B_ROUTES],\n'
' "init": m1b_result,\n'
' },')
assert t.count(old) == 1, "anchor3 not unique: %d" % t.count(old)
t = t.replace(old, new)
# ---- 4) 返回值
old = (' return {"module": MODULE_NAME, "tables": TABLE_NAMES,\n'
' "subobject_types": list(SUBOBJECT_TYPES), "loaded": True}')
new = (' return {"module": MODULE_NAME, "tables": TABLE_NAMES,\n'
' "m1b_tables": M1B_TABLE_NAMES, "m1b": m1b_result,\n'
' "subobject_types": list(SUBOBJECT_TYPES), "loaded": True}')
assert t.count(old) == 1, "anchor4 not unique: %d" % t.count(old)
t = t.replace(old, new)
write(P, t)
print("PATCH init.py OK")