fix: resolve CI compilation errors
Some checks failed
CI / test (push) Has been cancelled

This commit is contained in:
2026-02-05 15:36:01 +00:00
parent aa72b301c5
commit 24369c5e4e

View File

@@ -0,0 +1,181 @@
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;
use crate::models::{
AnalysisSummary, ByLanguage, ByPriority, ComplexityDistribution, TechDebtItem,
};
pub struct Exporter;
impl Exporter {
pub fn new() -> Self {
Self
}
pub fn export_json(&self, items: &[TechDebtItem], output: &PathBuf) -> anyhow::Result<()> {
let summary = self.create_summary(items);
let export_data = ExportData {
summary,
items: items.to_vec(),
};
let json = serde_json::to_string_pretty(&export_data)?;
let mut file = File::create(output)?;
file.write_all(json.as_bytes())?;
println!("Exported {} items to {}", items.len(), output.display());
Ok(())
}
pub fn export_markdown(&self, items: &[TechDebtItem], output: &PathBuf) -> anyhow::Result<()> {
let mut content = String::new();
content.push_str("# Technical Debt Report\n\n");
content.push_str(&format!(
"**Generated:** {}\n\n",
chrono::Local::now().to_rfc2829()
));
let summary = self.create_summary(items);
content.push_str("## Summary\n\n");
content.push_str("| Metric | Count |\n|--------|-------|\n");
content.push_str(&format!"| Total Items | {} |\n", summary.total_items));
content.push_str(&format!(
"| Critical | {} |\n",
summary.by_priority.critical
));
content.push_str(&format!("| High | {} |\n", summary.by_priority.high));
content.push_str(&format!("| Medium | {} |\n", summary.by_priority.medium));
content.push_str(&format!("| Low | {} |\n", summary.by_priority.low));
content.push_str("\n");
content.push_str("## By Priority\n\n");
content.push_str("| Priority | Count | Bar |\n|---------|-------|-----|\n");
for (priority_str, count) in [
("Critical", summary.by_priority.critical),
("High", summary.by_priority.high),
("Medium", summary.by_priority.medium),
("Low", summary.by_priority.low),
] {
let bar = "".repeat(count.min(50));
content.push_str(&format!"| {} | {} | {} |\n", priority_str, count, bar));
}
content.push_str("\n");
content.push_str("## By Language\n\n");
content.push_str("| Language | Count |\n|----------|-------|\n");
for lang in &summary.by_language.items {
content.push_str(&format!"| {} | {} |\n", lang.language, lang.count));
}
content.push_str("\n");
content.push_str("## Technical Debt Items\n\n");
let priority_order = ["Critical", "High", "Medium", "Low"];
for priority_str in priority_order {
let priority_items: Vec<_> = items
.iter()
.filter(|i| i.priority.as_str() == priority_str)
.collect();
if !priority_items.is_empty() {
content.push_str(&format!("### {}\n\n", priority_str));
let mut sorted_items: Vec<_> = priority_items.iter().collect();
sorted_items.sort_by_key(|i| &i.location.path);
for item in sorted_items {
content.push_str(&format!(
"- **{}** at `{}:{}`\n",
item.keyword,
item.location.path.display(),
item.location.line
));
content.push_str(&format!(" - {}\n", self.truncate(&item.content, 100)));
content.push_str(&format!(" - Complexity: {}/10\n", item.complexity_score));
content.push_str(&format!(" - Language: {}\n", item.metadata.language));
content.push_str("\n");
}
}
}
let mut file = File::create(output)?;
file.write_all(content.as_bytes())?;
println!("Exported to {}", output.display());
Ok(())
}
pub fn print_summary(&self, items: &[TechDebtItem]) {
let summary = self.create_summary(items);
println!();
println!("═══════════════════════════════════════════");
println!(" TECHNICAL DEBT ANALYSIS ");
println!("═══════════════════════════════════════════");
println!();
println!(" Total Items: {}", summary.total_items);
println!();
println!(" Priority Breakdown:");
println!(" 🔴 Critical: {}", summary.by_priority.critical);
println!(" 🟠 High: {}", summary.by_priority.high);
println!(" 🟡 Medium: {}", summary.by_priority.medium);
println!(" 🟢 Low: {}", summary.by_priority.low);
println!();
println!(" Complexity Distribution:");
println!(" Low (1-3): {}", summary.complexity_distribution.low);
println!(
" Medium (4-6): {}",
summary.complexity_distribution.medium
);
println!(
" High (7-8): {}",
summary.complexity_distribution.high
);
println!(
" Critical (9+): {}",
summary.complexity_distribution.critical
);
println!();
println!(" By Language:");
for lang in summary.by_language.items.iter().take(5) {
println!(" {}: {}", lang.language, lang.count);
}
if summary.by_language.items.len() > 5 {
println!(" ... and {} more", summary.by_language.items.len() - 5);
}
println!();
println!("═══════════════════════════════════════════");
}
fn create_summary(&self, items: &[TechDebtItem]) -> AnalysisSummary {
let by_priority = ByPriority::from_items(items);
let by_language = ByLanguage::from_items(items);
let complexity_distribution = ComplexityDistribution::from_items(items);
AnalysisSummary {
total_items: items.len(),
by_priority,
by_language,
complexity_distribution,
}
}
fn truncate(&self, s: &str, max_len: usize) -> String {
if s.len() <= max_len {
s.to_string()
} else {
let mut truncated = s[..max_len - 3].to_string();
truncated.push_str("...");
truncated
}
}
}
#[derive(serde::Serialize)]
struct ExportData {
summary: AnalysisSummary,
items: Vec<TechDebtItem>,
}