diff --git a/.github/PULL_REQUEST_TEMPLATE/improvement.md b/.github/PULL_REQUEST_TEMPLATE/improvement.md index 090ad43..7c992be 100644 --- a/.github/PULL_REQUEST_TEMPLATE/improvement.md +++ b/.github/PULL_REQUEST_TEMPLATE/improvement.md @@ -13,7 +13,7 @@ ## Related ticket > [!IMPORTANT] -> Please replace `[ISSUE-NUMBER]` with the issue-number that tracks this bug fix. If there is no such +> Please replace `[ISSUE-NUMBER]` with the issue-number that tracks this improvement. If there is no such > ticket yet, create one via [this issue template](../ISSUE_TEMPLATE/new?template=improvement.md). closes [ISSUE-NUMBER] (improvement ticket) diff --git a/MODULE.bazel b/MODULE.bazel index ac5b607..72af2a9 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -11,9 +11,14 @@ # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -module(name = "score_cpp_policies") +module( + name = "score_cpp_policies", + version = "0.0.0", +) bazel_dep(name = "bazel_skylib", version = "1.8.2") bazel_dep(name = "platforms", version = "0.0.10") bazel_dep(name = "rules_cc", version = "0.1.5") +bazel_dep(name = "aspect_rules_lint", version = "2.5.0") + diff --git a/README.md b/README.md index 707ea02..58470dc 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,7 @@ cd tests bazel test --config=asan_ubsan_lsan //... bazel test --config=tsan //... +bazel test --config=clang-tidy //... ``` ## Contributing diff --git a/clang_tidy/.clang-tidy b/clang_tidy/.clang-tidy new file mode 100644 index 0000000..19502ce --- /dev/null +++ b/clang_tidy/.clang-tidy @@ -0,0 +1,39 @@ +# ******************************************************************************* +# 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 +# ******************************************************************************* + +--- +# Default clang-tidy configuration for S-CORE C++ modules. +# NOTE: the set of enabled checks is yet subject to be tailored per module. +Checks: >- + -*, + clang-analyzer-*, + cert-*, + cppcoreguidelines-*, + bugprone-*, + misc-*, + performance-*, + readability-*, + modernize-* + +# NOTE: WarningsAsErrors is yet subject to be expanded per module as compliance increases. +WarningsAsErrors: >- + clang-analyzer-* + +# Exclude third-party and generated headers from analysis. +HeaderFilterRegex: '^(?!.*/(third_party|bazel-out|external)/).*$' + +FormatStyle: file + +# NOTE: CheckOptions are yet subject to be provided for each enabled check per module. +#CheckOptions: +# none yet diff --git a/clang_tidy/BUILD.bazel b/clang_tidy/BUILD.bazel new file mode 100644 index 0000000..b2ad96f --- /dev/null +++ b/clang_tidy/BUILD.bazel @@ -0,0 +1,19 @@ +# ******************************************************************************* +# 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 +# ******************************************************************************* + +exports_files( + [ + ".clang-tidy", + ], + visibility = ["//visibility:public"], +) diff --git a/clang_tidy/README.md b/clang_tidy/README.md new file mode 100644 index 0000000..b6921cb --- /dev/null +++ b/clang_tidy/README.md @@ -0,0 +1,67 @@ +# Clang-Tidy Integration + +Centralized clang-tidy configuration and Bazel macros for Eclipse S-CORE C++ modules. + +## What This Provides + +- **`//clang_tidy:defs.bzl`** — `make_clang_tidy_aspect` / `make_clang_tidy_test` macros wrapping `aspect_rules_lint` +- **`clang_tidy/.clang-tidy`** — default S-CORE check set (conservative baseline, tailorable per module) + +## Usage + +### Add Dependency + +```python +bazel_dep(name = "score_cpp_policies", version = "0.0.0") +bazel_dep(name = "toolchains_llvm", version = "1.5.0") +``` + +Set up `@llvm_toolchain` via the `llvm` extension (see `tests/MODULE.bazel` for an example). + +### Add the Bazelrc Snippet + +There is no importable `.bazelrc` from an external module — `%workspace%` resolves to the +consuming workspace, not to `@score_cpp_policies`. Copy these lines into your own `.bazelrc` +instead: + +```bazelrc +test:clang-tidy --output_groups=+rules_lint_report +# Pin the LLVM toolchain for clang-tidy — adjust the target for your host arch: +test:clang-tidy --extra_toolchains=@llvm_toolchain//:cc-toolchain-x86_64-linux +test:clang-tidy --aspects=//tools/lint:linters.bzl%clang_tidy_aspect +``` + +> **Note**: The `--extra_toolchains` line hard-codes `x86_64-linux`. On AArch64 hosts (Apple +> Silicon CI runners, etc.) replace it with `cc-toolchain-aarch64-linux`. + +### Create `tools/lint/linters.bzl` + +```python +load("@score_cpp_policies//clang_tidy:defs.bzl", "make_clang_tidy_aspect", "make_clang_tidy_test") + +clang_tidy_aspect = make_clang_tidy_aspect( + # binary MUST be a Label literal here — string labels silently resolve to the wrong repo. + binary = Label("@llvm_toolchain//:clang-tidy"), + configs = [Label("//:.clang-tidy")], +) + +clang_tidy_test = make_clang_tidy_test(aspect = clang_tidy_aspect) +``` + +### Add a `.clang-tidy` Config + +Place a `.clang-tidy` at your repo root. Use +[`@score_cpp_policies//clang_tidy:.clang-tidy`](.clang-tidy) as the starting point. + +> **Advisory checks**: The enabled checks (`cppcoreguidelines-*`, `modernize-*`, etc.) are +> advisory — only `clang-analyzer-*` is `WarningsAsErrors`. Module owners should tighten +> `WarningsAsErrors` incrementally as compliance improves. + +### Run + +```bash +# Lint all C++ targets +bazel test --config=clang-tidy //... +``` + +Reports are written to `bazel-out/.../rules_lint_report/` as text files. diff --git a/clang_tidy/defs.bzl b/clang_tidy/defs.bzl new file mode 100644 index 0000000..4f0618c --- /dev/null +++ b/clang_tidy/defs.bzl @@ -0,0 +1,79 @@ +# ******************************************************************************* +# 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 +# ******************************************************************************* + +"""Clang-tidy support macros for S-CORE C++ modules. + +Provides macros to create a clang-tidy aspect and test rule with S-CORE defaults. +Consuming projects call make_clang_tidy_aspect() in their own linters.bzl to +create a project-specific aspect bound to their toolchain and .clang-tidy config. + +Example usage in your project's tools/lint/linters.bzl: + + load("@score_cpp_policies//clang_tidy:defs.bzl", "make_clang_tidy_aspect", "make_clang_tidy_test") + + clang_tidy_aspect = make_clang_tidy_aspect( + binary = Label("@llvm_toolchain//:clang-tidy"), + configs = [Label("//:.clang-tidy")], + ) + + clang_tidy_test = make_clang_tidy_test(aspect = clang_tidy_aspect) +""" + +load("@aspect_rules_lint//lint:clang_tidy.bzl", "lint_clang_tidy_aspect") +load("@aspect_rules_lint//lint:lint_test.bzl", "lint_test") + +def make_clang_tidy_aspect( + binary, + configs, + lint_target_headers = True, + angle_includes_are_system = True, + verbose = False): + """Creates a clang-tidy lint aspect with S-CORE defaults. + + Args: + binary: Label of the clang-tidy binary. + Must be resolved in the calling .bzl file's repository context, + e.g. Label("@llvm_toolchain//:clang-tidy"). + configs: List of Labels to .clang-tidy config files that clang-tidy needs + as inputs, e.g. [Label("//:.clang-tidy")]. + lint_target_headers: Whether to lint headers owned by analyzed targets (default: True). + angle_includes_are_system: Treat angle bracket includes as system headers (default: True). + verbose: Enable verbose clang-tidy output (default: False). + + Returns: + A clang-tidy aspect. Assign to a top-level variable in your .bzl file + so it can be referenced via --aspects= in .bazelrc. + """ + return lint_clang_tidy_aspect( + binary = binary, + configs = configs, + lint_target_headers = lint_target_headers, + angle_includes_are_system = angle_includes_are_system, + verbose = verbose, + ) + +def make_clang_tidy_test(aspect): + """Creates a clang-tidy lint test rule for per-target testing. + + Args: + aspect: The clang-tidy aspect returned by make_clang_tidy_aspect(). + + Returns: + A rule that can be instantiated in BUILD files to run clang-tidy + on individual cc_library / cc_binary / cc_test targets. + + Example usage in a BUILD file: + load("//tools/lint:linters.bzl", "clang_tidy_test") + clang_tidy_test(name = "my_lib_tidy", srcs = [":my_lib"]) + """ + return lint_test(aspect = aspect) diff --git a/tests/.bazelrc b/tests/.bazelrc index d2b7f84..e1930d9 100644 --- a/tests/.bazelrc +++ b/tests/.bazelrc @@ -14,6 +14,11 @@ # Import centralized sanitizer configurations import %workspace%/../sanitizers/sanitizers.bazelrc +# Clang-tidy: bazel test --config=clang-tidy //... +test:clang-tidy --aspects=//tools/lint:linters.bzl%clang_tidy_aspect +test:clang-tidy --output_groups=+rules_lint_report +test:clang-tidy --extra_toolchains=@llvm_toolchain//:cc-toolchain-x86_64-linux + common --registry=https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/ common --registry=https://bcr.bazel.build diff --git a/tests/.clang-tidy b/tests/.clang-tidy new file mode 100644 index 0000000..c234a7f --- /dev/null +++ b/tests/.clang-tidy @@ -0,0 +1,27 @@ +# ******************************************************************************* +# 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 +# ******************************************************************************* + +--- +# Clang-tidy configuration for the score_cpp_policies test workspace. +# NOTE: conservative check set so that existing sample_test.cpp passes cleanly. +Checks: > + -*, + clang-analyzer-*, + bugprone-* + +WarningsAsErrors: "" + +# Exclude third-party and googletest headers from analysis. +HeaderFilterRegex: '^(?!.*/third_party/)(?!.*/googletest/).*' + +FormatStyle: file diff --git a/tests/BUILD.bazel b/tests/BUILD.bazel index 7a4a276..40f1317 100644 --- a/tests/BUILD.bazel +++ b/tests/BUILD.bazel @@ -13,6 +13,9 @@ load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_test") +# Required as input to the clang-tidy aspect (configs = [Label("//:.clang-tidy")]). +exports_files([".clang-tidy"]) + # ============================================================================== # Positive tests - verify clean code passes with all sanitizers # ============================================================================== diff --git a/tests/MODULE.bazel b/tests/MODULE.bazel index 62d0e1b..ad2800c 100644 --- a/tests/MODULE.bazel +++ b/tests/MODULE.bazel @@ -13,19 +13,27 @@ module( name = "score_cpp_policies_tests", + version = "0.0.0", ) bazel_dep(name = "googletest", version = "1.17.0.bcr.2") -bazel_dep(name = "rules_cc", version = "0.1.5") -bazel_dep(name = "toolchains_llvm", version = "1.7.0") +bazel_dep(name = "rules_cc", version = "0.2.17") + +bazel_dep(name = "rules_go", version = "0.60.0", repo_name = "io_bazel_rules_go") -bazel_dep(name = "score_cpp_policies") +bazel_dep(name = "score_cpp_policies", version = "0.0.0") local_path_override( module_name = "score_cpp_policies", path = "..", ) -llvm = use_extension("@toolchains_llvm//toolchain/extensions:llvm.bzl", "llvm") +# LLVM toolchain for clang-tidy (provides @llvm_toolchain//:clang-tidy). +bazel_dep(name = "toolchains_llvm", version = "1.7.0") + +llvm = use_extension( + "@toolchains_llvm//toolchain/extensions:llvm.bzl", + "llvm", +) llvm.toolchain( llvm_version = "19.1.7", extra_known_features = [ diff --git a/tests/tools/lint/BUILD.bazel b/tests/tools/lint/BUILD.bazel new file mode 100644 index 0000000..206c4e4 --- /dev/null +++ b/tests/tools/lint/BUILD.bazel @@ -0,0 +1,17 @@ +# ******************************************************************************* +# 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 +# ******************************************************************************* + +exports_files( + ["linters.bzl"], + visibility = ["//visibility:public"], +) diff --git a/tests/tools/lint/linters.bzl b/tests/tools/lint/linters.bzl new file mode 100644 index 0000000..6e1c4e4 --- /dev/null +++ b/tests/tools/lint/linters.bzl @@ -0,0 +1,23 @@ +# ******************************************************************************* +# 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 +# ******************************************************************************* + +"""Clang-tidy aspect and test rule for the score_cpp_policies test workspace.""" + +load("@score_cpp_policies//clang_tidy:defs.bzl", "make_clang_tidy_aspect", "make_clang_tidy_test") + +clang_tidy_aspect = make_clang_tidy_aspect( + binary = Label("@llvm_toolchain//:clang-tidy"), + configs = [Label("//:.clang-tidy")], +) + +clang_tidy_test = make_clang_tidy_test(aspect = clang_tidy_aspect)