-
Notifications
You must be signed in to change notification settings - Fork 5
feat: add Cargo.toml lint profiles for relaxed and strict baselines #11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 11 commits
30d0929
196bba8
b9f249c
786fa7f
70d1884
6950775
be60645
d636d3e
98353ed
c05f47c
44f848a
3d16faf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| 8.6.0 |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,11 +6,12 @@ Centralized Rust linting and formatting policies for the Eclipse Safe Open Vehic | |
| - Distribute those policies as a Bazel module (`score_rust_policies`) so bzlmod users can depend on them directly. | ||
| - Keep tooling configurations (e.g., Clippy, rustfmt) versioned and auditable in one place. | ||
|
|
||
| ## Clippy policy levels | ||
| - `clippy/strict/clippy.toml`: ASIL-B–oriented settings for safety-critical code (enables `pedantic`/`nursery`, disallows `panic`/`unwrap`/`expect`, forbids debug/print macros, and enforces size/complexity thresholds). | ||
| ## Rust lint policy levels | ||
| - `clippy/strict/clippy.toml`: ASIL-B–oriented settings for safety-critical code (enables `pedantic`/`nursery`, checks private items, disallows `panic`/`unwrap`/`expect`, forbids debug/print macros, and enforces size/complexity thresholds). | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the strict-policy intent described here is good, but I do not think msrv = "1.90.0"
check-private-items = trueLints such as Could we either narrow the README wording to say that For the Bazel-native path, If adding Bazel-native strict/relaxed lint targets is more than you want in this PR, I think documenting the current limitation here and opening a follow-up issue for
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed, the wording overstated it. Reworded the "Rust lint policy levels" section to make clear that |
||
| - `clippy/relaxed/clippy.toml`: For tooling, generators, and tests where controlled panics/unwraps and debug printing are acceptable. Still forbids `todo` and `unimplemented`. | ||
| - `lint-profiles/strict/Cargo.toml` / `lint-profiles/relaxed/Cargo.toml`: Corresponding `[lints.rust]`, `[lints.clippy]`, and `[profile.release]` settings for use directly in a project's `Cargo.toml`. The main behavioral split today is that `strict` keeps `unsafe_op_in_unsafe_fn = "deny"`, while `relaxed` downgrades it to `warn`; the rest is currently aligned. See the [SCORE Rust Coding Guidelines](https://eclipse-score.github.io/score/contribute/development/rust/coding_guidelines.html) for the full rationale and coverage matrix. | ||
|
|
||
| ## How to use Clippy in consumers | ||
| ## How to use lint policies in consumers | ||
| - Wire configs in your repo’s `.bazelrc` (mirrors `tests/.bazelrc`): | ||
| ``` | ||
| build:clippy-strict --@rules_rust//rust/settings:clippy.toml=@score_rust_policies//clippy/strict:clippy.toml | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The README says this mirrors
Could we make the names consistent? Otherwise a consumer copying the README cannot compare directly against the test workspace, and the example commands do not match the example config definitions.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unified everything on |
||
|
|
@@ -38,6 +39,40 @@ Centralized Rust linting and formatting policies for the Eclipse Safe Open Vehic | |
| ``` | ||
| Then run `bazel build --config=clippy-strict //:clippy` (or `--config=clippy-relaxed`). | ||
|
|
||
| ## Applying rustc lints in a Bazel-first repo | ||
| The `[lints.rust]` table in `lint-profiles/{strict,relaxed}/Cargo.toml` is a Cargo | ||
| feature and is **not** read by `rules_rust`. For Bazel-only consumers (e.g. | ||
| `baselibs_rust`), the same rustc lints are exported as ready-to-use flag lists in | ||
| [rustc-lints/flags.bzl](rustc-lints/flags.bzl), so they don't have to be redefined. | ||
|
|
||
| - Load the shared flag list and apply it per target: | ||
| ```starlark | ||
| load("@score_rust_policies//rustc-lints:flags.bzl", "STRICT_RUSTC_FLAGS") | ||
|
|
||
| rust_library( | ||
| name = "my_lib", | ||
| srcs = [...], | ||
| rustc_flags = STRICT_RUSTC_FLAGS, # or RELAXED_RUSTC_FLAGS | ||
| ) | ||
| ``` | ||
| - To apply the same lints to every target via a `.bazelrc` config instead, use | ||
| `@rules_rust//rust/settings:extra_rustc_flags`. Note: a `.bazelrc` cannot `load` | ||
| a `.bzl`, so the flags must be repeated literally there: | ||
| ``` | ||
| build:rustc-strict --@rules_rust//rust/settings:extra_rustc_flags=-Wunused,-Dunsafe_op_in_unsafe_fn,-Wmissing_abi,-Wunreachable_pub,-Wmissing_docs,-Wunused_results,-Wlet_underscore_drop,-Wnon_exhaustive_omitted_patterns,-Welided_lifetimes_in_paths,-Wexplicit_outlives_requirements,-Wmacro_use_extern_crate,-Wmeta_variable_misuse,-Wnon_local_definitions,-Wredundant_lifetimes,-Wsingle_use_lifetimes,-Wtrivial_numeric_casts,-Wunit_bindings,-Wunnameable_types,-Wvariant_size_differences | ||
| ``` | ||
| - Combine with the matching Clippy profile when building: | ||
| ``` | ||
| bazel build --config=clippy-strict --config=rustc-strict //src/... | ||
| ``` | ||
|
|
||
| Notes: | ||
| - The flag lists in [rustc-lints/flags.bzl](rustc-lints/flags.bzl) mirror the | ||
| `[lints.rust]` tables in lint-profiles; keep both in sync (there is no automatic | ||
| translation from `[lints.rust]` to rustc flags). | ||
| - Loading the constant (per target) avoids duplicating the flags; the global | ||
| `.bazelrc` path cannot read the `.bzl` and therefore repeats them. | ||
|
|
||
| ## Local validation | ||
| - From `tests/` (consumer workspace with a local_path_override) run: | ||
| - `bazel build --config=strict //:sample_clippy` | ||
|
|
@@ -47,7 +82,7 @@ Centralized Rust linting and formatting policies for the Eclipse Safe Open Vehic | |
| ## Using with Bazel (bzlmod) | ||
| - Add to your `MODULE.bazel`: | ||
| ``` | ||
| bazel_dep(name = "score_rust_policies", version = "0.0.4") | ||
| bazel_dep(name = "score_rust_policies", version = "<latest-version>") | ||
| ``` | ||
| - During local development you can pin a checkout with: | ||
| ``` | ||
|
|
@@ -57,8 +92,8 @@ Centralized Rust linting and formatting policies for the Eclipse Safe Open Vehic | |
| ) | ||
| ``` | ||
| - Reference policy files in Bazel targets with: | ||
| - `@score_rust_policies//clippy:clippy.toml` for safety components. | ||
| - `@score_rust_policies//clippy:clippy_relaxed.toml` for tooling/tests. | ||
| - `@score_rust_policies//clippy/strict:clippy.toml` for safety components. | ||
| - `@score_rust_policies//clippy/relaxed:clippy.toml` for tooling/tests. | ||
| - When running Clippy directly, pass the config you need: `cargo clippy --config-path path/to/clippy/clippy.toml`. | ||
|
|
||
| ## Repository layout | ||
|
|
@@ -67,9 +102,11 @@ Centralized Rust linting and formatting policies for the Eclipse Safe Open Vehic | |
| - `LICENSE.md`: Apache License 2.0. | ||
| - `CONTRIBUTION.md`: contribution process and links to S-CORE guidelines. | ||
| - `.gitignore`: common ignores for Bazel and development tooling. | ||
| - `clippy/`: Clippy configs exported as `@score_rust_policies//clippy/{strict,relaxed}:clippy.toml`. | ||
| - `clippy/`: Clippy-only configs exported as `@score_rust_policies//clippy/{strict,relaxed}:clippy.toml`. | ||
| - `lint-profiles/`: Cargo lint profiles exported as `@score_rust_policies//lint-profiles/{strict,relaxed}:Cargo.toml`. | ||
| - `rustc-lints/`: rustc lint flag lists for Bazel consumers, exported as `@score_rust_policies//rustc-lints:flags.bzl` (`STRICT_RUSTC_FLAGS` / `RELAXED_RUSTC_FLAGS`). | ||
| - `tests/`: consumer workspace that depends on this module via `local_path_override` and runs Clippy with strict/relaxed configs. | ||
| - (planned) `rustfmt/`: rustfmt defaults when added. | ||
| - `rustfmt/`: rustfmt defaults. | ||
|
|
||
| ## Contributing | ||
| See `CONTRIBUTION.md` for how to propose and review policy changes. All contributions require ECA/DCO sign-off and follow the Eclipse Foundation project handbook. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,5 @@ | ||
| # clippy.toml - ASIL-B profile, compatible with your Clippy version | ||
| # License: Apache-2.0 (see LICENSE.md). | ||
|
|
||
| msrv = "1.90.0" | ||
| msrv = "1.90.0" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we clarify the intended MSRV here? My understanding is that Clippy Could we either align these values, lower the Clippy
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Documented the relationship in both |
||
| check-private-items = true | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| # ******************************************************************************* | ||
| # 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(["Cargo.toml"], visibility = ["//visibility:public"]) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| # Cargo.toml lint profile – safety-oriented practical baseline | ||
| # License: Apache-2.0 (see LICENSE.md). | ||
| # | ||
| # Background and rationale: https://eclipse-score.github.io/score/contribute/development/rust/coding_guidelines.html | ||
| # | ||
| # Copy the [lints.rust], [lints.clippy], and [profile.release] sections below | ||
| # into your project's Cargo.toml to adopt the SCORE practical baseline. | ||
|
|
||
| # Rust compiler lints (rustc) | ||
| [lints.rust] | ||
| # Relaxed baseline keeps the lint visible but does not fail the build. | ||
| unsafe_op_in_unsafe_fn = "warn" | ||
| missing_abi = "warn" | ||
| unreachable_pub = "warn" | ||
| missing_docs = "warn" | ||
| unused_results = "warn" | ||
| let_underscore_drop = "warn" | ||
| non_exhaustive_omitted_patterns = "warn" | ||
|
|
||
| # Rustc lints recommended to evaluate as warn | ||
| elided_lifetimes_in_paths = "warn" | ||
| explicit_outlives_requirements = "warn" | ||
| macro_use_extern_crate = "warn" | ||
| meta_variable_misuse = "warn" | ||
| non_local_definitions = "warn" | ||
| redundant_lifetimes = "warn" | ||
| single_use_lifetimes = "warn" | ||
| trivial_numeric_casts = "warn" | ||
| unit_bindings = "warn" | ||
| unnameable_types = "warn" | ||
| variant_size_differences = "warn" | ||
|
|
||
| # Edition and compatibility lint groups (baseline intent) | ||
| # Enable rust-<YEAR>-* and keyword-idents-<YEAR> lints supported by the | ||
| # pinned compiler version. | ||
| unused = { level = "warn", priority = -1 } | ||
|
|
||
| # Future/availability-dependent rustc lints (enable when available in | ||
| # the selected toolchain) | ||
| # must_not_suspend = "warn" | ||
| # fuzzy_provenance_casts = "warn" | ||
| # lossy_provenance_casts = "warn" | ||
|
|
||
| # Clippy lints | ||
| [lints.clippy] | ||
| # Warn | ||
| as_underscore = "warn" | ||
| cast_lossless = "warn" | ||
| cast_possible_truncation = "warn" | ||
| cast_possible_wrap = "warn" | ||
| cast_sign_loss = "warn" | ||
| cast_ptr_alignment = "warn" | ||
| exit = "warn" | ||
| format_push_string = "warn" | ||
| infinite_loop = "warn" | ||
| iter_over_hash_type = "warn" | ||
| invalid_upcast_comparisons = "warn" | ||
| lossy_float_literal = "warn" | ||
| missing_errors_doc = "warn" | ||
| missing_docs_in_private_items = "warn" | ||
| panic_in_result_fn = "warn" | ||
| ptr_cast_constness = "warn" | ||
| ref_as_ptr = "warn" | ||
| transmute_ptr_to_ptr = "warn" | ||
| redundant_type_annotations = "warn" | ||
| shadow_reuse = "warn" | ||
| shadow_unrelated = "warn" | ||
| try_err = "warn" | ||
| wildcard_enum_match_arm = "warn" | ||
|
|
||
| # Deny | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The relaxed profile still denies several lints, including Could we document the intended boundary a bit more explicitly? In particular, it would help to say which safety/security lints remain hard errors even in the relaxed profile, and which lints are intentionally downgraded for tooling/test code. This does not necessarily need to block this PR if the current deny list is intentional. If the boundary is still being worked out, a short README note plus a follow-up issue for the full strict/relaxed policy matrix would be enough from my perspective.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added a "Relaxed profile boundary" section to the README spelling out which safety/doc lints stay hard errors even in relaxed ( |
||
| as_ptr_cast_mut = "deny" | ||
| let_underscore_must_use = "deny" | ||
| missing_panics_doc = "deny" | ||
| undocumented_unsafe_blocks = "deny" | ||
| wildcard_imports = "deny" | ||
| declare_interior_mutable_const = "deny" | ||
|
|
||
| # Allow | ||
| shadow_same = "allow" | ||
| implicit_return = "allow" | ||
| allow_attributes = "allow" | ||
|
|
||
| # Evaluate for helpfulness | ||
| panicking_overflow_checks = "warn" | ||
| unwrap_used = "warn" | ||
|
|
||
| # Recommended against because too coarse | ||
| as_conversions = "allow" | ||
|
|
||
| # Release profile requirement | ||
| [profile.release] | ||
| overflow-checks = true # Required for safety-oriented integer checks | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| # ******************************************************************************* | ||
| # 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(["Cargo.toml"], visibility = ["//visibility:public"]) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| # Cargo.toml lint profile – safety-oriented strict/ASIL variant | ||
| # License: Apache-2.0 (see LICENSE.md). | ||
| # | ||
| # Background and rationale: https://eclipse-score.github.io/score/contribute/development/rust/coding_guidelines.html | ||
| # | ||
| # Copy the [lints.rust], [lints.clippy], and [profile.release] sections below | ||
| # into your project's Cargo.toml to adopt the SCORE strict/ASIL baseline. | ||
| # Also enable "check-private-items = true" in clippy.toml for this profile. | ||
|
|
||
| # Rust compiler lints (strict) | ||
| [lints.rust] | ||
| unsafe_op_in_unsafe_fn = "deny" | ||
| missing_abi = "warn" | ||
| unreachable_pub = "warn" | ||
| missing_docs = "warn" | ||
| unused_results = "warn" | ||
| let_underscore_drop = "warn" | ||
| non_exhaustive_omitted_patterns = "warn" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The same warning appears through the Bazel rustc flag list ( Could we gate this lint by supported toolchain, remove it from the default stable baseline until it is available without
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed it shouldn't inject a warning into a warning-free safety build on stable. Commented it out in both Cargo profiles and removed |
||
|
|
||
| # Rustc lints recommended to evaluate as warn | ||
| elided_lifetimes_in_paths = "warn" | ||
| explicit_outlives_requirements = "warn" | ||
| macro_use_extern_crate = "warn" | ||
| meta_variable_misuse = "warn" | ||
| non_local_definitions = "warn" | ||
| redundant_lifetimes = "warn" | ||
| single_use_lifetimes = "warn" | ||
| trivial_numeric_casts = "warn" | ||
| unit_bindings = "warn" | ||
| unnameable_types = "warn" | ||
| variant_size_differences = "warn" | ||
|
|
||
| # Edition and compatibility lint groups (baseline intent) | ||
| unused = { level = "warn", priority = -1 } | ||
|
|
||
| # Clippy lints (strict) | ||
| [lints.clippy] | ||
| # Warn | ||
| as_underscore = "warn" | ||
| cast_lossless = "warn" | ||
| cast_possible_truncation = "warn" | ||
| cast_possible_wrap = "warn" | ||
| cast_sign_loss = "warn" | ||
| cast_ptr_alignment = "warn" | ||
| exit = "warn" | ||
| format_push_string = "warn" | ||
| infinite_loop = "warn" | ||
| iter_over_hash_type = "warn" | ||
| invalid_upcast_comparisons = "warn" | ||
| lossy_float_literal = "warn" | ||
| missing_errors_doc = "warn" | ||
| missing_docs_in_private_items = "warn" | ||
| panic_in_result_fn = "warn" | ||
| ptr_cast_constness = "warn" | ||
| ref_as_ptr = "warn" | ||
| transmute_ptr_to_ptr = "warn" | ||
| redundant_type_annotations = "warn" | ||
| shadow_reuse = "warn" | ||
| shadow_unrelated = "warn" | ||
| try_err = "warn" | ||
| wildcard_enum_match_arm = "warn" | ||
|
|
||
| # Deny | ||
| as_ptr_cast_mut = "deny" | ||
| let_underscore_must_use = "deny" | ||
| missing_panics_doc = "deny" | ||
| undocumented_unsafe_blocks = "deny" | ||
| wildcard_imports = "deny" | ||
| declare_interior_mutable_const = "deny" | ||
|
|
||
| # Allow | ||
| shadow_same = "allow" | ||
| implicit_return = "allow" | ||
| allow_attributes = "allow" | ||
|
|
||
| # Evaluate for helpfulness | ||
| panicking_overflow_checks = "warn" | ||
| unwrap_used = "warn" | ||
|
|
||
| # Recommended against because too coarse | ||
| as_conversions = "allow" | ||
|
|
||
| # Release profile requirement | ||
| [profile.release] | ||
| overflow-checks = true | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| # ******************************************************************************* | ||
| # 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(["flags.bzl"], visibility = ["//visibility:public"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The workflow currently builds
//:sample_clippywith the strict and relaxed Clippy configs, but it does not appear to exercise the newlint-profiles/{strict,relaxed}/Cargo.tomlfiles orrustc-lints/flags.bzl.This matters because the PR currently seems to contain a concrete Cargo/Bazel drift bug:
lint-profiles/relaxed/Cargo.tomlsetsunsafe_op_in_unsafe_fn = "warn", whileRELAXED_RUSTC_FLAGSuses-Dunsafe_op_in_unsafe_fn.Could we add at least a small check that compares the Cargo
[lints.rust]levels againstSTRICT_RUSTC_FLAGSandRELAXED_RUSTC_FLAGS? That would catch the current drift without requiring a large integration test.It would also be useful, either here or in follow-up issues, to verify that the strict/relaxed profiles differ only where intended and that the exported Bazel labels for the new files are loadable by a consumer workspace. If this PR grows Bazel-native Clippy lint support via
rust_lint_config, then a small consumer probe for representative Clippy denies such asunwrap_used,expect_used,panic,print_stdout, anddbg_macrowould be a good regression test for that path too.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added
tools/check_lint_sync.py, run as a CI step, which translates each Cargo[lints.rust]table into rustc flags and diffs them againstSTRICT_RUSTC_FLAGS/RELAXED_RUSTC_FLAGS. It catches exactly the-Dvs-Wdrift you found (verified locally: passes now, fails if I reintroduce the bug). A full Bazel-native Clippy-deny regression test (unwrap_used,expect_used, etc. viarust_lint_config) is tracked as a follow-up.