Ctrl K
ComunidadGuías…

scripts/build_subpackages.py

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
"""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()