#[allow(clippy::too_many_arguments)]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "path_exists")]
pub async fn handle_quality_gate(
project_path: PathBuf,
file: Option<PathBuf>,
format: QualityGateOutputFormat,
fail_on_violation: bool,
checks: Vec<QualityCheckType>,
max_dead_code: f64,
min_entropy: Option<f64>,
max_complexity_p99: u32,
include_provability: bool,
output: Option<PathBuf>,
perf: bool,
) -> Result<()> {
use std::time::Instant;
if !project_path.exists() {
return Err(anyhow::anyhow!(
"Path not found: {}",
project_path.display()
));
}
let start_time = if perf { Some(Instant::now()) } else { None };
print_quality_gate_start_message(&file);
let checks_to_run = if checks.is_empty() {
vec![QualityCheckType::All]
} else {
checks.clone()
};
print_checks_to_run(&checks_to_run);
let result = if let Some(single_file) = file {
handle_single_file_quality_gate(
project_path,
single_file,
format,
fail_on_violation,
checks_to_run.clone(), max_complexity_p99,
output,
perf,
)
.await
} else {
handle_project_quality_gate(
project_path,
format,
fail_on_violation,
checks_to_run.clone(), max_dead_code,
min_entropy,
max_complexity_p99,
include_provability,
output,
perf,
)
.await
};
if let Some(start) = start_time {
let duration = start.elapsed();
crate::status_eprintln!("\n⏱️ Performance Metrics:");
crate::status_eprintln!(" Total execution time: {:.2}s", duration.as_secs_f64());
crate::status_eprintln!(" Checks performed: {}", checks_to_run.len());
crate::status_eprintln!(
" Average time per check: {:.2}s",
duration.as_secs_f64() / checks_to_run.len() as f64
);
}
result
}
fn print_quality_gate_start_message(file: &Option<PathBuf>) {
if let Some(single_file) = file {
crate::status_eprintln!(
"🔍 Running quality gate checks on file: {}...",
single_file.display()
);
} else {
crate::status_eprintln!("🔍 Running quality gate checks...");
}
}
fn print_checks_to_run(checks: &[QualityCheckType]) {
crate::status_eprintln!("\n📋 Checks to run:");
if checks.contains(&QualityCheckType::All) {
print_all_checks();
} else {
print_selected_checks(checks);
}
crate::status_eprintln!();
}
fn print_all_checks() {
crate::status_eprintln!(" ✓ Complexity analysis");
crate::status_eprintln!(" ✓ Dead code detection");
crate::status_eprintln!(" ✓ Self-admitted technical debt (SATD)");
crate::status_eprintln!(" ✓ Security vulnerabilities");
crate::status_eprintln!(" ✓ Code entropy");
crate::status_eprintln!(" ✓ Duplicate code");
crate::status_eprintln!(" ✓ Test coverage");
}
fn print_selected_checks(checks: &[QualityCheckType]) {
for check in checks {
print_single_check(check);
}
}
fn print_single_check(check: &QualityCheckType) {
if let Some(message) = get_check_message(check) {
print_check_success(message);
}
}
fn get_check_message(check: &QualityCheckType) -> Option<&'static str> {
match check {
QualityCheckType::Complexity => Some("Complexity analysis"),
QualityCheckType::DeadCode => Some("Dead code detection"),
QualityCheckType::Satd => Some("Self-admitted technical debt (SATD)"),
QualityCheckType::Security => Some("Security vulnerabilities"),
QualityCheckType::Entropy => Some("Code entropy"),
QualityCheckType::Duplicates => Some("Duplicate code"),
QualityCheckType::Coverage => Some("Test coverage"),
_ => None,
}
}
fn print_check_success(message: &str) {
crate::status_eprintln!(" ✓ {message}");
}