from __future__ import annotations import re from collections.abc import Iterable from gitea_codex_bot.types import ParsedCommand PREFIX_RE = re.compile(r"^@([^\s]+)\s+(.+)$", re.IGNORECASE | re.DOTALL) HELP_ALIASES = {"-h", "--help", "help"} SUPPORTED_COMMANDS = {"review", "explain", "fix", "ignore", "rerun"} def parse_command(body: str, aliases: Iterable[str] | None = None) -> ParsedCommand | None: stripped = body.strip() match = PREFIX_RE.match(stripped) if not match: return None command_alias = match.group(1).lstrip("@").lower() allowed_aliases = {alias.lstrip("@").lower() for alias in (aliases or {"codex"})} if command_alias not in allowed_aliases: return None remainder = match.group(2).strip() if not remainder: return None parts = remainder.split(maxsplit=1) raw_name = parts[0].lower() rest = parts[1].strip() if len(parts) > 1 else "" if raw_name in HELP_ALIASES: return ParsedCommand(name="help", raw=stripped, arguments=[token for token in rest.split() if token]) if raw_name not in SUPPORTED_COMMANDS: return None name = raw_name tokens = [token for token in rest.split() if token] parsed = ParsedCommand(name=name, raw=stripped, arguments=tokens) if name == "review": if "--full" in tokens: parsed.full = True parsed.mode = "full" parsed.mode_explicit = True for mode in ("security", "performance", "tests"): if mode in tokens: parsed.mode = mode parsed.mode_explicit = True break elif name == "fix": parsed.branch_fix = "--branch" in tokens return parsed