Add output formatters

This commit is contained in:
2026-02-02 21:35:56 +00:00
parent c8379fc113
commit a84ce8a450

View File

@@ -0,0 +1,159 @@
from __future__ import annotations
from rich.console import Console
from rich.table import Table
from rich.text import Text
from rich import box as rich_box
from depaudit.output import AuditResult, Formatter
SEVERITY_COLORS = {
"critical": "red",
"high": "orange3",
"medium": "yellow",
"low": "blue",
"unknown": "grey",
}
class TableFormatter(Formatter):
def __init__(self, use_color: bool = True, verbosity: str = "info"):
super().__init__(use_color, verbosity)
self.console = Console(force_terminal=use_color, color_system="auto" if use_color else None)
def format(self, result: AuditResult) -> str:
lines = []
summary = result.get_summary()
lines.append("")
lines.append("=" * 60)
lines.append("DepAudit Report")
lines.append("=" * 60)
lines.append(f"Scanned Files: {result.scanned_count}")
lines.append(f"Scan Duration: {result.scan_duration:.2f}s")
lines.append("")
if result.vulnerabilities:
lines.append("[VULNERABILITIES]")
vuln_table = self._create_vulnerability_table(result.vulnerabilities)
lines.append(self._render_table(vuln_table))
if result.outdated:
lines.append("[OUTDATED PACKAGES]")
outdated_table = self._create_outdated_table(result.outdated)
lines.append(self._render_table(outdated_table))
if result.license_issues:
lines.append("[LICENSE ISSUES]")
license_table = self._create_license_table(result.license_issues)
lines.append(self._render_table(license_table))
if result.unused:
lines.append("[UNUSED DEPENDENCIES]")
unused_table = self._create_unused_table(result.unused)
lines.append(self._render_table(unused_table))
if summary["total_vulnerabilities"] > 0:
lines.append("")
lines.append("SEVERITY SUMMARY:")
for severity, count in summary["severity_breakdown"].items():
if count > 0:
color = SEVERITY_COLORS.get(severity, "grey")
lines.append(f" {severity.upper()}: {count}")
lines.append("")
lines.append("=" * 60)
return "\n".join(lines)
def _render_table(self, table: Table) -> str:
from io import StringIO
output = StringIO()
self.console.begin_capture()
self.console.print(table)
captured = self.console.end_capture()
return captured
def _create_vulnerability_table(self, vulnerabilities: list[dict]) -> Table:
table = Table(box=rich_box.SIMPLE, show_header=True, header_style="bold")
table.add_column("Severity", width=10)
table.add_column("Package", width=25)
table.add_column("Current", width=12)
table.add_column("Fixed", width=12)
table.add_column("ID", width=20)
for vuln in vulnerabilities:
severity = vuln.get("severity", "unknown")
color = SEVERITY_COLORS.get(severity, "grey")
table.add_row(
Text(severity.upper(), style=color),
vuln.get("package_name", ""),
vuln.get("current_version", ""),
vuln.get("fixed_version", "") or "N/A",
vuln.get("id", ""),
)
return table
def _create_outdated_table(self, outdated: list[dict]) -> Table:
table = Table(box=rich_box.SIMPLE, show_header=True, header_style="bold")
table.add_column("Package", width=30)
table.add_column("Current", width=15)
table.add_column("Latest", width=15)
table.add_column("Update Type", width=15)
for pkg in outdated:
update_type = []
if pkg.get("major_available"):
update_type.append("major")
if pkg.get("minor_available"):
update_type.append("minor")
if pkg.get("patch_available"):
update_type.append("patch")
table.add_row(
pkg.get("package_name", ""),
pkg.get("current_version", ""),
pkg.get("latest_version", ""),
", ".join(update_type) if update_type else "latest",
)
return table
def _create_license_table(self, issues: list[dict]) -> Table:
table = Table(box=rich_box.SIMPLE, show_header=True, header_style="bold")
table.add_column("Package", width=30)
table.add_column("License", width=20)
table.add_column("Status", width=15)
for issue in issues:
status = issue.get("status", "unknown")
if status == "blocked":
style = "red"
elif status == "allowed":
style = "green"
else:
style = "yellow"
table.add_row(
issue.get("package_name", ""),
issue.get("license", "") or "Unknown",
Text(status, style=style),
)
return table
def _create_unused_table(self, unused: list[dict]) -> Table:
table = Table(box=rich_box.SIMPLE, show_header=True, header_style="bold")
table.add_column("Package", width=30)
table.add_column("Version", width=15)
table.add_column("Reason", width=40)
for item in unused:
table.add_row(
item.get("package_name", ""),
item.get("version", ""),
item.get("reason", ""),
)
return table