@@ -96,10 +96,12 @@ fn main() -> Result<()> {
9696
9797 for rule in & rules {
9898 match rule. check ( & file_path, verbose && !json) {
99- Ok ( result) => {
100- all_results. push ( result. clone ( ) ) ;
101- if !json && result. has_issue {
102- println ! ( " {} {}" , "✗" . red( ) , result. message. unwrap_or_default( ) ) ;
99+ Ok ( results) => {
100+ for result in results {
101+ all_results. push ( result. clone ( ) ) ;
102+ if !json && result. has_issue {
103+ println ! ( " {} {}" , "✗" . red( ) , result. message. unwrap_or_default( ) ) ;
104+ }
103105 }
104106 }
105107 Err ( e) => {
@@ -111,6 +113,11 @@ fn main() -> Result<()> {
111113 }
112114 }
113115
116+ // Print summary if not in JSON mode
117+ if !json && !all_results. is_empty ( ) {
118+ print_check_summary ( & all_results) ;
119+ }
120+
114121 // Output handling
115122 if json {
116123 for result in & all_results {
@@ -202,3 +209,73 @@ fn resolve_rules(
202209 Ok ( rules)
203210 }
204211}
212+
213+ fn print_check_summary ( results : & [ rule:: CheckResult ] ) {
214+ use std:: collections:: { HashMap , HashSet } ;
215+
216+ // Get unique files checked
217+ let unique_files: HashSet < & str > = results. iter ( ) . map ( |r| r. file_path . as_str ( ) ) . collect ( ) ;
218+ let total_files = unique_files. len ( ) ;
219+
220+ // Count files with issues (at least one result with has_issue=true)
221+ let mut files_with_issues = HashSet :: new ( ) ;
222+ let mut total_issues = 0 ;
223+
224+ // Track issues by rule type
225+ let mut issues_by_rule: HashMap < String , usize > = HashMap :: new ( ) ;
226+ let mut files_by_rule: HashMap < String , HashSet < String > > = HashMap :: new ( ) ;
227+
228+ for result in results {
229+ if result. has_issue {
230+ files_with_issues. insert ( & result. file_path ) ;
231+ total_issues += result. issue_count ;
232+
233+ // Track by rule
234+ * issues_by_rule. entry ( result. rule_name . clone ( ) ) . or_insert ( 0 ) += result. issue_count ;
235+ files_by_rule
236+ . entry ( result. rule_name . clone ( ) )
237+ . or_insert_with ( HashSet :: new)
238+ . insert ( result. file_path . clone ( ) ) ;
239+ }
240+ }
241+
242+ let files_with_issues_count = files_with_issues. len ( ) ;
243+ let files_clean = total_files - files_with_issues_count;
244+
245+ println ! ( "\n {}" , "=== Summary ===" . bold( ) ) ;
246+ println ! ( "Total files: {}" , total_files) ;
247+ println ! (
248+ "Files with issues: {} {}" ,
249+ files_with_issues_count,
250+ if files_with_issues_count > 0 {
251+ "✗" . red( )
252+ } else {
253+ "✓" . green( )
254+ }
255+ ) ;
256+ println ! ( "Clean files: {} {}" , files_clean, "✓" . green( ) ) ;
257+
258+ if !issues_by_rule. is_empty ( ) {
259+ println ! ( "\n {}" , "Issues by rule:" . bold( ) ) ;
260+ let mut rule_names: Vec < _ > = issues_by_rule. keys ( ) . collect ( ) ;
261+ rule_names. sort ( ) ;
262+
263+ for rule_name in rule_names {
264+ let count = issues_by_rule[ rule_name] ;
265+ let file_count = files_by_rule[ rule_name] . len ( ) ;
266+ println ! (
267+ " {}: {} issue(s) in {} file(s)" ,
268+ rule_name. cyan( ) ,
269+ count,
270+ file_count
271+ ) ;
272+ }
273+ }
274+
275+ println ! ( "\n Total issues found: {}" , total_issues) ;
276+
277+ if total_files > 0 {
278+ let success_rate = ( files_clean as f64 / total_files as f64 ) * 100.0 ;
279+ println ! ( "Success rate: {:.1}%" , success_rate) ;
280+ }
281+ }
0 commit comments