1+ // rules-repo/functions/hitTracker.js
2+
3+ const fs = require ( 'fs' ) ;
4+ const path = require ( 'path' ) ;
5+
6+ const RuleTracker = {
7+ hits : new Map ( ) ,
8+ noMatches : new Set ( ) ,
9+
10+ trackRule ( ruleName , given , results ) {
11+ if ( ! this . hits . has ( ruleName ) ) {
12+ this . hits . set ( ruleName , {
13+ matches : 0 ,
14+ violations : 0 ,
15+ elements : new Set ( ) ,
16+ paths : new Set ( )
17+ } ) ;
18+ }
19+
20+ if ( ! given || ( Array . isArray ( given ) && given . length === 0 ) ) {
21+ this . noMatches . add ( ruleName ) ;
22+ return ;
23+ }
24+
25+ const stats = this . hits . get ( ruleName ) ;
26+ stats . matches ++ ;
27+ if ( results && results . length > 0 ) {
28+ stats . violations ++ ;
29+ // Track paths where violations occurred
30+ results . forEach ( result => {
31+ if ( result . path ) {
32+ stats . paths . add ( result . path ) ;
33+ }
34+ } ) ;
35+ }
36+
37+ if ( typeof given === 'object' ) {
38+ Object . keys ( given ) . forEach ( path => {
39+ stats . elements . add ( path ) ;
40+ } ) ;
41+ } else {
42+ stats . elements . add ( String ( given ) ) ;
43+ }
44+
45+ // Write report to CI_REPORT_PATH if environment variable is set
46+ if ( process . env . CI_REPORT_PATH ) {
47+ this . writeReport ( process . env . CI_REPORT_PATH ) ;
48+ }
49+ } ,
50+
51+ getReport ( ) {
52+ return {
53+ ruleStats : Object . fromEntries ( [ ...this . hits . entries ( ) ] . map ( ( [ rule , stats ] ) => [
54+ rule ,
55+ {
56+ totalMatches : stats . matches ,
57+ violations : stats . violations ,
58+ elements : Array . from ( stats . elements ) ,
59+ violationPaths : Array . from ( stats . paths )
60+ }
61+ ] ) ) ,
62+ noMatches : Array . from ( this . noMatches ) ,
63+ timestamp : new Date ( ) . toISOString ( ) ,
64+ summary : {
65+ totalRules : this . hits . size + this . noMatches . size ,
66+ rulesWithMatches : this . hits . size ,
67+ rulesWithNoMatches : this . noMatches . size ,
68+ totalViolations : [ ...this . hits . values ( ) ] . reduce ( ( sum , stat ) => sum + stat . violations , 0 )
69+ }
70+ } ;
71+ } ,
72+
73+ writeReport ( reportPath ) {
74+ fs . mkdirSync ( path . dirname ( reportPath ) , { recursive : true } ) ;
75+ fs . writeFileSync ( reportPath , JSON . stringify ( this . getReport ( ) , null , 2 ) ) ;
76+ }
77+ } ;
78+
79+ const withTracking = ( ruleName , originalRule ) => ( given , options , context ) => {
80+ const results = originalRule ( given , options , context ) ;
81+ RuleTracker . trackRule ( ruleName , given , results ) ;
82+ return results ;
83+ } ;
84+
85+ module . exports = { RuleTracker, withTracking } ;
0 commit comments