Initial upload with CI/CD workflow

This commit is contained in:
2026-01-30 22:12:51 +00:00
parent 280547de53
commit 591edf97f4

View File

@@ -0,0 +1,118 @@
"""JSON export module for CodeSnap."""
import json
from dataclasses import asdict, dataclass
from datetime import datetime
from pathlib import Path
from typing import Any, Optional
from ..core.extractor import ClassInfo, ExtractedCode, FunctionInfo
@dataclass
class FileSummary:
"""Summary information for a file."""
path: str
language: str
function_count: int
class_count: int
complexity: str
line_count: int
@dataclass
class CodeSummary:
"""Complete code summary for export."""
timestamp: str
version: str
directory: str
file_count: int
language_breakdown: dict[str, int]
files: list[dict[str, Any]]
dependencies: dict[str, list[str]]
metrics: dict[str, Any]
class JSONExporter:
"""Exports code summaries in JSON format."""
def __init__(self, version: str = "0.1.0") -> None:
self.version = version
def export(
self,
extracted_files: list[ExtractedCode],
file_paths: list[Path],
dependency_data: dict[str, Any],
complexity_data: dict[str, str],
output_path: Optional[Path] = None,
) -> str:
"""Export code summary to JSON."""
language_counts: dict[str, int] = {}
file_summaries: list[dict[str, Any]] = []
for extracted in extracted_files:
lang = extracted.language
language_counts[lang] = language_counts.get(lang, 0) + 1
file_summary = {
"path": str(extracted.file_path),
"language": lang,
"functions": [
{
"name": f.name,
"start_line": f.start_line,
"end_line": f.end_line,
"parameters": f.parameters,
"return_type": f.return_type,
"is_method": f.is_method,
"class_name": f.class_name,
}
for f in extracted.functions
],
"classes": [
{
"name": c.name,
"start_line": c.start_line,
"end_line": c.end_line,
"methods": [m.name for m in c.methods],
"base_classes": c.base_classes,
}
for c in extracted.classes
],
"complexity": complexity_data.get(str(extracted.file_path), "unknown"),
}
file_summaries.append(file_summary)
dependencies: dict[str, list[str]] = {}
for dep in dependency_data.get("dependencies", []):
source = str(dep.source)
target = str(dep.target)
if source not in dependencies:
dependencies[source] = []
dependencies[source].append(target)
summary = CodeSummary(
timestamp=datetime.utcnow().isoformat() + "Z",
version=self.version,
directory=str(file_paths[0].parent) if file_paths else "",
file_count=len(file_summaries),
language_breakdown=language_counts,
files=file_summaries,
dependencies=dependencies,
metrics={
"total_functions": sum(len(f.functions) for f in extracted_files),
"total_classes": sum(len(f.classes) for f in extracted_files),
"cycles_found": len(dependency_data.get("cycles", [])),
"orphaned_files": len(dependency_data.get("orphaned", [])),
},
)
result = asdict(summary)
if output_path:
output_path.write_text(json.dumps(result, indent=2), encoding="utf-8")
return json.dumps(result, indent=2)