From ff2090985054ea092e7981a277382195e98c8da2 Mon Sep 17 00:00:00 2001 From: Oliver Lee Date: Tue, 17 Mar 2026 14:29:20 -0700 Subject: [PATCH 1/2] use custom no-fail clippy with rust-analyzer-check Update `rust-analyzer-check.bash` to use a wrapped version of the clippy-driver that always succeeds. This allows the clippy aspect to emit build failure diagnostics, even though the underlying clippy-driver returns a failure exit code. --- MODULE.bazel | 21 ++++++++ toolchain/BUILD.bazel | 11 ++++ tools/clippy_no_fail/BUILD.bazel | 0 .../clippy_no_fail_toolchain_tools.bzl | 51 +++++++++++++++++++ tools/rust-analyzer/rust-analyzer-check.bash | 15 +----- 5 files changed, 85 insertions(+), 13 deletions(-) create mode 100644 toolchain/BUILD.bazel create mode 100644 tools/clippy_no_fail/BUILD.bazel create mode 100644 tools/clippy_no_fail/clippy_no_fail_toolchain_tools.bzl diff --git a/MODULE.bazel b/MODULE.bazel index 90f65e2..d944db4 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -14,6 +14,22 @@ register_toolchains( "@rust_toolchains//:all", ) +# make these tool repos visible to the clippy_no_fail_toolchain_tools rule +use_repo( + rust, + "rust_linux_x86_64__x86_64-unknown-linux-gnu__stable_tools", + "rust_macos_aarch64__aarch64-apple-darwin__stable_tools", +) + +clippy_no_fail_toolchain_tools = use_repo_rule( + "//tools/clippy_no_fail:clippy_no_fail_toolchain_tools.bzl", + "clippy_no_fail_toolchain_tools", +) + +clippy_no_fail_toolchain_tools( + name = "local_clippy_no_fail_toolchain_tools", +) + bazel_dep( name = "buildifier_prebuilt", version = "8.2.0.2", @@ -29,6 +45,11 @@ bazel_dep( version = "0.12.0", dev_dependency = True, ) +bazel_dep( + name = "rules_shell", + version = "0.6.1", + dev_dependency = True, +) starpls = use_extension( "//tools/starpls:extension.bzl", diff --git a/toolchain/BUILD.bazel b/toolchain/BUILD.bazel new file mode 100644 index 0000000..44a0f8b --- /dev/null +++ b/toolchain/BUILD.bazel @@ -0,0 +1,11 @@ +load("@platforms//host:constraints.bzl", "HOST_CONSTRAINTS") + +toolchain( + name = "local_rust_stable_clippy_no_fail", + exec_compatible_with = HOST_CONSTRAINTS, + tags = ["manual"], + target_compatible_with = HOST_CONSTRAINTS, + target_settings = ["@rules_rust//rust/toolchain/channel:stable"], + toolchain = "@local_clippy_no_fail_toolchain_tools//:rust_toolchain", + toolchain_type = "@rules_rust//rust:toolchain", +) diff --git a/tools/clippy_no_fail/BUILD.bazel b/tools/clippy_no_fail/BUILD.bazel new file mode 100644 index 0000000..e69de29 diff --git a/tools/clippy_no_fail/clippy_no_fail_toolchain_tools.bzl b/tools/clippy_no_fail/clippy_no_fail_toolchain_tools.bzl new file mode 100644 index 0000000..48cc751 --- /dev/null +++ b/tools/clippy_no_fail/clippy_no_fail_toolchain_tools.bzl @@ -0,0 +1,51 @@ +load("@platforms//host:constraints.bzl", "HOST_CONSTRAINTS") + +STABLE_TOOL_REPOS = [ + "rust_linux_x86_64__x86_64-unknown-linux-gnu__stable_tools", + "rust_macos_aarch64__aarch64-apple-darwin__stable_tools", +] + +_SOURCE_TOOLS = STABLE_TOOL_REPOS[int("@platforms//os:osx" in HOST_CONSTRAINTS)] + +def _clippy_no_fail_toolchain_tools_impl(rctx): + source_build = rctx.path(rctx.attr.source_build_file) + source_root = source_build.dirname + + strip_root_prefix = lambda path: str(path)[len(str(source_root)) + 1:] + + result = rctx.execute(["find", str(source_root), "-not", "-type", "d"]) + if result.return_code != 0: + fail("find failed: " + result.stderr) + + for line in result.stdout.splitlines(): + src = rctx.path(line) + rel = strip_root_prefix(src) + + if rel not in ("BUILD.bazel", "WORKSPACE.bazel", "bin/clippy-driver"): + rctx.symlink(src, rel) + + rctx.file( + "bin/clippy-driver", + """\ +#!/usr/bin/env bash +{real_clippy_driver} "$@" || true +""".format( + real_clippy_driver = "{}/bin/clippy-driver".format(source_root), + ), + executable = True, + ) + + rctx.file( + "BUILD.bazel", + rctx.read(source_build), + ) + +clippy_no_fail_toolchain_tools = repository_rule( + implementation = _clippy_no_fail_toolchain_tools_impl, + attrs = { + "source_build_file": attr.label( + default = Label("@{}//:BUILD.bazel".format(_SOURCE_TOOLS)), + allow_single_file = True, + ), + }, +) diff --git a/tools/rust-analyzer/rust-analyzer-check.bash b/tools/rust-analyzer/rust-analyzer-check.bash index 18f527f..69d0ab2 100755 --- a/tools/rust-analyzer/rust-analyzer-check.bash +++ b/tools/rust-analyzer/rust-analyzer-check.bash @@ -10,25 +10,14 @@ if [[ "$label" = "{label}" ]]; then label="//..." fi -stamp_file="$(mktemp)" -trap 'rm -f "$stamp_file"' EXIT - -build_status=0 bazelisk \ "--output_base=${output_base}" \ build \ + --extra_toolchains=//toolchain:local_rust_stable_clippy_no_fail \ --aspects=//tools/rust-analyzer:aspect.bzl%clippy_stdout_aspect \ --@rules_rust//rust/settings:error_format=json \ --@rules_rust//rust/settings:capture_clippy_output=true \ --output_groups=clippy_stdout \ --config=clippy_settings \ --keep_going \ - -- "$label" || build_status=$? - -if (( build_status != 0 )); then - while IFS= read -r -d '' diagnostics_file; do - if grep -q '^{"$message_type":"diagnostic",' "$diagnostics_file"; then - cat "$diagnostics_file" - fi - done < <(find "$output_base" -type f -name '*.clippy.diagnostics' -newer "$stamp_file" -print0 | sort -z) -fi + -- "$label" || true From 3aed1a2e643735cc6af130b494241f63e7b11190 Mon Sep 17 00:00:00 2001 From: Oliver Lee Date: Tue, 17 Mar 2026 14:39:59 -0700 Subject: [PATCH 2/2] docstring --- tools/clippy_no_fail/clippy_no_fail_toolchain_tools.bzl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/clippy_no_fail/clippy_no_fail_toolchain_tools.bzl b/tools/clippy_no_fail/clippy_no_fail_toolchain_tools.bzl index 48cc751..01b4345 100644 --- a/tools/clippy_no_fail/clippy_no_fail_toolchain_tools.bzl +++ b/tools/clippy_no_fail/clippy_no_fail_toolchain_tools.bzl @@ -1,3 +1,7 @@ +""" +Provides a rust toolchain tools repo where clippy-driver always succeeds. +""" + load("@platforms//host:constraints.bzl", "HOST_CONSTRAINTS") STABLE_TOOL_REPOS = [