ferrous_forge/commands/validate/
mod.rs1pub mod ai_report;
5pub mod checks;
7pub mod markdown;
9pub mod utils;
11
12use ai_report::generate_ai_report;
13use checks::{run_additional_checks, run_clippy_validation};
14
15use crate::{
16 Result,
17 config::Config,
18 validation::{RustValidator, Violation, ViolationType},
19};
20use console::style;
21use std::path::{Path, PathBuf};
22
23pub async fn execute(path: Option<PathBuf>, ai_report: bool, locked_only: bool) -> Result<()> {
30 let project_path = path.unwrap_or_else(|| std::env::current_dir().unwrap_or_default());
31
32 print_header(&project_path);
33
34 let config = Config::load_or_default().await?;
36 let validator = RustValidator::with_config(project_path.clone(), config)?;
37 let violations = validator.validate_project().await?;
38
39 if locked_only {
40 return handle_locked_only_check(&violations);
41 }
42
43 display_validation_results(&validator, &violations)?;
44
45 if ai_report {
46 generate_ai_report_with_message(&project_path, &violations).await?;
47 }
48
49 let clippy_result = run_clippy_validation(&validator).await?;
50 run_additional_checks(&project_path).await;
51
52 handle_final_result(&violations, &clippy_result);
53
54 Ok(())
55}
56
57fn print_header(project_path: &Path) {
58 println!();
59 println!("{}", style("š¦ Running Ferrous Forge validation...").bold());
60 println!();
61
62 println!("š Project: {}", project_path.display());
63 println!();
64}
65
66fn display_validation_results(validator: &RustValidator, violations: &[Violation]) -> Result<()> {
67 let report = validator.generate_report(violations);
68 println!("{}", report);
69 Ok(())
70}
71
72fn handle_locked_only_check(violations: &[Violation]) -> Result<()> {
74 let locked: Vec<&Violation> = violations
75 .iter()
76 .filter(|v| {
77 matches!(
78 v.violation_type,
79 ViolationType::WrongEdition
80 | ViolationType::OldRustVersion
81 | ViolationType::LockedSetting
82 )
83 })
84 .collect();
85
86 if locked.is_empty() {
87 println!("{}", style("ā
No locked setting violations.").green());
88 return Ok(());
89 }
90
91 eprintln!("\nā FERROUS FORGE ā Locked Setting Violations\n");
92 for v in &locked {
93 eprintln!("{}\n", v.message);
94 }
95 std::process::exit(1);
96}
97
98async fn generate_ai_report_with_message(
99 project_path: &PathBuf,
100 violations: &[Violation],
101) -> Result<()> {
102 generate_ai_report(project_path, violations).await
103}
104
105fn handle_final_result(violations: &[Violation], clippy_result: &crate::validation::ClippyResult) {
106 if !violations.is_empty() || !clippy_result.success {
107 println!(
108 "{}",
109 style("ā Validation completed with issues").red().bold()
110 );
111 std::process::exit(1);
112 } else {
113 println!(
114 "{}",
115 style("ā
All validation checks passed!").green().bold()
116 );
117 }
118}