@@ -62,63 +62,48 @@ function main() {
6262 rows . sort ( ( a , b ) => b . ageDays - a . ageDays ) ;
6363 console . log ( 'Sorted files by age (descending)' ) ;
6464
65- // Grouping buckets
66- const buckets = [
67- { label : '24+ months' , filter : r => r . ageMonths >= 24 } ,
68- { label : '18-24 months' , filter : r => r . ageMonths >= 18 && r . ageMonths < 24 } ,
69- { label : '12-18 months' , filter : r => r . ageMonths >= 12 && r . ageMonths < 18 } ,
70- { label : '6-12 months' , filter : r => r . ageMonths >= 6 && r . ageMonths < 12 } ,
71- { label : '0-6 months' , filter : r => r . ageMonths < 6 } ,
72- ] ;
73-
74- function renderTable ( sectionRows ) {
75- if ( sectionRows . length === 0 ) return '_No files_' ;
76- const header = [ 'Path' , 'Last Commit' , 'Age (months)' , 'Age (days)' ] ;
77- const lines = [
78- `| ${ header . join ( ' | ' ) } |` ,
79- `| ${ header . map ( ( ) => '---' ) . join ( ' | ' ) } |`
80- ] ;
81- for ( const r of sectionRows ) {
82- lines . push ( `| ${ r . path } | ${ r . lastCommit } | ${ r . ageMonths . toFixed ( 1 ) } | ${ r . ageDays . toFixed ( 0 ) } |` ) ;
83- }
84- return lines . join ( '\n' ) ;
65+ // Determine age bucket for each row
66+ function getAgeBucket ( ageMonths ) {
67+ if ( ageMonths >= 24 ) return '24+ months' ;
68+ if ( ageMonths >= 18 ) return '18-24 months' ;
69+ if ( ageMonths >= 12 ) return '12-18 months' ;
70+ if ( ageMonths >= 6 ) return '6-12 months' ;
71+ return '0-6 months' ;
8572 }
8673
87- const summaryCounts = buckets . map ( b => ( { label : b . label , count : rows . filter ( b . filter ) . length } ) ) ;
88-
89- const out = [ ] ;
90- out . push ( '# MDX Report' ) ;
91- out . push ( '' ) ;
92-
93- out . push ( `Generated: ${ new Date ( ) . toISOString ( ) } ` ) ;
94- out . push ( '' ) ;
95-
96- out . push ( '## Summary by Age Bucket' ) ;
97- out . push ( '' ) ;
98-
99- out . push ( '| Age Bucket | File Count |' ) ;
100- out . push ( '| --- | ---: |' ) ;
101- for ( const sc of summaryCounts ) {
102- out . push ( `| ${ sc . label } | ${ sc . count } |` ) ;
74+ // Escape CSV field if needed (contains comma, quote, or newline)
75+ function escapeCSV ( field ) {
76+ if ( field . includes ( ',' ) || field . includes ( '"' ) || field . includes ( '\n' ) ) {
77+ return `"${ field . replace ( / " / g, '""' ) } "` ;
78+ }
79+ return field ;
10380 }
104- out . push ( '' ) ;
105-
106- for ( const b of buckets ) {
107- const sectionRows = rows . filter ( b . filter ) ;
108- out . push ( `## ${ b . label } ` ) ;
109- out . push ( '' ) ;
110- out . push ( renderTable ( sectionRows ) ) ;
111- out . push ( '' ) ;
81+
82+ // Generate CSV output
83+ const csvLines = [ ] ;
84+ csvLines . push ( 'Path,Last Commit,Age (months),Age (days),Age Bucket' ) ;
85+
86+ for ( const r of rows ) {
87+ const bucket = getAgeBucket ( r . ageMonths ) ;
88+ const line = [
89+ escapeCSV ( r . path ) ,
90+ r . lastCommit ,
91+ r . ageMonths . toFixed ( 1 ) ,
92+ r . ageDays . toFixed ( 0 ) ,
93+ bucket
94+ ] . join ( ',' ) ;
95+ csvLines . push ( line ) ;
11296 }
113- const outputTxt = out . join ( '\n' ) ;
97+
98+ const outputCSV = csvLines . join ( '\n' ) ;
11499 const outArg = process . argv . find ( a => a . startsWith ( '--out=' ) ) ;
115- const outPath = outArg ? outArg . split ( '=' ) [ 1 ] : 'mdx-freshness.txt ' ;
100+ const outPath = outArg ? outArg . split ( '=' ) [ 1 ] : 'mdx-freshness.csv ' ;
116101 try {
117- writeFileSync ( outPath , outputTxt , 'utf8' ) ;
102+ writeFileSync ( outPath , outputCSV , 'utf8' ) ;
118103 console . log ( `Wrote report to ${ outPath } ` ) ;
119104 } catch ( e ) {
120105 console . log ( 'Failed writing file, falling back to stdout' ) ;
121- console . log ( outputTxt ) ;
106+ console . log ( outputCSV ) ;
122107 }
123108 console . log ( 'Done' ) ;
124109}
0 commit comments