Enforce coverage inside of Bazel lcov merger - #450
Merged
tinder-maxwellelliott merged 4 commits intoAug 10, 2026
Merged
Conversation
Replace Bazel's built-in LCOV merger with a dependency-free Rust binary (//tools/coverage:lcov_merger, wired via --coverage_output_generator in .bazelrc) that merges each test's raw per-runner LCOV tracefiles into its coverage.dat and, when the target declares one, enforces a minimum line coverage percentage. Bazel only invokes the merger during 'bazel coverage', so plain 'bazel test' runs are never affected. Targets opt in through their env attribute via //tools/coverage:defs.bzl (coverage_enforced_test macro / coverage_minimum_env helper), which works with any test rule exposing the standard env attribute (go_test, rust_test, kt_jvm_test, py_test, ...). Applied so far: - //tools/go/sample:sample_test — min 90% over tools/go/ (mirrors the CI gate) - //tools/coverage:lcov_merger_test — min 90% over its own sources, enforced by the merger itself (currently at 98%) The merger mirrors the built-in CoverageOutputGenerator's contract: --coverage_dir/--output_file/--filter_sources/--source_file_manifest, full-match filter regexes (small built-in subset, no third-party crates), manifest restriction to instrumented sources, and recomputed summary counters. Unknown flags warn instead of failing so newer Bazels degrade gracefully. Below-minimum targets exit with code 33 and a per-file breakdown in the test log; the merged coverage.dat is still written and --combined_report=lcov works unchanged. rules_rust is a dev_dependency (consumers of bazel-diff as a module do not inherit it), pinned to Rust 1.90.0, edition 2021. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016KqwUSCW2t6fmvnRFyw9vX
Apply the lcov_merger enforcement (previous commit) across every test target in the repository that produces coverage: - cli/BUILD: all 40 kt_jvm_test targets declare a minimum via coverage_minimum_env, scoped to the source file(s) each test is responsible for (Jacoco instruments all of :cli-lib for every test, so unscoped percentages would be meaningless). Floors were set from measured per-target coverage minus ~10 points of headroom, rounded down to 5 and capped at 90, to absorb platform/Bazel-version variance while still catching real regressions. E2ETest carries a conservative 30% smoke floor over the whole main tree instead of a measured one. - rules_kotlin ignores --coverage_output_generator: kt_jvm_test hardcodes its _lcov_merger attribute to Bazel's built-in merger instead of the coverage fragment's output_generator configuration field, which would silently bypass enforcement for Kotlin targets. A single_version_override patch (tools/coverage/rules_kotlin_lcov_merger.patch) makes it read the configuration field, like rules_go/rules_rust/rules_java already do. Verified: an unreachable floor fails 'bazel coverage' with the merger's per-file report in the test log, and plain 'bazel test' is unaffected. - gazelle direct dep bumped 0.45.0 -> 0.47.0 to match the version MVS now resolves (rules_rust requires the newer one), silencing the check_direct_dependencies warning. - CI/Makefile coverage universes include //tools/coverage/...; README documents the per-target system. All 40 Kotlin targets (39 measured + E2E), the Go sample test, and the Rust merger's own test pass 'bazel coverage' with enforcement active. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016KqwUSCW2t6fmvnRFyw9vX
maxwellE
force-pushed
the
claude/lcov-merger-bazel-coverage-tl9k4j
branch
from
August 10, 2026 14:05
a6e0304 to
d03e4bb
Compare
Make 90% the Starlark default, drop enforcement on E2E/partial tests, and expand primary-owner unit tests (including RuleHasherTest) so every remaining coverage_minimum_env target clears the floor. Co-authored-by: Cursor <cursoragent@cursor.com>
chflags is macOS-only and ProcessBuilder.start throws when the binary is missing, so the prior skip path never ran on Ubuntu. Use POSIX directory permissions and a VisibleForTesting touch hook instead. Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
As we look to possibly port this project into Rust we need to ensure that at a core level we are not regressing on the high standards in the codebase around test coverage. This work moves our coverage enforcement inside of bazel itself, providing agents with direct feedback when work they are performing does not contain the necessary coverage standards to merge into this codebase.