Skip to main content

garbage_code_hunter/commit_roaster/
mod.rs

1//! Commit Roaster module.
2//!
3//! Scans git history and roasts bad commit messages with
4//! sharp but humorous feedback.
5
6pub 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
18/// Run the commit-roaster analysis on a repository.
19pub fn run(repo_path: &Path, config: &AnalyzerConfig, format: &OutputFormat) -> Result<String> {
20    // Load default rules
21    let ruleset = RuleSet::from_toml(rules::default_rules_toml())?;
22    let active_rules = ruleset.active_rules();
23
24    // Analyze commits
25    let commits = analyzer::analyze_repo(repo_path, config)?;
26
27    // Score each commit
28    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    // Build report
38    let report = report::build_report(scored_commits);
39
40    // Format output
41    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}