diff options
author | Richard Levasseur <rlevasseur@google.com> | 2023-04-27 22:04:20 +0000 |
---|---|---|
committer | Richard Levasseur <rlevasseur@google.com> | 2023-04-28 01:34:35 +0000 |
commit | c473ea85acd3bff2517a1f1631ab7613dbbdeb2a (patch) | |
tree | 76b620f3b5b960a014e6a8f87732afd133c05b7b | |
parent | 79fd58291d29e22fe92542ca8c35f4af9ee8021a (diff) | |
download | bazelbuild-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.bazel | 23 | ||||
-rw-r--r-- | dev_extension.bzl | 50 | ||||
-rw-r--r-- | e2e/bzlmod/BUILD.bazel | 4 | ||||
-rw-r--r-- | e2e/bzlmod/tests.bzl | 27 |
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", + ) |