mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-08-30 04:27:40 +08:00
126 lines
3.4 KiB
Python
126 lines
3.4 KiB
Python
#!/usr/bin/env python3
|
|
"""生成并校验 ``app.schemas`` 根入口的惰性导出清单。"""
|
|
|
|
import argparse
|
|
import importlib
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
PROJECT_ROOT = Path(__file__).resolve().parents[2]
|
|
if str(PROJECT_ROOT) not in sys.path:
|
|
sys.path.insert(0, str(PROJECT_ROOT))
|
|
OUTPUT_PATH = PROJECT_ROOT / "app" / "schemas" / "exports.py"
|
|
SCHEMA_MODULES = (
|
|
"agent",
|
|
"cache",
|
|
"category",
|
|
"common",
|
|
"context",
|
|
"dashboard",
|
|
"download",
|
|
"event",
|
|
"exception",
|
|
"file",
|
|
"history",
|
|
"llm",
|
|
"mediaserver",
|
|
"message",
|
|
"mfa",
|
|
"music",
|
|
"monitoring",
|
|
"notification",
|
|
"plugin",
|
|
"response",
|
|
"rule",
|
|
"search",
|
|
"storage",
|
|
"openai",
|
|
"servarr",
|
|
"servcookie",
|
|
"site",
|
|
"subscribe",
|
|
"system",
|
|
"tmdb",
|
|
"token",
|
|
"transfer",
|
|
"user",
|
|
"workflow",
|
|
"mcp",
|
|
)
|
|
|
|
|
|
def collect_exports() -> tuple[dict[str, tuple[str, str]], dict[str, list[str]]]:
|
|
"""按旧星号导入顺序收集最终导出所有者和重名来源。"""
|
|
exports: dict[str, tuple[str, str]] = {}
|
|
sources: dict[str, list[str]] = {}
|
|
for module_basename in SCHEMA_MODULES:
|
|
module_name = f"app.schemas.{module_basename}"
|
|
module = importlib.import_module(module_name)
|
|
names = getattr(module, "__all__", None)
|
|
if names is None:
|
|
names = [name for name in vars(module) if not name.startswith("_")]
|
|
for name in names:
|
|
if not hasattr(module, name):
|
|
continue
|
|
exports[name] = (module_name, name)
|
|
sources.setdefault(name, []).append(module_name)
|
|
conflicts = {
|
|
name: module_names
|
|
for name, module_names in sources.items()
|
|
if len(set(module_names)) > 1
|
|
}
|
|
return dict(sorted(exports.items())), dict(sorted(conflicts.items()))
|
|
|
|
|
|
def render_manifest() -> str:
|
|
"""把导出与冲突清单渲染为稳定、可审查的 Python 模块。"""
|
|
exports, conflicts = collect_exports()
|
|
lines = [
|
|
'"""由 scripts/schema/exports.py 生成,请勿手工编辑。"""',
|
|
"",
|
|
"SCHEMA_EXPORTS = {",
|
|
]
|
|
lines.extend(
|
|
f" {name!r}: ({module_name!r}, {symbol_name!r}),"
|
|
for name, (module_name, symbol_name) in exports.items()
|
|
)
|
|
lines.extend(["}", "", "SCHEMA_CONFLICTS = {"])
|
|
lines.extend(
|
|
f" {name!r}: {module_names!r},"
|
|
for name, module_names in conflicts.items()
|
|
)
|
|
lines.extend(["}", ""])
|
|
return "\n".join(lines)
|
|
|
|
|
|
def parse_args() -> argparse.Namespace:
|
|
"""解析写入或校验动作。"""
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
action = parser.add_mutually_exclusive_group(required=True)
|
|
action.add_argument("--write", action="store_true")
|
|
action.add_argument("--check", action="store_true")
|
|
return parser.parse_args()
|
|
|
|
|
|
def main() -> int:
|
|
"""写入清单,或检查当前 schema 公开面是否发生漂移。"""
|
|
args = parse_args()
|
|
rendered = render_manifest()
|
|
if args.write:
|
|
OUTPUT_PATH.write_text(rendered, encoding="utf-8")
|
|
print(f"已写入 {OUTPUT_PATH.relative_to(PROJECT_ROOT)}")
|
|
return 0
|
|
current = OUTPUT_PATH.read_text(encoding="utf-8")
|
|
if current == rendered:
|
|
return 0
|
|
print(
|
|
"schema 导出清单已变化;确认兼容性后运行 "
|
|
"scripts/schema/exports.py --write",
|
|
)
|
|
return 1
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|