103 lines
3.0 KiB
Python
103 lines
3.0 KiB
Python
#!/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())
|