@@ -6,10 +6,21 @@ import { readdirSync, readFileSync, writeFileSync } from "node:fs";
66import { join , relative } from "node:path" ;
77import { fileURLToPath } from "node:url" ;
88
9- const root = join ( fileURLToPath ( new URL ( "." , import . meta. url ) ) , ".." ) ;
10- const c8Bin = join ( root , "review-enrichment" , "node_modules" , "c8" , "bin" , "c8.js" ) ;
11- const reportDir = join ( root , "review-enrichment" , "coverage" ) ;
12- const testRoot = join ( root , "review-enrichment" , "test" ) ;
9+ /** Normalize c8's SF: paths to forward slashes for Codecov. Swallows only a missing report
10+ * (ENOENT on read) — CI's "Verify REES coverage report exists" step fails closed downstream.
11+ * Any other read/write error propagates so a real lcov post-process failure is not masked. */
12+ export function normalizeLcovSfPaths ( lcovPath , { readFile = readFileSync , writeFile = writeFileSync } = { } ) {
13+ try {
14+ const raw = readFile ( lcovPath , "utf8" ) ;
15+ writeFile (
16+ lcovPath ,
17+ raw . replace ( / ^ S F : ( .* ) $ / gm, ( _match , path ) => `SF:${ String ( path ) . replace ( / \\ / g, "/" ) } ` ) ,
18+ ) ;
19+ } catch ( error ) {
20+ if ( error && typeof error === "object" && "code" in error && error . code === "ENOENT" ) return ;
21+ throw error ;
22+ }
23+ }
1324
1425function collectTests ( dir , out = [ ] ) {
1526 for ( const ent of readdirSync ( dir , { withFileTypes : true } ) ) {
@@ -20,40 +31,40 @@ function collectTests(dir, out = []) {
2031 return out ;
2132}
2233
23- const tests = collectTests ( testRoot ) . map ( ( path ) => relative ( root , path ) . split ( "\\" ) . join ( "/" ) ) ;
24- if ( tests . length === 0 ) {
25- console . error ( "rees-coverage: no review-enrichment/test/**/*.test.ts files found ") ;
26- process . exit ( 1 ) ;
27- }
34+ function main ( ) {
35+ const root = join ( fileURLToPath ( new URL ( "." , import . meta . url ) ) , ".." ) ;
36+ const c8Bin = join ( root , " review-enrichment" , "node_modules" , "c8" , "bin" , "c8.js ") ;
37+ const reportDir = join ( root , "review-enrichment" , "coverage" ) ;
38+ const testRoot = join ( root , "review-enrichment" , "test" ) ;
2839
29- const result = spawnSync (
30- process . execPath ,
31- [
32- c8Bin ,
33- "--reporter=lcov" ,
34- "--reporter=text-summary" ,
35- `--report-dir=${ reportDir } ` ,
36- "--include=review-enrichment/dist/**/*.js" ,
37- "--exclude=**/*.d.ts" ,
38- "--all" ,
40+ const tests = collectTests ( testRoot ) . map ( ( path ) => relative ( root , path ) . split ( "\\" ) . join ( "/" ) ) ;
41+ if ( tests . length === 0 ) {
42+ console . error ( "rees-coverage: no review-enrichment/test/**/*.test.ts files found" ) ;
43+ process . exit ( 1 ) ;
44+ }
45+
46+ const result = spawnSync (
3947 process . execPath ,
40- "--test" ,
41- "--experimental-strip-types" ,
42- ... tests ,
43- ] ,
44- { cwd : root , stdio : "inherit" , env : process . env } ,
45- ) ;
46-
47- // Codecov expects forward-slash SF: paths; c8 on Windows emits backslashes.
48- const lcovPath = join ( reportDir , "lcov.info" ) ;
49- try {
50- const raw = readFileSync ( lcovPath , "utf8" ) ;
51- writeFileSync (
52- lcovPath ,
53- raw . replace ( / ^ S F : ( . * ) $ / gm , ( _match , path ) => `SF: ${ String ( path ) . replace ( / \\ / g , "/" ) } ` ) ,
48+ [
49+ c8Bin ,
50+ "--reporter=lcov" ,
51+ "--reporter=text-summary" ,
52+ `--report-dir= ${ reportDir } ` ,
53+ "--include=review-enrichment/dist/**/*.js" ,
54+ "--exclude=**/*.d.ts" ,
55+ "--all" ,
56+ process . execPath ,
57+ "--test" ,
58+ "--experimental-strip-types" ,
59+ ... tests ,
60+ ] ,
61+ { cwd : root , stdio : "inherit" , env : process . env } ,
5462 ) ;
55- } catch {
56- // CI's "Verify REES coverage report exists" step fails closed if the report is missing.
63+
64+ // Codecov expects forward-slash SF: paths; c8 on Windows emits backslashes.
65+ normalizeLcovSfPaths ( join ( reportDir , "lcov.info" ) ) ;
66+
67+ process . exit ( result . status === null ? 1 : result . status ) ;
5768}
5869
59- process . exit ( result . status === null ? 1 : result . status ) ;
70+ if ( process . argv [ 1 ] === fileURLToPath ( import . meta . url ) ) main ( ) ;
0 commit comments