aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Levasseur <rlevasseur@google.com>2023-04-27 22:04:20 +0000
committerRichard Levasseur <rlevasseur@google.com>2023-04-28 01:34:35 +0000
commitc473ea85acd3bff2517a1f1631ab7613dbbdeb2a (patch)
tree76b620f3b5b960a014e6a8f87732afd133c05b7b
parent79fd58291d29e22fe92542ca8c35f4af9ee8021a (diff)
downloadbazelbuild-rules_testing-c473ea85acd3bff2517a1f1631ab7613dbbdeb2a.tar.gz
fix: Don't require downstream users to register Python toolchains.
The Python toolchains are only needed for dev purposes (doc generation). Unfortunately, Bazel doesn't provide an easy way to mark a register_toolchains() call as dev-only. To work around this, we use an extension to create a repository whose contents depend on if its the root module or not. If its the root module, it means we're the rules_testing module and its the dev-dependency case, so write a build file with the real toolchains. If its not the root module, then its not the dev-dependency case, so write an empty build file. Fixes #33
-rw-r--r--MODULE.bazel23
-rw-r--r--dev_extension.bzl50
-rw-r--r--e2e/bzlmod/BUILD.bazel4
-rw-r--r--e2e/bzlmod/tests.bzl27
4 files changed, 101 insertions, 3 deletions
diff --git a/MODULE.bazel b/MODULE.bazel
index 046e33e..5fe4649 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -29,12 +29,29 @@ python.toolchain(
name = "python3_11",
python_version = "3.11",
)
-use_repo(python, "python3_11_toolchains")
-register_toolchains(
- "@python3_11_toolchains//:all",
+# NOTE: use_repo() must be called for each platform that runs the docgen tools
+use_repo(
+ python,
+ "python3_11_toolchains",
+ "python3_11_x86_64-unknown-linux-gnu",
)
+# NOTE: This is actualy a dev dependency, but due to
+# https://github.com/bazelbuild/bazel/issues/18248
+# it has to be non-dev to generate the repo name used
+# in the subsequent register_toolchains() call.
+dev = use_extension(
+ "//:dev_extension.bzl",
+ "dev",
+)
+dev.setup()
+use_repo(dev, "rules_testing_dev_toolchains")
+
+# NOTE: This call will be run by downstream users, so the
+# repos it mentions must exist.
+register_toolchains("@rules_testing_dev_toolchains//:all")
+
pip = use_extension(
"@rules_python//python:extensions.bzl",
"pip",
diff --git a/dev_extension.bzl b/dev_extension.bzl
new file mode 100644
index 0000000..808ac86
--- /dev/null
+++ b/dev_extension.bzl
@@ -0,0 +1,50 @@
+# Copyright 2023 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Extension only used for development purposes."""
+
+def _dev_ext_impl(mctx):
+ module = mctx.modules[0]
+ _dev_toolchains_repo(
+ name = "rules_testing_dev_toolchains",
+ is_root = module.is_root,
+ )
+
+dev = module_extension(
+ implementation = _dev_ext_impl,
+ tag_classes = {
+ "setup": tag_class(),
+ },
+)
+
+def _dev_toolchains_repo_impl(rctx):
+ # If its the root module, then we're in rules_testing and
+ # it's a dev dependency situation.
+ if rctx.attr.is_root:
+ toolchain_build = Label("@python3_11_toolchains//:BUILD.bazel")
+
+ # NOTE: This is brittle. It only works because, luckily,
+ # rules_python's toolchain BUILD file is essentially self-contained.
+ # It only uses absolute references and doesn't load anything,
+ # so we can copy it elsewhere and it still works.
+ rctx.symlink(toolchain_build, "BUILD.bazel")
+ else:
+ rctx.file("BUILD.bazel", "")
+
+_dev_toolchains_repo = repository_rule(
+ implementation = _dev_toolchains_repo_impl,
+ attrs = {
+ "is_root": attr.bool(),
+ },
+)
diff --git a/e2e/bzlmod/BUILD.bazel b/e2e/bzlmod/BUILD.bazel
index a646c9d..5b8c49a 100644
--- a/e2e/bzlmod/BUILD.bazel
+++ b/e2e/bzlmod/BUILD.bazel
@@ -3,3 +3,7 @@
load(":tests.bzl", "bzlmod_test_suite")
bzlmod_test_suite(name = "bzlmod_tests")
+
+toolchain_type(
+ name = "fake",
+)
diff --git a/e2e/bzlmod/tests.bzl b/e2e/bzlmod/tests.bzl
index c3019c8..12471fe 100644
--- a/e2e/bzlmod/tests.bzl
+++ b/e2e/bzlmod/tests.bzl
@@ -38,4 +38,31 @@ def _simple_test_impl(env, target):
def bzlmod_test_suite(name):
test_suite(name = name, tests = [
_simple_test,
+ _trigger_toolchains_test,
])
+
+def _needs_toolchain_impl(ctx):
+ # We just need to trigger toolchain resolution, we don't
+ # care about the result.
+ _ = ctx.toolchains["//:fake"] # @unused
+
+_needs_toolchain = rule(
+ implementation = _needs_toolchain_impl,
+ toolchains = [config_common.toolchain_type("//:fake", mandatory = False)],
+)
+
+def _trigger_toolchains_test_impl(env, target):
+ # Building is sufficient evidence of success
+ _ = env, target # @unused
+
+# A regression test for https://github.com/bazelbuild/rules_testing/issues/33
+def _trigger_toolchains_test(name):
+ util.helper_target(
+ _needs_toolchain,
+ name = name + "_subject",
+ )
+ analysis_test(
+ name = name,
+ impl = _trigger_toolchains_test_impl,
+ target = name + "_subject",
+ )