blob: a39862734e3e6918d04839b2981f49f1e549db47 [file]
#!/usr/bin/env python3
"""Prepare the AGENTS.md guide list for automated PR review prompts."""
from __future__ import annotations
import argparse
from pathlib import Path, PurePosixPath
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"--changed-files",
required=True,
type=Path,
help="Newline-delimited PR changed file paths.",
)
parser.add_argument(
"--required-agents",
required=True,
type=Path,
help="Output file containing one required AGENTS.md path per line.",
)
parser.add_argument(
"--prompt-block",
required=True,
type=Path,
help="Output file containing the bullet list inserted into the review prompt.",
)
parser.add_argument(
"--repo-root",
default=Path("."),
type=Path,
help="Repository root. Defaults to the current working directory.",
)
return parser.parse_args()
def valid_changed_path(path: str) -> PurePosixPath | None:
value = path.strip()
if not value:
return None
candidate = PurePosixPath(value)
if candidate.is_absolute() or ".." in candidate.parts:
raise ValueError(f"Changed file path escapes the repository: {path!r}")
return candidate
def add_if_present(repo_root: Path, agents: list[str], seen: set[str], path: PurePosixPath) -> None:
text_path = path.as_posix()
if text_path in seen:
return
if (repo_root / Path(text_path)).is_file():
agents.append(text_path)
seen.add(text_path)
def required_agents(repo_root: Path, changed_files: list[PurePosixPath]) -> list[str]:
agents: list[str] = []
seen: set[str] = set()
add_if_present(repo_root, agents, seen, PurePosixPath("AGENTS.md"))
for changed_file in changed_files:
for index in range(1, len(changed_file.parts)):
directory = PurePosixPath(*changed_file.parts[:index])
add_if_present(repo_root, agents, seen, directory / "AGENTS.md")
return agents
def main() -> None:
args = parse_args()
repo_root = args.repo_root.resolve()
changed_files = [
path
for path in (valid_changed_path(line) for line in args.changed_files.read_text().splitlines())
if path is not None
]
agents = required_agents(repo_root, changed_files)
args.required_agents.write_text("".join(f"{path}\n" for path in agents))
if agents:
args.prompt_block.write_text("".join(f"- {path}\n" for path in agents))
else:
args.prompt_block.write_text("- No AGENTS.md files were found for the changed file ancestors.\n")
if __name__ == "__main__":
main()