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