scripts/build_subpackages.py
Rama main · réplica de lectura del repositorio original.
"""Build standalone Python packages with the repository's legal files."""
from __future__ import annotations
import argparse
import shutil
import subprocess
import sys
import tempfile
from collections.abc import Iterator, Sequence
from contextlib import contextmanager
from pathlib import Path
REPO_ROOT = Path(__file__).resolve().parents[1]
LEGAL_FILES = ("LICENSE", "NOTICE")
LICENSE_FILES_DECLARATION = 'license-files = ["LICENSE", "NOTICE"]'
PACKAGE_DIRS = {
"omnigent-client": Path("sdks/python-client"),
"omnigent-ui-sdk": Path("sdks/ui"),
"omnigent-slack": Path("integrations/slack"),
}
@contextmanager
def staged_package(package_dir: Path) -> Iterator[Path]:
"""Stage a package beside its source and add the canonical legal files."""
source = (REPO_ROOT / package_dir).resolve()
with tempfile.TemporaryDirectory(prefix=f".{source.name}-build-", dir=source.parent) as tmp:
staged = Path(tmp)
shutil.copytree(
source,
staged,
dirs_exist_ok=True,
ignore=shutil.ignore_patterns(".venv", "__pycache__", ".pytest_cache", "dist"),
)
for filename in LEGAL_FILES:
shutil.copy2(REPO_ROOT / filename, staged / filename)
_declare_license_files(staged / "pyproject.toml")
yield staged
def _declare_license_files(pyproject: Path) -> None:
"""Declare the legal files that exist only in the staged project."""
source = pyproject.read_text(encoding="utf-8")
anchor = 'license = "Apache-2.0"\n'
if source.count(anchor) != 1:
raise ValueError(f"expected one Apache-2.0 license declaration in {pyproject}")
pyproject.write_text(
source.replace(anchor, f"{anchor}{LICENSE_FILES_DECLARATION}\n"), encoding="utf-8"
)
def build_packages(package_names: Sequence[str], out_dir: Path, *, wheel_only: bool) -> None:
"""Build selected packages from temporary, self-contained source trees."""
output = out_dir.resolve()
output.mkdir(parents=True, exist_ok=True)
for package_name in package_names:
with staged_package(PACKAGE_DIRS[package_name]) as staged:
command = [sys.executable, "-m", "build", "--outdir", str(output)]
if wheel_only:
command.append("--wheel")
command.append(str(staged))
subprocess.run(command, cwd=REPO_ROOT, check=True)
def parse_args(argv: Sequence[str] | None = None) -> argparse.Namespace:
"""Parse command-line arguments."""
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("package", nargs="+", choices=PACKAGE_DIRS)
parser.add_argument("--out-dir", type=Path, default=Path("dist"))
parser.add_argument("--wheel", action="store_true", help="Build wheels without sdists")
return parser.parse_args(argv)
def main(argv: Sequence[str] | None = None) -> None:
"""Build the requested standalone packages."""
args = parse_args(argv)
build_packages(args.package, args.out_dir, wheel_only=args.wheel)
if __name__ == "__main__":
main()