From 0c9f94f71c7c46d0c2fcadc674c12598d05f348a Mon Sep 17 00:00:00 2001 From: Oliver Lee Date: Thu, 22 Aug 2024 17:17:23 -0700 Subject: [PATCH] allow deps to include test targets (#13) Change-Id: I228e14a393bc1b3e95b82a07ac91425cf679591e --- apply_fixes.bzl | 38 +++++++++++++++++++++++----- example/dep-cc_test/.bazelignore | 1 + example/dep-cc_test/.bazelrc | 8 ++++++ example/dep-cc_test/BUILD.bazel | 17 +++++++++++++ example/dep-cc_test/WORKSPACE.bazel | 8 ++++++ example/dep-cc_test/bar.cpp | 4 +++ example/dep-cc_test/fail/BUILD.bazel | 10 ++++++++ example/dep-cc_test/foo.cpp | 4 +++ example/dep-cc_test/pass/BUILD.bazel | 9 +++++++ private/BUILD.bazel | 4 +++ private/functional.bzl | 4 +++ private/true.bash | 3 +++ test/BUILD.bazel | 2 ++ test/check_cc_test-deps_test.bash | 22 ++++++++++++++++ 14 files changed, 128 insertions(+), 6 deletions(-) create mode 100644 example/dep-cc_test/.bazelignore create mode 100644 example/dep-cc_test/.bazelrc create mode 100644 example/dep-cc_test/BUILD.bazel create mode 100644 example/dep-cc_test/WORKSPACE.bazel create mode 100644 example/dep-cc_test/bar.cpp create mode 100644 example/dep-cc_test/fail/BUILD.bazel create mode 100644 example/dep-cc_test/foo.cpp create mode 100644 example/dep-cc_test/pass/BUILD.bazel create mode 100755 private/true.bash create mode 100755 test/check_cc_test-deps_test.bash diff --git a/apply_fixes.bzl b/apply_fixes.bzl index c430932..4b8db04 100644 --- a/apply_fixes.bzl +++ b/apply_fixes.bzl @@ -7,6 +7,7 @@ multiple times to a header when running on multiple targets. load("@bazel_skylib//lib:shell.bzl", "shell") load("@bazel_skylib//lib:versions.bzl", "versions") load("@local_bazel_version//:bazel_version.bzl", "BAZEL_VERSION") +load("//private:functional.bzl", fn = "functional") load(":aspects.bzl", "export_fixes") def _do_verify_deps(ctx, out): @@ -103,6 +104,17 @@ cd "$BUILD_WORKSPACE_DIRECTORY" }, ) + def _deduced_label(s): + label = str(Label(s)) + + def _implicit_workspace(x): + idx = x.find("//") + return idx < 1 or fn.empty(x[:idx].strip("@")) + + return ( + fn.add(*(label.rpartition("//")[-2:])) if _implicit_workspace(s) else label + ) + ctx.actions.run_shell( inputs = depset(direct = [query]), outputs = [out], @@ -138,7 +150,7 @@ touch {outfile} outfile = out.path, query = query.path, actual_deps = " ".join([ - shell.quote(str(d.label).strip("@")) + shell.quote(_deduced_label(d)) for d in ctx.attr.deps ]), pattern = ctx.attr.desired_deps, @@ -173,9 +185,8 @@ def _verify_deps_impl(ctx): _verify_deps = rule( implementation = _verify_deps_impl, attrs = { - "deps": attr.label_list( - providers = [CcInfo], - ), + # avoid using a label_list in case some deps are test targets + "deps": attr.string_list(), "desired_deps": attr.string(), "bazel_bin": attr.string( default = "bazel", @@ -282,8 +293,8 @@ def apply_fixes( `bazel_bin`), which may not have the same configuration as the parent process. - Note that the following issue is may still present. `.bazelignore` - can be defined ignore convenience symlinks. + Note that the following issue may still present. `.bazelignore` + can be defined to ignore convenience symlinks. https://github.com/bazelbuild/bazel/issues/10653 bazel_bin: `string`; default is `bazel` @@ -304,6 +315,21 @@ def apply_fixes( ) ``` """ + + # Create a test target that depends on deps. We need to use a test target + # in case any deps are tests. We use this to check that all deps are valid + # targets, which otherwise will not happen at build time. The .verify + # target takes deps as a string_list and the target is tagged manual. + # + # + # https://github.com/bazelbuild/bazel/issues/6842 + # https://github.com/bazelbuild/bazel/issues/14294 + native.sh_test( + name = name + ".dummy", + srcs = [Label("//private:true.bash")], + data = deps, + ) + _verify_deps( name = name + ".verify", deps = deps, diff --git a/example/dep-cc_test/.bazelignore b/example/dep-cc_test/.bazelignore new file mode 100644 index 0000000..35755e7 --- /dev/null +++ b/example/dep-cc_test/.bazelignore @@ -0,0 +1 @@ +bazel-dep-cc_test diff --git a/example/dep-cc_test/.bazelrc b/example/dep-cc_test/.bazelrc new file mode 100644 index 0000000..09a49e5 --- /dev/null +++ b/example/dep-cc_test/.bazelrc @@ -0,0 +1,8 @@ +common --enable_bzlmod=false + +build:clang-tidy --aspects=@rules_clang_tidy//:aspects.bzl%check +build:clang-tidy --output_groups=report + +build:clang-tidy-export-fixes --aspects=@rules_clang_tidy//:aspects.bzl%export_fixes +build:clang-tidy-export-fixes --output_groups=report + diff --git a/example/dep-cc_test/BUILD.bazel b/example/dep-cc_test/BUILD.bazel new file mode 100644 index 0000000..fe6f9bb --- /dev/null +++ b/example/dep-cc_test/BUILD.bazel @@ -0,0 +1,17 @@ +cc_binary( + name = "foo", + srcs = ["foo.cpp"], + visibility = [ + "//fail:__pkg__", + "//pass:__pkg__", + ], +) + +cc_test( + name = "bar", + srcs = ["bar.cpp"], + visibility = [ + "//fail:__pkg__", + "//pass:__pkg__", + ], +) diff --git a/example/dep-cc_test/WORKSPACE.bazel b/example/dep-cc_test/WORKSPACE.bazel new file mode 100644 index 0000000..95cdabb --- /dev/null +++ b/example/dep-cc_test/WORKSPACE.bazel @@ -0,0 +1,8 @@ +local_repository( + name = "rules_clang_tidy", + path = "../..", +) + +load("@rules_clang_tidy//:dependencies.bzl", "rules_clang_tidy_dependencies") + +rules_clang_tidy_dependencies() diff --git a/example/dep-cc_test/bar.cpp b/example/dep-cc_test/bar.cpp new file mode 100644 index 0000000..8e18a28 --- /dev/null +++ b/example/dep-cc_test/bar.cpp @@ -0,0 +1,4 @@ +auto main() -> int +{ + return 1; +} diff --git a/example/dep-cc_test/fail/BUILD.bazel b/example/dep-cc_test/fail/BUILD.bazel new file mode 100644 index 0000000..1c06241 --- /dev/null +++ b/example/dep-cc_test/fail/BUILD.bazel @@ -0,0 +1,10 @@ +load("@rules_clang_tidy//:defs.bzl", "apply_fixes") + +apply_fixes( + name = "build_fail", + deps = [ + "//:bar", + "//:baz", # doesn't exist + "//:foo", + ], +) diff --git a/example/dep-cc_test/foo.cpp b/example/dep-cc_test/foo.cpp new file mode 100644 index 0000000..8e18a28 --- /dev/null +++ b/example/dep-cc_test/foo.cpp @@ -0,0 +1,4 @@ +auto main() -> int +{ + return 1; +} diff --git a/example/dep-cc_test/pass/BUILD.bazel b/example/dep-cc_test/pass/BUILD.bazel new file mode 100644 index 0000000..21a4491 --- /dev/null +++ b/example/dep-cc_test/pass/BUILD.bazel @@ -0,0 +1,9 @@ +load("@rules_clang_tidy//:defs.bzl", "apply_fixes") + +apply_fixes( + name = "build_pass", + deps = [ + "//:bar", + "//:foo", + ], +) diff --git a/private/BUILD.bazel b/private/BUILD.bazel index e69de29..5998522 100644 --- a/private/BUILD.bazel +++ b/private/BUILD.bazel @@ -0,0 +1,4 @@ +exports_files( + ["true.bash"], + visibility = ["//visibility:public"], +) diff --git a/private/functional.bzl b/private/functional.bzl index 2cedb7a..e7a76cd 100644 --- a/private/functional.bzl +++ b/private/functional.bzl @@ -27,6 +27,9 @@ def _add(head, *tail): def _bind_front(f, *front): return lambda *back: f(*(tuple(front) + tuple(back))) +def _empty(x): + return not len(x) + functional = struct( map = _map, filter = _filter, @@ -34,4 +37,5 @@ functional = struct( left_fold = _left_fold, add = _add, bind_front = _bind_front, + empty = _empty, ) diff --git a/private/true.bash b/private/true.bash new file mode 100755 index 0000000..007807b --- /dev/null +++ b/private/true.bash @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +true diff --git a/test/BUILD.bazel b/test/BUILD.bazel index b3f6eae..5669ba0 100644 --- a/test/BUILD.bazel +++ b/test/BUILD.bazel @@ -25,6 +25,8 @@ tidy_test(name = "check_misc-unused_test") tidy_test(name = "check_extra-options_test") +tidy_test(name = "check_cc_test-deps_test") + tidy_test(name = "fix_script_test") tidy_test(name = "fix_rule_test") diff --git a/test/check_cc_test-deps_test.bash b/test/check_cc_test-deps_test.bash new file mode 100755 index 0000000..6481800 --- /dev/null +++ b/test/check_cc_test-deps_test.bash @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +set -euxo pipefail + +source test/prelude.bash + +check_setup example/dep-cc_test + +# This sets a 15 second idle timeout +# https://github.com/bazelbuild/bazel/issues/11062 +unset TEST_TMPDIR + +bazel \ + --bazelrc="$test_bazelrc" \ + build \ + //pass/... + +bazel \ + --bazelrc="$test_bazelrc" \ + build \ + //fail/... 2>&1 | tee "$log" || true + +grep "no such target '//:baz'" "$log"