Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
bazel-*
.bazel-*

# Generated coverage reports (output from `bazel run @score_cpp_policies//coverage:generate_coverage_html`)
cpp_coverage/
*/cpp_coverage/

# IDE files
.vscode/
.idea/
Expand Down
23 changes: 23 additions & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,26 @@ bazel_dep(name = "bazel_skylib", version = "1.8.2")
bazel_dep(name = "platforms", version = "0.0.10")
bazel_dep(name = "rules_cc", version = "0.2.17")
bazel_dep(name = "aspect_rules_lint", version = "2.5.0")

# ---------------------------------------------------------------------------
# Coverage tooling (//coverage/...). Hosts the merger/reporter/justify/
# effective_coverage Python binaries and the shell driver. Consumers do not
# need rules_python themselves to use //coverage:reporter — it is wired in
# here once for the whole policies module.
# ---------------------------------------------------------------------------
bazel_dep(name = "rules_python", version = "1.8.5")
bazel_dep(name = "rules_shell", version = "0.3.0")

python = use_extension("@rules_python//python/extensions:python.bzl", "python")
python.toolchain(
python_version = "3.12",
is_default = True,
)

pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip")
pip.parse(
hub_name = "score_cpp_policies_pip",
python_version = "3.12",
requirements_lock = "//coverage:requirements_lock.txt",
)
use_repo(pip, "score_cpp_policies_pip")
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# score_cpp_policies

Centralized C++ quality tool policies for Eclipse S-CORE, providing sanitizer
configurations and clang-tidy integration reusable across all S-CORE modules
(logging, communication, baselibs, etc.).
configurations, clang-tidy integration and source-based code coverage
reusable across all S-CORE modules (logging, communication, baselibs, etc.).

Planned: clang-format, code coverage policies.
Planned: clang-format.

## What This Provides

Expand All @@ -15,6 +15,10 @@ Planned: clang-format, code coverage policies.
- **Constraint system** — `target_compatible_with` settings for sanitizer-incompatible targets
- **`clang_tidy/.clang-tidy`** — centralized default check set (conservative baseline, tailorable per module)
- **`clang_tidy/clang_tidy.bazelrc`** — `--config=clang-tidy` bazelrc config consumers can import
- **`//coverage:reporter` + `score_coverage_reporter` macro** — llvm-cov source-based
coverage with a shared baseline of ignore regexes (test/mock/fake/external), pluggable
per-module extensions and an effective-coverage justification post-processor.
See [`coverage/README.md`](coverage/README.md) for the seven-step adoption guide.

## Available Sanitizer Configurations

Expand Down Expand Up @@ -54,6 +58,10 @@ bazel_dep(name = "score_cpp_policies")

Copy [`sanitizers/sanitizers.bazelrc`](sanitizers/sanitizers.bazelrc) into your repository's `.bazelrc`.

### Configure Coverage

See [`coverage/README.md`](coverage/README.md).

### Run Tests

```bash
Expand Down
97 changes: 97 additions & 0 deletions coverage/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# *******************************************************************************
# Copyright (c) 2026 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
#
# This program and the accompanying materials are made available under the
# terms of the Apache License Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0
#
# SPDX-License-Identifier: Apache-2.0
# *******************************************************************************

load("@rules_python//python:defs.bzl", "py_binary", "py_library")
load("@rules_shell//shell:sh_binary.bzl", "sh_binary")

package(default_visibility = ["//visibility:public"])

# Files consumers may reference directly (e.g. .bazelrc imports, custom macros).
exports_files([
"coverage.bazelrc",
"filter_regexes.txt",
"generate_coverage_html.sh",
])

# ---------------------------------------------------------------------------
# Per-test coverage merger.
# Bazel calls this as --coverage_output_generator once per test; it takes
# profraw files + the source-file manifest, merges them with llvm-profdata
# and packages everything (profdata + object-file list) into a zip that the
# reporter later aggregates.
# ---------------------------------------------------------------------------
py_binary(
name = "merger",
srcs = ["merger.py"],
)

# ---------------------------------------------------------------------------
# Final coverage reporter (HTML / LCOV / text).
# Invoked indirectly via the per-consumer wrapper produced by
# `score_coverage_reporter` (see defs.bzl). Reads per-test zips, merges all
# profdata, then calls llvm-cov to render the combined report.
#
# Note: this target intentionally does NOT carry the llvm-cov / llvm-profdata
# binaries in its `data` — the consumer-side wrapper supplies them by label,
# letting each consumer pick its own llvm_toolchain repository name and
# version (see score_coverage_reporter in coverage/defs.bzl).
# ---------------------------------------------------------------------------
py_library(
name = "reporter_lib",
srcs = ["reporter.py"],
imports = [".."],
deps = ["@rules_python//python/runfiles"],
)

py_binary(
name = "reporter",
srcs = ["reporter.py"],
deps = ["@rules_python//python/runfiles"],
)

# ---------------------------------------------------------------------------
# Coverage justification processor.
# Reads a YAML database of justifications + scans source for COV_JUSTIFIED
# markers and emits a manifest of (file, line) -> justification.
# ---------------------------------------------------------------------------
py_binary(
name = "justify",
srcs = ["justify.py"],
deps = [
"@score_cpp_policies_pip//pyyaml",
],
)

# ---------------------------------------------------------------------------
# Effective coverage calculator + HTML post-processor.
# Takes the llvm-cov HTML report and the resolved justification manifest;
# rewrites the HTML to highlight justified lines and emits effective
# coverage statistics.
# ---------------------------------------------------------------------------
py_binary(
name = "effective_coverage",
srcs = ["effective_coverage.py"],
)

# ---------------------------------------------------------------------------
# Generic post-`bazel coverage` driver. Consumers invoke this via
# `bazel run @score_cpp_policies//coverage:generate_coverage_html -- [flags]`.
# ---------------------------------------------------------------------------
sh_binary(
name = "generate_coverage_html",
srcs = ["generate_coverage_html.sh"],
data = [
":justify",
":effective_coverage",
],
)
Loading