#!/usr/bin/env python3 """ Собрать sdist (.tar.gz) из vendor/wheels в готовые .whl на build-машине. pip download иногда кладёт zeroconf как исходники (нет готового wheel под Python/arch). Офлайн pip install на терминале не должен тянуть Cython с PyPI — wheel собирается здесь. """ from __future__ import annotations import argparse import subprocess import sys from pathlib import Path ROOT = Path(__file__).resolve().parent.parent # PEP 517 build deps для zeroconf и похожих sdists в requirements-prod. SDIST_BUILD_DEPS = ( "Cython>=3.0.8", "setuptools>=61", "wheel", "packaging", ) def materialize_sdists(wheels_dir: Path, python_exe: str) -> list[str]: """Собрать каждый .tar.gz в wheels_dir → .whl, удалить sdist. Возвращает имена .whl.""" sdists = sorted(wheels_dir.glob("*.tar.gz")) if not sdists: return [] subprocess.run( [ python_exe, "-m", "pip", "download", *SDIST_BUILD_DEPS, "-d", str(wheels_dir), ], check=True, ) built: list[str] = [] for sdist in sdists: before = {p.name for p in wheels_dir.glob("*.whl")} subprocess.run( [ python_exe, "-m", "pip", "wheel", str(sdist.resolve()), "-w", str(wheels_dir), "--no-deps", f"--find-links={wheels_dir}", "--no-cache-dir", ], check=True, ) after = {p.name for p in wheels_dir.glob("*.whl")} new_wheels = sorted(after - before) if not new_wheels: raise RuntimeError( f"pip wheel не создал .whl для {sdist.name} в {wheels_dir}" ) built.extend(new_wheels) sdist.unlink() return built def main() -> int: parser = argparse.ArgumentParser(description="Build wheels from vendor/wheels sdists") parser.add_argument("--wheels", type=Path, default=ROOT / "vendor" / "wheels") parser.add_argument("--python", default=sys.executable) args = parser.parse_args() wheels_dir = args.wheels.resolve() if not wheels_dir.is_dir(): print(f"materialize_wheelhouse_sdists: нет каталога {wheels_dir}", file=sys.stderr) return 1 try: built = materialize_sdists(wheels_dir, args.python) except subprocess.CalledProcessError as exc: print("materialize_wheelhouse_sdists: ошибка сборки wheel", file=sys.stderr) return exc.returncode or 1 if built: print( "materialize_wheelhouse_sdists: собрано wheel из sdist:", ", ".join(built), ) return 0 if __name__ == "__main__": raise SystemExit(main())