fix: --experimental_split_coverage_postprocessing flag
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 4c2ff10..9901692 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml
@@ -119,6 +119,8 @@ run: echo "folder=e2e/vendored_tarfile" >> $GITHUB_OUTPUT - id: worker run: echo "folder=e2e/worker" >> $GITHUB_OUTPUT + - id: split_coverage + run: echo "folder=e2e/split_coverage" >> $GITHUB_OUTPUT outputs: # Will look like [".", "e2e/bzlmod", ...] folders: ${{ toJSON(steps.*.outputs.folder) }}
diff --git a/e2e/split_coverage/.bazelignore b/e2e/split_coverage/.bazelignore new file mode 100644 index 0000000..b512c09 --- /dev/null +++ b/e2e/split_coverage/.bazelignore
@@ -0,0 +1 @@ +node_modules \ No newline at end of file
diff --git a/e2e/split_coverage/.bazeliskrc b/e2e/split_coverage/.bazeliskrc new file mode 120000 index 0000000..0fbe20f --- /dev/null +++ b/e2e/split_coverage/.bazeliskrc
@@ -0,0 +1 @@ +../../.bazeliskrc \ No newline at end of file
diff --git a/e2e/split_coverage/.bazelrc b/e2e/split_coverage/.bazelrc new file mode 100644 index 0000000..db3624c --- /dev/null +++ b/e2e/split_coverage/.bazelrc
@@ -0,0 +1,7 @@ +# import common bazelrc shared with e2e workspaces +import %workspace%/../../.bazelrc.common + +coverage --sandbox_debug +coverage --experimental_split_coverage_postprocessing +coverage --experimental_fetch_all_coverage_outputs +coverage --instrument_test_targets \ No newline at end of file
diff --git a/e2e/split_coverage/.bazelversion b/e2e/split_coverage/.bazelversion new file mode 120000 index 0000000..96cf949 --- /dev/null +++ b/e2e/split_coverage/.bazelversion
@@ -0,0 +1 @@ +../../.bazelversion \ No newline at end of file
diff --git a/e2e/split_coverage/BUILD.bazel b/e2e/split_coverage/BUILD.bazel new file mode 100644 index 0000000..e98a045 --- /dev/null +++ b/e2e/split_coverage/BUILD.bazel
@@ -0,0 +1,3 @@ +load("@npm//:defs.bzl", "npm_link_all_packages") + +npm_link_all_packages(name = "node_modules")
diff --git a/e2e/split_coverage/WORKSPACE b/e2e/split_coverage/WORKSPACE new file mode 100644 index 0000000..c40edfb --- /dev/null +++ b/e2e/split_coverage/WORKSPACE
@@ -0,0 +1,27 @@ +local_repository( + name = "aspect_rules_js", + path = "../..", +) + +load("@aspect_rules_js//js:repositories.bzl", "rules_js_dependencies") + +rules_js_dependencies() + +load("@rules_nodejs//nodejs:repositories.bzl", "DEFAULT_NODE_VERSION", "nodejs_register_toolchains") + +nodejs_register_toolchains( + name = "nodejs", + node_version = DEFAULT_NODE_VERSION, +) + +load("@aspect_rules_js//npm:npm_import.bzl", "npm_translate_lock") + +npm_translate_lock( + name = "npm", + pnpm_lock = "//:pnpm-lock.yaml", + verify_node_modules_ignored = "//:.bazelignore", +) + +load("@npm//:repositories.bzl", "npm_repositories") + +npm_repositories()
diff --git a/e2e/split_coverage/package.json b/e2e/split_coverage/package.json new file mode 100644 index 0000000..b1ef5fe --- /dev/null +++ b/e2e/split_coverage/package.json
@@ -0,0 +1,6 @@ +{ + "private": true, + "dependencies": { + "@types/node": "18.15.11" + } +}
diff --git a/e2e/split_coverage/pnpm-lock.yaml b/e2e/split_coverage/pnpm-lock.yaml new file mode 100644 index 0000000..54499e0 --- /dev/null +++ b/e2e/split_coverage/pnpm-lock.yaml
@@ -0,0 +1,15 @@ +lockfileVersion: 5.4 + +importers: + + .: + specifiers: + '@types/node': 18.15.11 + dependencies: + '@types/node': 18.15.11 + +packages: + + /@types/node/18.15.11: + resolution: {integrity: sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==} + dev: false
diff --git a/e2e/split_coverage/pnpm-workspace.yaml b/e2e/split_coverage/pnpm-workspace.yaml new file mode 100644 index 0000000..2cce0eb --- /dev/null +++ b/e2e/split_coverage/pnpm-workspace.yaml
@@ -0,0 +1,2 @@ +packages: + - '.'
diff --git a/e2e/split_coverage/test/BUILD.bazel b/e2e/split_coverage/test/BUILD.bazel new file mode 100644 index 0000000..f55f431 --- /dev/null +++ b/e2e/split_coverage/test/BUILD.bazel
@@ -0,0 +1,10 @@ +load("@aspect_rules_js//js:defs.bzl", "js_test") + +js_test( + name = "coverage", + data = [ + "coverage.js", + "//:node_modules/@types/node", + ], + entry_point = "test.js", +)
diff --git a/e2e/split_coverage/test/coverage.js b/e2e/split_coverage/test/coverage.js new file mode 100644 index 0000000..30e97e9 --- /dev/null +++ b/e2e/split_coverage/test/coverage.js
@@ -0,0 +1,7 @@ +module.exports.test = function (num) { + if (num > 1) { + return 'bigger than 1' + } else { + return 'smaller than 1' + } +}
diff --git a/e2e/split_coverage/test/test.js b/e2e/split_coverage/test/test.js new file mode 100644 index 0000000..ae2c78d --- /dev/null +++ b/e2e/split_coverage/test/test.js
@@ -0,0 +1,7 @@ +const coverage = require('./coverage') + +coverage.test(0) + +// Disabling the statment below should give your 50% coverage +//coverage.test(2); +console.log(process.cwd())
diff --git a/js/private/coverage/bundle/c8.js b/js/private/coverage/bundle/c8.js index f649816..5174bda 100644 --- a/js/private/coverage/bundle/c8.js +++ b/js/private/coverage/bundle/c8.js
@@ -22,17 +22,22 @@ // TODO: can or should we instrument files from other repositories as well? // if so then the path.join call below will yield invalid paths since files will have external/wksp as their prefix. -const pwd = path.join(process.env.RUNFILES, process.env.TEST_WORKSPACE) -process.chdir(pwd) +let resolve = path.join(process.env.RUNFILES, process.env.TEST_WORKSPACE) + +if (process.env.SPLIT_COVERAGE_POST_PROCESSING == '1') { + resolve = fs + .readFileSync(path.resolve(process.env.COVERAGE_DIR, 'pwd')) + .toString() +} + +process.cwd = () => resolve new Report({ - include: include, + include: include.map((f) => path.join(resolve, f)), exclude: include.length === 0 ? ['**'] : [], reportsDirectory: process.env.COVERAGE_DIR, tempDirectory: process.env.COVERAGE_DIR, - resolve: '', - src: pwd, - all: true, + resolve: resolve, reporter: ['lcovonly'], }) .run()
diff --git a/js/private/coverage/coverage.js b/js/private/coverage/coverage.js index fb5583a..912e28d 100644 --- a/js/private/coverage/coverage.js +++ b/js/private/coverage/coverage.js
@@ -9611,7 +9611,7 @@ const convertSourceMap = convertSourceMap$1; const util$1 = require$$2; const debuglog$1 = util$1.debuglog('c8'); -const { dirname, isAbsolute: isAbsolute$1, join, resolve: resolve$1 } = require$$0; +const { dirname, isAbsolute: isAbsolute$1, join, resolve: resolve$2 } = require$$0; const { fileURLToPath: fileURLToPath$1 } = require$$1$1; const CovBranch = requireBranch(); const CovFunction = require_function(); @@ -9725,7 +9725,7 @@ if (isAbsolute$1(candidatePath)) { return candidatePath } else { - return resolve$1(dirname(this.path), candidatePath) + return resolve$2(dirname(this.path), candidatePath) } } @@ -10688,7 +10688,7 @@ const libReport = istanbulLibReport; const reports = istanbulReports; const { readdirSync, readFileSync, statSync } = require$$0$1; -const { isAbsolute, resolve, extname } = require$$0; +const { isAbsolute, resolve: resolve$1, extname } = require$$0; const { pathToFileURL, fileURLToPath } = require$$1$1; const getSourceMapFromFile = sourceMapFromFile_1; // TODO: switch back to @c88/v8-coverage once patch is landed. @@ -10782,7 +10782,7 @@ for (const v8ScriptCov of v8ProcessCov.result) { try { const sources = this._getSourceMap(v8ScriptCov); - const path = resolve(this.resolve, v8ScriptCov.url); + const path = resolve$1(this.resolve, v8ScriptCov.url); const converter = v8toIstanbul(path, this.wrapperLength, sources, (path) => { if (this.excludeAfterRemap) { return !this._shouldInstrument(path) @@ -10881,7 +10881,7 @@ const { extension } = this.exclude; for (const workingDir of workingDirs) { this.exclude.globSync(workingDir).forEach((f) => { - const fullPath = resolve(workingDir, f); + const fullPath = resolve$1(workingDir, f); if (!fileIndex.has(fullPath)) { const ext = extname(fullPath); if (extension.includes(ext)) { @@ -10892,7 +10892,7 @@ } emptyReports.push({ scriptId: 0, - url: resolve(fullPath), + url: resolve$1(fullPath), functions: [{ functionName: '(empty-report)', ranges: [{ @@ -10933,7 +10933,7 @@ for (const file of readdirSync(this.tempDirectory)) { try { reports.push(JSON.parse(readFileSync( - resolve(this.tempDirectory, file), + resolve$1(this.tempDirectory, file), 'utf8' ))); } catch (err) { @@ -11046,17 +11046,20 @@ // TODO: can or should we instrument files from other repositories as well? // if so then the path.join call below will yield invalid paths since files will have external/wksp as their prefix. -const pwd = require$$0.join(process.env.RUNFILES, process.env.TEST_WORKSPACE); -process.chdir(pwd); +let resolve = require$$0.join(process.env.RUNFILES, process.env.TEST_WORKSPACE); + +if (process.env.SPLIT_COVERAGE_POST_PROCESSING == "1") { + resolve = require$$0$1.readFileSync(require$$0.resolve(process.env.COVERAGE_DIR, "pwd")).toString(); +} + +process.cwd = () => resolve; new Report({ - include: include, + include: include.map(f => require$$0.join(resolve, f)), exclude: include.length === 0 ? ['**'] : [], reportsDirectory: process.env.COVERAGE_DIR, tempDirectory: process.env.COVERAGE_DIR, - resolve: '', - src: pwd, - all: true, + resolve: resolve, reporter: ['lcovonly'], }) .run()
diff --git a/js/private/coverage/coverage.sh.tpl b/js/private/coverage/coverage.sh.tpl index 6f6e100..2c4aa42 100644 --- a/js/private/coverage/coverage.sh.tpl +++ b/js/private/coverage/coverage.sh.tpl
@@ -18,6 +18,15 @@ # Initialize RUNFILES environment variable # ============================================================================== {{initialize_runfiles}} + +# When --experimental_split_coverage_postprocessing is enabled, bazel creates +# separate runfiles directory for the coverage merger. +# When --experimental_split_coverage_postprocessing is disabled we observe the issue +# in https://github.com/bazelbuild/bazel/issues/4033 +if [ $SPLIT_COVERAGE_POST_PROCESSING == 1 ]; then + RUNFILES=$(_normalize_path "$LCOV_MERGER.runfiles") +fi + export RUNFILES # ==============================================================================
diff --git a/js/private/js_binary.sh.tpl b/js/private/js_binary.sh.tpl index 58803e6..50467ff 100644 --- a/js/private/js_binary.sh.tpl +++ b/js/private/js_binary.sh.tpl
@@ -308,6 +308,10 @@ # Enable coverage if requested if [ "${COVERAGE_DIR:-}" ]; then logf_debug "enabling v8 coverage support ${COVERAGE_DIR}" + if [ ${SPLIT_COVERAGE_POST_PROCESSING:0} == 1 ]; then + logf_debug "split coverage post processing is requested. writing pwd to ${COVERAGE_DIR}/pwd" + echo -n "$PWD" > "${COVERAGE_DIR}/pwd" + fi export NODE_V8_COVERAGE=${COVERAGE_DIR} fi