Add analyzers, reporters, and utilities
Some checks failed
CI / test (push) Has been cancelled

This commit is contained in:
2026-02-04 14:57:54 +00:00
parent 6b9e2e48ce
commit d1ccbceca4

View File

@@ -0,0 +1,92 @@
"""JSON reporter for CI/CD integration."""
import json
from typing import Any, Optional
from depcheck.config import Config
from depcheck.models import ScanResult, Severity
class JSONReporter:
"""Report results in JSON format for CI/CD pipelines."""
def __init__(self, config: Optional[Config] = None):
self.config = config or Config()
def report(self, result: ScanResult) -> str:
"""Generate JSON report."""
report_data = self._build_report(result)
return json.dumps(report_data, indent=2)
def _build_report(self, result: ScanResult) -> dict[str, Any]:
"""Build report dictionary."""
highest_severity = result.get_highest_severity()
report: dict[str, Any] = {
"summary": {
"status": "success" if result.outdated_count == 0 and result.vulnerable_count == 0 else "issues_found",
"dependencies_scanned": len(result.dependencies),
"outdated_packages": result.outdated_count,
"vulnerabilities": result.vulnerable_count,
"highest_severity": highest_severity.value if highest_severity else None,
},
"dependencies": [],
"vulnerabilities": [],
"errors": result.scan_errors,
}
for dep in result.dependencies:
dep_data = {
"name": dep.name,
"current_version": dep.current_version,
"latest_version": dep.latest_version,
"is_outdated": dep.is_outdated,
"package_manager": dep.package_manager.value,
"category": dep.category,
"source_file": dep.source_file,
}
report["dependencies"].append(dep_data)
for dep, vuln in result.vulnerabilities:
vuln_data = {
"package": dep.name,
"current_version": dep.current_version,
"cve_id": vuln.cve_id,
"severity": vuln.severity.value,
"description": vuln.description,
"affected_versions": vuln.affected_versions,
"fixed_version": vuln.fixed_version,
"references": vuln.references,
}
report["vulnerabilities"].append(vuln_data)
return report
def get_exit_code(self, result: ScanResult) -> int:
"""Determine exit code based on results."""
if result.scan_errors:
return 2
highest_severity = result.get_highest_severity()
if not highest_severity:
return 0
severity_order = [Severity.CRITICAL, Severity.HIGH, Severity.MEDIUM, Severity.LOW]
threshold = self.config.fail_level
try:
threshold_index = severity_order.index(threshold)
except ValueError:
threshold_index = 2
if highest_severity in severity_order[:threshold_index + 1]:
return 1
return 0
def print_error(self, message: str) -> None:
"""Print error message (for CLI output)."""
print(f"ERROR: {message}")
def print_warning(self, message: str) -> None:
"""Print warning message (for CLI output)."""
print(f"WARNING: {message}")