#![cfg_attr(coverage_nightly, coverage(off))]
use crate::cli::RepoScoreOutputFormat;
use crate::services::repo_score::{
aggregator::ScoreAggregator, models::Grade, scorers::ScorerConfig, RepoScore,
};
use anyhow::{Context, Result};
use std::fs;
use std::path::Path;
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "path_exists")]
pub async fn handle_repo_score(
path: &Path,
format: RepoScoreOutputFormat,
verbose: bool,
failures_only: bool,
output: Option<&Path>,
update_badge: bool,
deep: bool,
) -> Result<()> {
if !path.exists() {
anyhow::bail!("Path not found: {}", path.display());
}
let config = ScorerConfig {
verbose,
timeout_seconds: 300,
skip_slow_checks: failures_only,
deep,
};
let aggregator = ScoreAggregator::new();
let score = aggregator
.aggregate(path, &config)
.await
.context("Failed to calculate repository score")?;
if update_badge {
update_readme_badge(path, &score)?;
}
let output_text = match format {
RepoScoreOutputFormat::Text => format_text(&score, verbose),
RepoScoreOutputFormat::Json => format_json(&score)?,
RepoScoreOutputFormat::Markdown => format_markdown(&score),
RepoScoreOutputFormat::Yaml => format_yaml(&score)?,
};
if let Some(output_path) = output {
fs::write(output_path, output_text)
.with_context(|| format!("Failed to write to {}", output_path.display()))?;
println!("Repository score written to: {}", output_path.display());
} else {
print!("{}", output_text);
}
Ok(())
}
include!("repo_score_handlers_display.rs");
include!("repo_score_handlers_badge.rs");
include!("repo_score_handlers_tests.rs");