from __future__ import annotations import argparse import importlib.util import shutil import subprocess import sys from pathlib import Path from set_version import PYPROJECT_PATH, extract_project_version, write_project_version ROOT = Path(__file__).resolve().parent.parent def parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser(description="Build a wheel for the project.") parser.add_argument("--version", help="Optionally set the project version before building.") parser.add_argument("--outdir", default="dist", help="Directory where the wheel will be written.") parser.add_argument("--no-clean", action="store_true", help="Keep existing build and output directories.") return parser.parse_args() def resolve_output_dir(outdir: str) -> Path: output_dir = Path(outdir) if not output_dir.is_absolute(): output_dir = ROOT / output_dir return output_dir def ensure_build_dependency() -> None: if importlib.util.find_spec("build") is None: raise RuntimeError( 'Missing dependency "build". Install development dependencies with '\ '"python -m pip install -e .[dev]" or install "build" directly.' ) def clean_build_artifacts(output_dir: Path) -> None: for path in (ROOT / "build", output_dir): if path.exists(): shutil.rmtree(path) def build_wheel(output_dir: Path) -> None: command = [ sys.executable, "-m", "build", "--wheel", "--outdir", str(output_dir), ] subprocess.run(command, check=True, cwd=ROOT) def main() -> int: args = parse_args() output_dir = resolve_output_dir(args.outdir) if args.version: previous_version, updated_version = write_project_version(PYPROJECT_PATH, args.version) if previous_version == updated_version: print(f"Version already set to {updated_version}") else: print(f"Updated version: {previous_version} -> {updated_version}") ensure_build_dependency() if not args.no_clean: clean_build_artifacts(output_dir) output_dir.mkdir(parents=True, exist_ok=True) version = extract_project_version(PYPROJECT_PATH.read_text(encoding="utf-8")) print(f"Building wheel for version {version} into {output_dir}") build_wheel(output_dir) wheels = sorted(output_dir.glob("*.whl")) if not wheels: raise RuntimeError("Build completed without producing a wheel file.") for wheel in wheels: print(f"Built wheel: {wheel}") return 0 if __name__ == "__main__": raise SystemExit(main())