104 lines
4.1 KiB
Python
104 lines
4.1 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
EXPECTED_PROJECT_VERSION = "0.4.5"
|
|
EXPECTED_RUNTIME_VERSION = "0.4.5-production-nonrenderable-label-omit"
|
|
EXPECTED_BUILDER = "cm95pbf-builder/0.4.5-nonrenderable-label-omit"
|
|
EXPECTED_INVALIDATE_COUNT = 16
|
|
|
|
|
|
def fail(msg: str) -> None:
|
|
print(f"FAIL: {msg}")
|
|
raise SystemExit(2)
|
|
|
|
|
|
def main() -> None:
|
|
root = Path.cwd()
|
|
pyproject = root / "pyproject.toml"
|
|
init_py = root / "src" / "cm95pbf" / "__init__.py"
|
|
cli_py = root / "src" / "cm95pbf" / "cli.py"
|
|
production_py = root / "src" / "cm95pbf" / "production.py"
|
|
tiles_path = root / "config" / "pbf" / "cm95_v1_4_5_nonrenderable_label_tiles.txt"
|
|
|
|
for path in (pyproject, init_py, cli_py, production_py, tiles_path):
|
|
if not path.exists():
|
|
fail(f"缺少文件: {path}")
|
|
|
|
pyproject_text = pyproject.read_text(encoding="utf-8")
|
|
if f'version = "{EXPECTED_PROJECT_VERSION}"' not in pyproject_text:
|
|
fail(f"pyproject 不是 {EXPECTED_PROJECT_VERSION}")
|
|
|
|
init_text = init_py.read_text(encoding="utf-8")
|
|
if EXPECTED_RUNTIME_VERSION not in init_text:
|
|
fail("src/cm95pbf/__init__.py runtime version 不正确")
|
|
if EXPECTED_BUILDER not in init_text:
|
|
fail("src/cm95pbf/__init__.py builder contract 不正确")
|
|
|
|
cli_text = cli_py.read_text(encoding="utf-8")
|
|
if "--invalidate-tiles-file" not in cli_text:
|
|
fail("CLI 缺少 --invalidate-tiles-file")
|
|
|
|
production_text = production_py.read_text(encoding="utf-8")
|
|
if '"builder_contract_version": BUILDER_CONTRACT_VERSION' not in production_text:
|
|
fail("production plan hash 未纳入 builder_contract_version")
|
|
if "_load_explicit_invalidate_tiles" not in production_text:
|
|
fail("production migration 缺少 explicit invalidate 实现")
|
|
|
|
tiles = []
|
|
for raw in tiles_path.read_text(encoding="utf-8").splitlines():
|
|
line = raw.strip()
|
|
if not line or line.startswith("#"):
|
|
continue
|
|
parts = line.split("/")
|
|
if len(parts) != 3:
|
|
fail(f"非法 invalidate tile: {line}")
|
|
z, x, y = map(int, parts)
|
|
if x < 0 or y < 0 or x >= (1 << z) or y >= (1 << z):
|
|
fail(f"非法 XYZ: {line}")
|
|
tiles.append((z, x, y))
|
|
if len(tiles) != EXPECTED_INVALIDATE_COUNT or len(set(tiles)) != EXPECTED_INVALIDATE_COUNT:
|
|
fail(f"invalidate tile 数量应为 {EXPECTED_INVALIDATE_COUNT},实际 {len(tiles)} / unique {len(set(tiles))}")
|
|
|
|
# Installed/editable runtime check.
|
|
try:
|
|
import cm95pbf
|
|
from cm95pbf.cli import build_parser
|
|
except Exception as exc:
|
|
fail(f"无法 import 已安装 cm95pbf: {exc}")
|
|
|
|
if getattr(cm95pbf, "__version__", None) != EXPECTED_RUNTIME_VERSION:
|
|
fail(f"installed cm95pbf.__version__={getattr(cm95pbf, '__version__', None)!r}")
|
|
if getattr(cm95pbf, "BUILDER_CONTRACT_VERSION", None) != EXPECTED_BUILDER:
|
|
fail(f"installed BUILDER_CONTRACT_VERSION={getattr(cm95pbf, 'BUILDER_CONTRACT_VERSION', None)!r}")
|
|
|
|
parser = build_parser()
|
|
migrate = None
|
|
for action in parser._actions:
|
|
if isinstance(action, argparse._SubParsersAction):
|
|
migrate = action.choices.get("migrate-production-release")
|
|
break
|
|
if migrate is None:
|
|
fail("CLI 缺少 migrate-production-release")
|
|
options = {opt for action in migrate._actions for opt in action.option_strings}
|
|
if "--invalidate-tiles-file" not in options:
|
|
fail("installed CLI parser 未注册 --invalidate-tiles-file")
|
|
|
|
print("CM95 PBF v1.4.5 preflight")
|
|
print("=" * 68)
|
|
print(f"Project version : {EXPECTED_PROJECT_VERSION} PASS")
|
|
print(f"Runtime version : {EXPECTED_RUNTIME_VERSION} PASS")
|
|
print(f"Builder contract : {EXPECTED_BUILDER} PASS")
|
|
print("CLI invalidate option : PASS")
|
|
print(f"Explicit invalidate tiles: {EXPECTED_INVALIDATE_COUNT} PASS")
|
|
print("Plan hash builder binding: PASS")
|
|
print("OVERALL : PASS")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|