mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
f48c4512d3
* updated automation tasks and commands, with alias for the time being * Restore aggregate test exclusions Preserve the legacy all-tests scope for test --all by excluding lab and devui from the default aggregate sweep, while still allowing explicit package selection. Also ignore hidden/generated test directories such as .mypy_cache during aggregate discovery. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * updated versions in pre-commit --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
119 lines
4.1 KiB
Python
119 lines
4.1 KiB
Python
# Copyright (c) Microsoft. All rights reserved.
|
|
# ruff: noqa: S603
|
|
|
|
"""Add a dependency to one workspace package selected by short name or path.
|
|
|
|
``uv add --package`` expects the published workspace distribution name, while
|
|
the root Poe surface intentionally speaks in short repo package names such as
|
|
``core``. This wrapper keeps the user-facing selector stable and translates it
|
|
just before delegating to uv.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import subprocess
|
|
from dataclasses import dataclass
|
|
from pathlib import Path
|
|
|
|
import tomli
|
|
from rich import print
|
|
|
|
from scripts.task_runner import discover_projects, project_filter_matches
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class WorkspacePackage:
|
|
"""Workspace package metadata needed for `uv add --package`."""
|
|
|
|
short_name: str
|
|
project_path: Path
|
|
distribution_name: str
|
|
|
|
|
|
def _load_distribution_name(pyproject_file: Path) -> str:
|
|
with pyproject_file.open("rb") as f:
|
|
data = tomli.load(f)
|
|
return str(data.get("project", {}).get("name", "")).strip()
|
|
|
|
|
|
def _discover_workspace_packages(workspace_root: Path) -> list[WorkspacePackage]:
|
|
workspace_pyproject = workspace_root / "pyproject.toml"
|
|
packages: list[WorkspacePackage] = []
|
|
for project_path in sorted(discover_projects(workspace_pyproject), key=str):
|
|
pyproject_file = workspace_root / project_path / "pyproject.toml"
|
|
if not pyproject_file.exists():
|
|
continue
|
|
distribution_name = _load_distribution_name(pyproject_file)
|
|
if not distribution_name:
|
|
continue
|
|
packages.append(
|
|
WorkspacePackage(
|
|
short_name=project_path.name,
|
|
project_path=project_path,
|
|
distribution_name=distribution_name,
|
|
)
|
|
)
|
|
return packages
|
|
|
|
|
|
def _resolve_workspace_package(workspace_root: Path, project_filter: str) -> WorkspacePackage:
|
|
"""Resolve one workspace package from a user-facing selector.
|
|
|
|
The wrapper accepts the same short-name/path/distribution-name vocabulary as
|
|
the other root tasks, but errors on ambiguous matches so dependency edits
|
|
never hit the wrong package.
|
|
"""
|
|
matches = [
|
|
package
|
|
for package in _discover_workspace_packages(workspace_root)
|
|
if project_filter_matches(package.project_path, project_filter, [package.short_name, package.distribution_name])
|
|
]
|
|
if not matches:
|
|
raise SystemExit(f"No workspace package matched selector '{project_filter}'.")
|
|
if len(matches) > 1:
|
|
names = ", ".join(sorted(package.short_name for package in matches))
|
|
raise SystemExit(
|
|
f"Package selector '{project_filter}' matched multiple workspace packages: {names}. "
|
|
"Use a more specific short name or path."
|
|
)
|
|
return matches[0]
|
|
|
|
|
|
def main() -> None:
|
|
"""Resolve a workspace project selector, then delegate to `uv add`."""
|
|
parser = argparse.ArgumentParser(
|
|
description="Add a dependency to a single workspace package selected by short name, path, or package name."
|
|
)
|
|
parser.add_argument(
|
|
"-P",
|
|
"--package",
|
|
dest="project",
|
|
metavar="PACKAGE",
|
|
required=True,
|
|
help="Workspace package selector, such as `core`.",
|
|
)
|
|
# Keep the old long flag as a silent alias while downstream automation
|
|
# finishes moving to the user-facing ``--package`` spelling.
|
|
parser.add_argument("--project", dest="project", help=argparse.SUPPRESS)
|
|
parser.add_argument("-D", "--dependency", required=True, help="Dependency specifier to add.")
|
|
args = parser.parse_args()
|
|
|
|
workspace_root = Path(__file__).resolve().parents[2]
|
|
package = _resolve_workspace_package(workspace_root, args.project)
|
|
print(
|
|
f"[cyan]Adding {args.dependency} to {package.short_name} "
|
|
f"({package.distribution_name})[/cyan]"
|
|
)
|
|
result = subprocess.run(
|
|
["uv", "add", "--package", package.distribution_name, args.dependency],
|
|
cwd=workspace_root,
|
|
check=False,
|
|
)
|
|
if result.returncode:
|
|
raise SystemExit(result.returncode)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|