Files
draugnorak/skills/nvgt-engine-dev/scripts/nvgt_lookup.py

121 lines
3.3 KiB
Python
Executable File

#!/usr/bin/env python3
"""Search NVGT docs/includes/bindings in one command."""
from __future__ import annotations
import argparse
import shutil
import subprocess
import sys
from pathlib import Path
SECTIONS = {
"docs": ("doc/src",),
"include-docs": ("doc/src/references/include",),
"builtin-docs": ("doc/src/references/builtin",),
"plugin-docs": ("doc/src/references/plugin",),
"release-includes": ("release/include",),
"bindings": ("src",),
"samples": ("extra/samples",),
}
def run_rg(query: str, roots: list[Path], max_count: int) -> tuple[int, str]:
existing = [str(p) for p in roots if p.exists()]
if not existing:
return 0, ""
cmd = [
"rg",
"-n",
"--hidden",
"--no-ignore",
"--max-count",
str(max_count),
query,
*existing,
]
proc = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
# ripgrep exits 1 when no matches; that is not an error for this tool.
if proc.returncode in (0, 1):
return proc.returncode, proc.stdout.strip()
raise RuntimeError(proc.stderr.strip() or "ripgrep failed")
def resolve_roots(nvgt_root: Path, section: str | None) -> list[tuple[str, list[Path]]]:
if section:
rels = SECTIONS[section]
return [(section, [nvgt_root / rel for rel in rels])]
groups: list[tuple[str, list[Path]]] = []
for key, rels in SECTIONS.items():
groups.append((key, [nvgt_root / rel for rel in rels]))
return groups
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="Search NVGT docs/includes/source quickly.")
parser.add_argument("query", help="Symbol or text to search for")
parser.add_argument(
"--root",
default="",
help="Path to NVGT repository root (auto-discovered if omitted)",
)
parser.add_argument(
"--section",
choices=sorted(SECTIONS.keys()),
help="Limit search to one section",
)
parser.add_argument(
"--max-count",
type=int,
default=50,
help="Maximum matches per section (default: 50)",
)
return parser.parse_args()
def discover_nvgt_root(explicit_root: str) -> Path | None:
if explicit_root:
root = Path(explicit_root).expanduser().resolve()
return root if root.exists() else None
default_root = Path.home() / "git" / "nvgt"
default_resolved = default_root.expanduser().resolve()
if default_resolved.exists():
return default_resolved
return None
def main() -> int:
if shutil.which("rg") is None:
print("Error: ripgrep (rg) is required.", file=sys.stderr)
return 2
args = parse_args()
nvgt_root = discover_nvgt_root(args.root)
if nvgt_root is None:
print(
"Error: NVGT root not found at ~/git/nvgt. Pass --root to override.",
file=sys.stderr,
)
return 2
groups = resolve_roots(nvgt_root, args.section)
any_match = False
for title, roots in groups:
code, output = run_rg(args.query, roots, args.max_count)
if code == 0 and output:
any_match = True
print(f"\n== {title} ==")
print(output)
if not any_match:
print("No matches found.")
return 1
return 0
if __name__ == "__main__":
raise SystemExit(main())