Skip to content

Include virtual-includes and vendored headers in the coverage scope - #3

Merged
dcalavrezo-qorix merged 2 commits into
mainfrom
dcalavrezo_558
Sep 11, 2026
Merged

Include virtual-includes and vendored headers in the coverage scope#3
dcalavrezo-qorix merged 2 commits into
mainfrom
dcalavrezo_558

Conversation

@dcalavrezo-qorix

Copy link
Copy Markdown
Contributor

What

Fixes the header loss reported in eclipse-score/baselibs#558: a workspace
target whose hdrs are vendored from an external repository behind
strip_include_prefix (//score/flatbuffers:flatbufferscpp) had all its
headers filtered out of the coverage report.

Two causes, both addressed:

  1. The scope aspect dropped every file under external/.
  2. The compiler does not record that path anyway. With strip_include_prefix
    / include_prefix, Bazel compiles against a generated _virtual_includes/
    symlink tree and the coverage mapping names that file, under a
    configuration-specific prefix (bazel-out/k8-fastbuild/bin/... in the
    test binaries, bazel-out/k8-opt-exec-*/bin/... in the scope's baseline
    archive).

How

  • Aspect (coverage_scope.bzl): for workspace targets, the post-processing
    identity of the public headers (CcInfo.compilation_context.direct_public_headers)
    is listed as well: the _virtual_includes/ path and headers vendored from an
    external repository. Other generated headers and external targets stay out.
  • Reporter (reporter.py): get_covered_files returns raw → normalized
    names and strip_config_prefix drops bazel-out/<config>/bin/, so covmap
    paths compare equal to the allowlist's short_path form; the same
    normalization applies to LCOV SF: records and HTML titles.
    redundant_baseline_variants excludes the baseline archive's variant of a
    header a test binary already covers, so such a header appears once instead
    of twice (the second at 0 %).

Follows the patch candidates of eclipse-score/baselibs#577, but needs no
extra_deps attribute: the aspect handles every workspace target.

Verification

Check Result
New analysis test (strip_include_prefix fixture): allowlist lists both the declared header and the _virtual_includes/ path pass
5 new unit tests: prefix normalization (LCOV, HTML, covered-files map), redundant baseline variants pass
Integration workspace: header-only library behind strip_include_prefix, hand-derived record (3 of 6 lines, one call) added to expected_lcov.dat 15/15 checks pass
Lint (ruff, pylint, ty), format, copyright, self coverage 95.5 % / 87.2 % pass
baselibs //score/flatbuffers/... with this module overridden locally all 13 vendored headers in LCOV and HTML, each exactly once (base.h: 14 of 21 lines)

Notes

  • Reported file name for such headers is the virtual-includes path
    (score/flatbuffers/_virtual_includes/flatbufferscpp/flatbuffers/base.h),
    the identity the compiler records; documented in the known problems and the
    tool requirements.
  • Docs updated: tool_req__coverage_scope_transitive,
    tool_req__coverage_report_relative_paths, release notes, known problems,
    verification report inventory.

eclipse-score/baselibs#558: a workspace target whose hdrs are vendored
from an external repository behind strip_include_prefix
(//score/flatbuffers:flatbufferscpp) lost all its headers from the report.
Two causes: the scope aspect dropped every file under external/, and the
compiler does not even record that path. With strip_include_prefix /
include_prefix Bazel compiles against a generated _virtual_includes/
symlink tree and the coverage mapping names that file, under a
configuration-specific prefix (bazel-out/k8-fastbuild/bin/... in the test
binaries, bazel-out/k8-opt-exec-*/bin/... in the scope's baseline archive).

Aspect: for workspace targets the post-processing identity of the public
headers (CcInfo.compilation_context.direct_public_headers) is listed as
well: the _virtual_includes/ path, and headers a workspace target vendors
from an external repository (external/<repo>/...). Other generated headers
stay out; external targets stay out.

Reporter: get_covered_files returns raw -> normalized names and
strip_config_prefix drops bazel-out/<config>/bin/ so covmap paths compare
equal to the allowlist's short_path form; the same normalization applies
to LCOV SF records and HTML titles. redundant_baseline_variants excludes
the baseline archive's variant of a header that a test binary already
covers, so such a header appears once instead of twice (once at 0 %).

Verification: new analysis test (strip_include_prefix fixture), 5 unit
tests for the normalization and the variant exclusion, and a header-only
library behind strip_include_prefix in the integration workspace whose
hand-derived record (3 of 6 lines, one call) joins expected_lcov.dat; all
15 integration checks pass. Validated on baselibs //score/flatbuffers/...:
the 13 vendored headers appear in LCOV and HTML, each exactly once.

The approach follows the patch candidates of baselibs#577 but needs no
extra_deps attribute: the scope aspect handles it for every workspace
target.

Signed-off-by: Dan Calavrezo <195309321+dcalavrezo-qorix@users.noreply.github.com>
(cherry picked from commit 40b1746)
@github-actions

github-actions Bot commented Sep 11, 2026

Copy link
Copy Markdown

License Check Results

🚀 The license check job ran with the Bazel command:

bazel run //:license-check

Status: ⚠️ Needs Review

Click to expand output
[License Check Output]
Extracting Bazel installation...
Starting local Bazel server (8.6.0) and connecting to it...
INFO: Invocation ID: 489d9ab6-eca7-43bf-8a10-74e06e3dd0f9
Computing main repo mapping: 
Computing main repo mapping: 
Computing main repo mapping: 
Loading: 
Loading: 0 packages loaded
Loading: 0 packages loaded
Loading: 0 packages loaded
Analyzing: target //:license-check (1 packages loaded, 0 targets configured)
Analyzing: target //:license-check (1 packages loaded, 0 targets configured)

Analyzing: target //:license-check (5 packages loaded, 6 targets configured)

Analyzing: target //:license-check (5 packages loaded, 6 targets configured)

Analyzing: target //:license-check (5 packages loaded, 6 targets configured)

Analyzing: target //:license-check (5 packages loaded, 6 targets configured)

Analyzing: target //:license-check (5 packages loaded, 6 targets configured)

Analyzing: target //:license-check (5 packages loaded, 6 targets configured)

Analyzing: target //:license-check (5 packages loaded, 6 targets configured)

Analyzing: target //:license-check (5 packages loaded, 6 targets configured)

Analyzing: target //:license-check (73 packages loaded, 10 targets configured)

Analyzing: target //:license-check (79 packages loaded, 10 targets configured)

Analyzing: target //:license-check (116 packages loaded, 96 targets configured)

Analyzing: target //:license-check (151 packages loaded, 3138 targets configured)

Analyzing: target //:license-check (151 packages loaded, 3138 targets configured)

Analyzing: target //:license-check (151 packages loaded, 3138 targets configured)

Analyzing: target //:license-check (162 packages loaded, 6911 targets configured)

Analyzing: target //:license-check (163 packages loaded, 9464 targets configured)

Analyzing: target //:license-check (173 packages loaded, 9525 targets configured)

Analyzing: target //:license-check (173 packages loaded, 9525 targets configured)

Analyzing: target //:license-check (175 packages loaded, 10168 targets configured)

Analyzing: target //:license-check (176 packages loaded, 11413 targets configured)

Analyzing: target //:license-check (176 packages loaded, 11413 targets configured)

Analyzing: target //:license-check (176 packages loaded, 11413 targets configured)

Analyzing: target //:license-check (177 packages loaded, 11533 targets configured)

INFO: Analyzed target //:license-check (178 packages loaded, 11661 targets configured).
[6 / 16] Creating runfiles tree bazel-out/k8-opt-exec-ST-d57f47055a04/bin/external/score_tooling+/dash/tool/formatters/dash_format_converter.runfiles [for tool]; 0s local
[10 / 16] checking cached actions
[11 / 16] checking cached actions
[14 / 16] checking cached actions
[14 / 16] [Prepa] JavaToolchainCompileBootClasspath external/rules_java+/toolchains/platformclasspath.jar
[15 / 16] Building tools/license.check.license_check.jar (); 0s disk-cache, multiplex-worker
INFO: Found 1 target...
Target //tools:license.check.license_check up-to-date:
  bazel-bin/tools/license.check.license_check
  bazel-bin/tools/license.check.license_check.jar
INFO: Elapsed time: 44.089s, Critical Path: 2.51s
INFO: 16 processes: 12 internal, 3 processwrapper-sandbox, 1 worker.
INFO: Build completed successfully, 16 total actions
INFO: Running command line: bazel-bin/tools/license.check.license_check tools/formatted.txt <args omitted>
usage: org.eclipse.dash.licenses.cli.Main [-batch <int>] [-cd <url>]
       [-confidence <int>] [-ef <url>] [-excludeSources <sources>] [-help] [-lic
       <url>] [-project <shortname>] [-repo <url>] [-review] [-summary <file>]
       [-timeout <seconds>] [-token <token>]

@MaximilianSoerenPollak MaximilianSoerenPollak left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That looks good as far as i can tell.

Explanation makes sense and this for sure should be something that should work.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The requirements conflict and the external-repository regression path lacks automated coverage.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Extends coverage reporting to include vendored and virtual-include headers while normalizing configuration-specific Bazel paths.

Changes:

  • Includes public virtual and externally vendored headers in coverage scope.
  • Normalizes generated-header paths and removes duplicate baseline variants.
  • Adds unit, analysis, integration, and documentation updates.
File summaries
File Description
score_coverage/coverage_scope.bzl Expands header scope collection.
score_coverage/reporter.py Normalizes paths and suppresses duplicates.
score_coverage/tests/reporter_test.py Tests reporter normalization behavior.
score_coverage/tests/starlark/coverage_scope_tests.bzl Tests virtual-header scope collection.
score_coverage/tests/starlark/fixtures/BUILD Defines the analysis fixture.
score_coverage/tests/starlark/fixtures/vendor/include/vendored/api.h Adds the fixture header.
integration_tests/tools/coverage/BUILD Adds the fixture to coverage scope.
integration_tests/src/BUILD Defines the integration library.
integration_tests/src/coverable_test.cpp Exercises the virtual header.
integration_tests/src/vendored/include/vendored/inline_math.h Adds covered and uncovered inline functions.
integration_tests/expected_lcov.dat Adds expected virtual-header coverage.
docs/requirements/tool_requirements.rst Updates scope and path requirements.
docs/verification/verification_report.rst Updates verification inventory.
docs/release/release_notes.rst Documents the feature.
docs/manual/known_problems.rst Documents reported virtual paths.
Review details
  • Files reviewed: 13/15 changed files
  • Comments generated: 2
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +123 to +125
def _test_virtual_include_headers_are_in_scope(name):
coverage_scope(name = name + "_subject", testonly = True, deps = [_FIX + ":vendored"])
analysis_test(name = name, impl = _test_virtual_include_headers_are_in_scope_impl, target = name + "_subject")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done: a small local module (score_coverage/tests/starlark/external_fixture, local_path_override) now provides a header that two fixture targets vendor, once behind strip_include_prefix and once directly. The new tests assert both identities in the allowlist, external/coverage_external_fixture+/include/ext/ext.h and the _virtual_includes/ path, so the ../ -> external/ conversion is exercised.

Comment on lines +45 to +49
For workspace targets it shall additionally list the post-processing
identity of the public headers: the generated ``_virtual_includes/`` path a
header gets through ``strip_include_prefix`` or ``include_prefix`` (the path
the coverage mapping records), and headers a workspace target vendors from
an external repository.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, reworded: tool_req__coverage_scope_excludes now says external targets are not traversed and generated files are not listed, with the two exceptions named in tool_req__coverage_scope_transitive (headers a workspace target declares from an external repository, and the _virtual_includes/ identities of its public headers).

- Analysis tests: a local module (score_coverage/tests/starlark/
  external_fixture, wired via local_path_override) provides a header that
  two workspace fixture targets vendor, once behind strip_include_prefix
  and once directly. The tests assert both identities in the allowlist:
  external/coverage_external_fixture+/include/ext/ext.h and the
  _virtual_includes/ path. This exercises the ../<repo> -> external/<repo>
  conversion that baselibs#558 depends on.
- tool_req__coverage_scope_excludes no longer contradicts
  tool_req__coverage_scope_transitive: external targets are not traversed
  and generated files are not listed, except the two header identities the
  transitive requirement names.
- //:license-check: alias to a dash_license_checker in //tools over the
  Python requirements lock, so the cicd-workflows license check has its
  target. The root package still loads only runtime rules.

Signed-off-by: Dan Calavrezo <195309321+dcalavrezo-qorix@users.noreply.github.com>

@paulquiring paulquiring left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dcalavrezo-qorix
dcalavrezo-qorix merged commit 0231190 into main Sep 11, 2026
9 checks passed
@dcalavrezo-qorix
dcalavrezo-qorix deleted the dcalavrezo_558 branch September 11, 2026 12:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants