56 lines
1.5 KiB
Python
56 lines
1.5 KiB
Python
from __future__ import annotations
|
|
|
|
import json
|
|
from collections.abc import Iterable
|
|
from dataclasses import dataclass
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class Finding:
|
|
file: str
|
|
hunk: str
|
|
snippet: str
|
|
message: str
|
|
label: str
|
|
|
|
def key(self) -> tuple[str, str, str, str, str]:
|
|
return (self.file, self.hunk, self.snippet, self.message, self.label)
|
|
|
|
|
|
def dedupe_findings(findings: Iterable[Finding]) -> list[Finding]:
|
|
seen = set()
|
|
unique: list[Finding] = []
|
|
for item in findings:
|
|
key = item.key()
|
|
if key in seen:
|
|
continue
|
|
seen.add(key)
|
|
unique.append(item)
|
|
return unique
|
|
|
|
|
|
def render_json(findings: Iterable[Finding]) -> str:
|
|
payload = {"findings": [item.__dict__ for item in findings]}
|
|
return json.dumps(payload, indent=2, sort_keys=True) + "\n"
|
|
|
|
|
|
def render_markdown(findings: Iterable[Finding]) -> str:
|
|
items = list(findings)
|
|
if not items:
|
|
return "# Review Report\n\nNo findings.\n"
|
|
|
|
lines: list[str] = ["# Review Report", ""]
|
|
for idx, item in enumerate(items, start=1):
|
|
lines.append(f"## Finding {idx}")
|
|
lines.append(f"- File: {item.file}")
|
|
lines.append(f"- Hunk: {item.hunk}")
|
|
lines.append(f"- Label: {item.label}")
|
|
lines.append("- Snippet:")
|
|
lines.append("```")
|
|
lines.append(item.snippet.rstrip())
|
|
lines.append("```")
|
|
lines.append("")
|
|
lines.append(item.message)
|
|
lines.append("")
|
|
return "\n".join(lines).rstrip() + "\n"
|