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
1 change: 1 addition & 0 deletions .bazelversion
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
8.6.0
8 changes: 6 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,16 @@ on:
jobs:
bazel-test:
runs-on: ubuntu-latest
env:
USE_BAZEL_VERSION: 8.6.0

Copy link
Copy Markdown

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_clippy with the strict and relaxed Clippy configs, but it does not appear to exercise the new lint-profiles/{strict,relaxed}/Cargo.toml files or rustc-lints/flags.bzl.

This matters because the PR currently seems to contain a concrete Cargo/Bazel drift bug: lint-profiles/relaxed/Cargo.toml sets unsafe_op_in_unsafe_fn = "warn", while RELAXED_RUSTC_FLAGS uses -Dunsafe_op_in_unsafe_fn.

Could we add at least a small check that compares the Cargo [lints.rust] levels against STRICT_RUSTC_FLAGS and RELAXED_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 as unwrap_used, expect_used, panic, print_stdout, and dbg_macro would be a good regression test for that path too.

Copy link
Copy Markdown
Author

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 against STRICT_RUSTC_FLAGS/RELAXED_RUSTC_FLAGS. It catches exactly the -D vs -W drift 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. via rust_lint_config) is tracked as a follow-up.

steps:
- uses: actions/checkout@v4
- name: Install Bazelisk
uses: bazelbuild/setup-bazelisk@v3
- name: Check Cargo/Bazel rustc lint profile sync
run: python3 tools/check_lint_sync.py
- name: Run Clippy config tests
working-directory: tests
run: |
bazel build --config=strict //:sample_clippy
bazel build --config=relaxed //:sample_clippy
bazel build --config=clippy-strict //:sample_clippy
bazel build --config=clippy-relaxed //:sample_clippy
4,460 changes: 4,394 additions & 66 deletions MODULE.bazel.lock

Large diffs are not rendered by default.

81 changes: 69 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,30 @@ 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).
- `clippy/relaxed/clippy.toml`: For tooling, generators, and tests where controlled panics/unwraps and debug printing are acceptable. Still forbids `todo` and `unimplemented`.
## Rust lint policy levels
Lint *levels* (which lints warn or are hard errors) come from the Cargo
`[lints.rust]` / `[lints.clippy]` tables in `lint-profiles/` (or, for Bazel-first
repos, from `rustc-lints/flags.bzl` and `rules_rust` lint config). The
`clippy.toml` files only configure Clippy *options* (e.g. `msrv`,
`check-private-items`, thresholds, allowed/disallowed names); they do not by
themselves set the `unwrap_used`/`panic`/`print_stdout` levels.

## How to use Clippy in consumers
- `clippy/strict/clippy.toml`: ASIL-B–oriented Clippy *options* for safety-critical code (sets `msrv`, checks private items, and tunes size/complexity thresholds). Pair it with `lint-profiles/strict/Cargo.toml` (or `STRICT_RUSTC_FLAGS`) to actually enforce the `pedantic`/`nursery` and `panic`/`unwrap`/`expect`/debug-macro levels.
- `clippy/relaxed/clippy.toml`: Clippy *options* for tooling, generators, and tests. Pair it with `lint-profiles/relaxed/Cargo.toml` for the relaxed lint levels.
- `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.

### Relaxed profile boundary
The relaxed profile is meant for tooling, generators, and tests where controlled
panics/unwraps and debug printing are acceptable, so lints like `unwrap_used` and
debug-macro checks are downgraded to `warn`. It intentionally keeps several
safety/documentation lints as hard errors (`deny`), including
`missing_panics_doc`, `undocumented_unsafe_blocks`, `wildcard_imports`, and
`declare_interior_mutable_const`. The only rustc level that currently differs
between strict and relaxed is `unsafe_op_in_unsafe_fn` (`deny` in strict, `warn`
in relaxed).


## 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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The README says this mirrors tests/.bazelrc, but the config names differ:

  • README uses build:clippy-strict and build:clippy-relaxed.
  • tests/.bazelrc uses build:strict and build:relaxed.
  • The validation instructions later use bazel build --config=strict and --config=relaxed.

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.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Unified everything on clippy-strict/clippy-relaxed: tests/.bazelrc, the workflow, and the README validation commands now use the same names, so a consumer can copy directly from the README and compare against the test workspace.

Expand Down Expand Up @@ -38,16 +57,51 @@ 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,-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). `tools/check_lint_sync.py`
(run in CI) fails if they drift apart.
- 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`
- `bazel build --config=relaxed //:sample_clippy`
- The `tests/.bazelrc` sets the strict/relaxed Clippy configs to `@score_rust_policies//clippy/{strict,relaxed}:clippy.toml` via `@rules_rust//rust/settings:clippy.toml`.
- `bazel build --config=clippy-strict //:sample_clippy`
- `bazel build --config=clippy-relaxed //:sample_clippy`
- The `tests/.bazelrc` sets the `clippy-strict`/`clippy-relaxed` Clippy configs to `@score_rust_policies//clippy/{strict,relaxed}:clippy.toml` via `@rules_rust//rust/settings:clippy.toml`.

## 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:
```
Expand All @@ -57,8 +111,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
Expand All @@ -67,9 +121,12 @@ 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`).
- `tools/`: maintenance scripts, including `check_lint_sync.py`, which verifies the `flags.bzl` lists stay in sync with the Cargo `[lints.rust]` tables.
- `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.
Expand Down
6 changes: 5 additions & 1 deletion clippy/relaxed/clippy.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# Clippy configuration for tooling, generators, and test-only code.
# License: Apache-2.0 (see LICENSE.md).

#
# `msrv` is the minimum Rust version this policy targets; it drives Clippy's
# MSRV-aware lint suggestions. It is intentionally independent of the toolchain
# pinned by the test workspace in tests/MODULE.bazel (currently 1.85.0), which
# only validates that the config wiring loads.
msrv = "1.90.0"
10 changes: 8 additions & 2 deletions clippy/strict/clippy.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
# clippy.toml - ASIL-B profile, compatible with your Clippy version
# License: Apache-2.0 (see LICENSE.md).

msrv = "1.90.0"
#
# `msrv` is the minimum Rust version this policy targets; it drives Clippy's
# MSRV-aware lint suggestions. It is intentionally independent of the toolchain
# pinned by the test workspace in tests/MODULE.bazel (currently 1.85.0), which
# only validates that the config wiring loads. Consumers should set their own
# `rust-version`/toolchain to match the Rust version they actually support.
msrv = "1.90.0"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Can we clarify the intended MSRV here? clippy/strict/clippy.toml sets msrv = "1.90.0", while the test workspace pins Rust 1.85.0 in tests/MODULE.bazel.

My understanding is that Clippy msrv normally represents the minimum Rust version the codebase supports. If the policy MSRV and the tested toolchain intentionally differ, it would help to document that relationship so consumers know which compiler version the policy is meant to target.

Could we either align these values, lower the Clippy msrv to the currently tested toolchain, or add a short note explaining why they intentionally differ? A broader compiler-version matrix could also be tracked as a follow-up issue if that is outside the intended scope of this PR.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Documented the relationship in both clippy.toml files: msrv is the policy's target minimum supported Rust version and is intentionally independent of the toolchain pinned in tests/MODULE.bazel (1.85.0), which only validates config wiring. Happy to align them to a single value instead if you'd prefer — let me know which direction.

check-private-items = true
14 changes: 14 additions & 0 deletions lint-profiles/relaxed/BUILD.bazel
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"])
97 changes: 97 additions & 0 deletions lint-profiles/relaxed/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# 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 is unstable and emits an "unknown lint"
# warning on stable toolchains. Enable it only on nightly (requires
# #![feature(non_exhaustive_omitted_patterns_lint)]). Keep this in sync with
# rustc-lints/flags.bzl.
# 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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The relaxed profile still denies several lints, including missing_panics_doc, undocumented_unsafe_blocks, wildcard_imports, and declare_interior_mutable_const. That may be exactly the right SCORE policy, but the README describes relaxed as suitable for tooling, generators, and tests where controlled panics/unwraps/debug printing are acceptable.

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.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The 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 (missing_panics_doc, undocumented_unsafe_blocks, wildcard_imports, declare_interior_mutable_const), and that unsafe_op_in_unsafe_fn is the only rustc level that differs between strict and relaxed today. The full policy matrix is deferred to the coding-guidelines doc.

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
14 changes: 14 additions & 0 deletions lint-profiles/strict/BUILD.bazel
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"])
89 changes: 89 additions & 0 deletions lint-profiles/strict/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# 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 is unstable and emits an "unknown lint"
# warning on stable toolchains. Enable it only on nightly (requires
# #![feature(non_exhaustive_omitted_patterns_lint)]). Keep this in sync with
# rustc-lints/flags.bzl.
# 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)
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
14 changes: 14 additions & 0 deletions rustc-lints/BUILD.bazel
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"])
Loading
Loading