code complexity & repetition analysis tool
1use anyhow::Result;
2use mccabre_core::coverage::{FileCoverage, parse_coverage_from_file};
3use mccabre_core::reporter::{coverage_jsonl::JsonlReporter, coverage_term::report_coverage};
4use owo_colors::OwoColorize;
5use std::path::PathBuf;
6
7pub fn run(from: PathBuf, jsonl: Option<PathBuf>, repo_root: Option<PathBuf>) -> Result<()> {
8 if !from.exists() {
9 eprintln!("{}", format!("LCOV file not found: {}", from.display()).red());
10 std::process::exit(1);
11 }
12
13 let report = parse_coverage_from_file(&from, repo_root.as_deref())?;
14
15 if report.files.is_empty() {
16 eprintln!("{}", "No coverage data found".yellow());
17 return Ok(());
18 }
19
20 if let Some(jsonl_path) = jsonl {
21 let mut reporter = JsonlReporter::new();
22 reporter.add_report(&report);
23 reporter.write_to_file(&jsonl_path)?;
24
25 println!(
26 "{}",
27 format!("JSONL report written to: {}", jsonl_path.display())
28 .green()
29 .bold()
30 );
31 }
32
33 println!("{}", report_coverage(&report));
34
35 Ok(())
36}
37
38pub fn run_file_view(path: PathBuf, from: PathBuf) -> Result<()> {
39 if !from.exists() {
40 eprintln!("{}", format!("LCOV file not found: {}", from.display()).red());
41 std::process::exit(1);
42 }
43
44 let report = parse_coverage_from_file(&from, None)?;
45
46 let file_coverage = report.files.iter().find(|f| f.path == path.to_string_lossy());
47
48 match file_coverage {
49 Some(file) => {
50 println!("{}", report_coverage_for_file(file));
51 }
52 None => {
53 eprintln!(
54 "{}",
55 format!("File not found in coverage data: {}", path.display()).red()
56 );
57 std::process::exit(1);
58 }
59 }
60
61 Ok(())
62}
63
64fn report_coverage_for_file(file: &FileCoverage) -> String {
65 mccabre_core::reporter::coverage_term::format_file_coverage(file, 0)
66}