42 lines
2.3 KiB
Python
42 lines
2.3 KiB
Python
"""Validate the authoring resources in staged, installed, or archived runtime wheels."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import re
|
|
import stat
|
|
import zipfile
|
|
from pathlib import Path
|
|
|
|
|
|
def validate_resources(root: Path | zipfile.Path, target: str) -> None:
|
|
"""Reject a missing or wrong-target Python environment or bundled Office skill tree."""
|
|
manifest_path = root / "primary-runtime/runtime.json"
|
|
if not manifest_path.is_file():
|
|
raise FileNotFoundError(f"runtime authoring resources are missing: {manifest_path}")
|
|
manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
|
|
platform, arch = target.rsplit("-", 1)
|
|
platform = {"macos": "darwin", "win": "win32"}.get(platform, platform)
|
|
if not isinstance(manifest, dict) or (manifest.get("platform"), manifest.get("arch")) != (platform, arch):
|
|
raise ValueError(f"runtime authoring resources do not match target {target}")
|
|
version = manifest.get("python")
|
|
if not isinstance(version, str) or not re.fullmatch(r"\d+\.\d+\.\d+", version):
|
|
raise ValueError("runtime authoring resources have invalid Python version metadata")
|
|
if not isinstance(manifest.get("pythonPackages"), dict) or not manifest["pythonPackages"]:
|
|
raise ValueError("runtime authoring resources have no Python distributions")
|
|
python_root = root / "primary-runtime/dependencies/python"
|
|
executable = python_root / ("python.exe" if platform == "win32" else "bin/python3")
|
|
packages = python_root / ("Lib/site-packages" if platform == "win32" else f"lib/python{version.rsplit('.', 1)[0]}/site-packages")
|
|
required = [executable, root / "office-skills/scripts/check_office.py"]
|
|
required.extend(root / f"office-skills/office-{kind}/SKILL.md" for kind in ("docx", "pptx", "xlsx"))
|
|
for path in required:
|
|
if not path.is_file():
|
|
raise FileNotFoundError(f"runtime authoring resource is missing: {path}")
|
|
if not packages.is_dir():
|
|
raise FileNotFoundError(f"runtime Python site-packages is missing: {packages}")
|
|
if platform != "win32":
|
|
mode = (executable.root.getinfo(executable.at).external_attr >> 16
|
|
if isinstance(executable, zipfile.Path) else executable.stat().st_mode)
|
|
if mode & stat.S_IXUSR == 0:
|
|
raise ValueError(f"runtime Python lost its executable bit: {executable}")
|