master
John Lauer 0.9.340: routing tests, demo runner + evidence (arav-rog 2026-09-07), vendoring and overlay tools, release notes 25dcdaf 2mo ago
"""Rebuild routing_deps/ (the vendored IPC client for the live routing verbs).

Downloads Windows x64 wheels for requirements-routing.txt, one tree per CPython
ABI the bridge may run under (start.bat picks system Python, else KiCad's), and
unpacks them under routing_deps/cp<maj><min>. The tree ships in the release zip
(tools/release_files.json "dirs") and is deliberately not pushed to the page repo.

    python3 tools/vendor_routing_deps.py            # cp311 cp312 cp313
    python3 tools/vendor_routing_deps.py 3.12       # one ABI
"""
import shutil
import subprocess
import sys
import tempfile
import zipfile
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
OUT = ROOT / "routing_deps"
README = """Vendored Python dependencies for the live routing verbs (requirements-routing.txt),
unpacked from Windows x64 wheels, one tree per CPython ABI: cp311, cp312, cp313.
handlers/live_routing.py appends routing_deps/cp<major><minor> to sys.path when it exists.
Other platforms: pip install -r requirements-routing.txt into the bridge's Python.
Rebuild with tools/vendor_routing_deps.py; never edit by hand.
"""


def main():
    versions = sys.argv[1:] or ["3.11", "3.12", "3.13"]
    if OUT.exists():
        shutil.rmtree(OUT)
    OUT.mkdir()
    (OUT / "README.txt").write_text(README)
    for ver in versions:
        tag = "cp" + ver.replace(".", "")
        target = OUT / tag
        target.mkdir()
        with tempfile.TemporaryDirectory() as tmp:
            subprocess.run([sys.executable, "-m", "pip", "download", "-r", str(ROOT / "requirements-routing.txt"),
                            "--platform", "win_amd64", "--python-version", ver, "--implementation", "cp",
                            "--only-binary=:all:", "-d", tmp, "-q"], check=True)
            wheels = sorted(Path(tmp).glob("*.whl"))
            for wheel in wheels:
                with zipfile.ZipFile(wheel) as z:
                    z.extractall(target)
            print(f"{tag}: {len(wheels)} wheels -> {target}")
    print("done:", OUT)


if __name__ == "__main__":
    main()