garbage_code_hunter/commit_roaster/
mod.rs1pub mod analyzer;
7pub mod report;
8pub mod rules;
9
10use analyzer::AnalyzerConfig;
11use anyhow::Result;
12use report::ScoredCommit;
13use rules::{match_rules, RuleSet};
14use std::path::Path;
15
16pub use crate::common::OutputFormat;
17
18pub fn run(repo_path: &Path, config: &AnalyzerConfig, format: &OutputFormat) -> Result<String> {
20 let ruleset = RuleSet::from_toml(rules::default_rules_toml())?;
22 let active_rules = ruleset.active_rules();
23
24 let commits = analyzer::analyze_repo(repo_path, config)?;
26
27 let scored_commits: Vec<ScoredCommit> = commits
29 .into_iter()
30 .map(|commit| {
31 let first = analyzer::first_line(&commit.message);
32 let issues = match_rules(first, &active_rules);
33 ScoredCommit { commit, issues }
34 })
35 .collect();
36
37 let report = report::build_report(scored_commits);
39
40 match format {
42 OutputFormat::Terminal => Ok(report::format_terminal(&report)),
43 OutputFormat::Json => Ok(report::format_json(&report)?),
44 }
45}
46
47#[cfg(test)]
48mod tests {
49 use super::*;
50 use std::path::PathBuf;
51
52 #[test]
53 fn test_run_on_nonexistent_path() {
54 let path = PathBuf::from("/nonexistent/repo");
55 let config = AnalyzerConfig::default();
56 let result = run(&path, &config, &OutputFormat::Terminal);
57 assert!(result.is_err(), "Should fail on nonexistent path");
58 }
59}