From 4be00a69ae3a0c4e7ef3a5f952254bacd16d0a2a Mon Sep 17 00:00:00 2001 From: Sahin Yort Date: Thu, 11 Apr 2024 11:26:42 -0700 Subject: [PATCH] refactor: toolchainize py_proto_library (#1577) Enables use of `--incompatible_enable_proto_toolchain_resolution` flag that launched in Bazel 7. This allows users to choose a pre-built `protoc` or use the runtime from https://pypi.org/project/protobuf/ rather than be forced to use hard-coded values in Bazel core. This change is also happening in other language rulesets that provide first-class protobuf support, e.g. https://github.com/bazelbuild/rules_go/issues/3895 No update to CHANGELOG.md in this PR as the feature is not yet documented for end-users, this just makes it possible to enable the flag. A follow-up PR will provide user instructions. --------- Co-authored-by: Alex Eagle --- MODULE.bazel | 2 +- examples/py_proto_library/WORKSPACE | 33 ++++++++++++----------- internal_deps.bzl | 8 +++--- python/private/proto/py_proto_library.bzl | 18 ++++++++++--- 4 files changed, 35 insertions(+), 26 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index fc32a3e51f..c7d5e23d0b 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -9,7 +9,7 @@ bazel_dep(name = "bazel_skylib", version = "1.3.0") bazel_dep(name = "platforms", version = "0.0.4") # Those are loaded only when using py_proto_library -bazel_dep(name = "rules_proto", version = "5.3.0-21.7") +bazel_dep(name = "rules_proto", version = "6.0.0-rc1") bazel_dep(name = "protobuf", version = "21.7", repo_name = "com_google_protobuf") internal_deps = use_extension("//python/private/bzlmod:internal_deps.bzl", "internal_deps") diff --git a/examples/py_proto_library/WORKSPACE b/examples/py_proto_library/WORKSPACE index bf38112f98..81f189dbbf 100644 --- a/examples/py_proto_library/WORKSPACE +++ b/examples/py_proto_library/WORKSPACE @@ -1,4 +1,6 @@ -workspace(name = "rules_python_py_proto_library_example") +# NB: short workspace name is required to workaround PATH length limitation, see +# https://github.com/bazelbuild/bazel/issues/18683#issuecomment-1843857373 +workspace(name = "p") # The following local_path_override is only needed to run this example as part of our CI. local_repository( @@ -24,21 +26,9 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "rules_proto", - sha256 = "dc3fb206a2cb3441b485eb1e423165b231235a1ea9b031b4433cf7bc1fa460dd", - strip_prefix = "rules_proto-5.3.0-21.7", - urls = [ - "https://github.com/bazelbuild/rules_proto/archive/refs/tags/5.3.0-21.7.tar.gz", - ], -) - -http_archive( - name = "com_google_protobuf", - sha256 = "75be42bd736f4df6d702a0e4e4d30de9ee40eac024c4b845d17ae4cc831fe4ae", - strip_prefix = "protobuf-21.7", - urls = [ - "https://mirror.bazel.build/github.com/protocolbuffers/protobuf/archive/v21.7.tar.gz", - "https://github.com/protocolbuffers/protobuf/archive/v21.7.tar.gz", - ], + sha256 = "904a8097fae42a690c8e08d805210e40cccb069f5f9a0f6727cf4faa7bed2c9c", + strip_prefix = "rules_proto-6.0.0-rc1", + url = "https://github.com/bazelbuild/rules_proto/releases/download/6.0.0-rc1/rules_proto-6.0.0-rc1.tar.gz", ) load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains") @@ -46,3 +36,14 @@ load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_ rules_proto_dependencies() rules_proto_toolchains() + +http_archive( + name = "com_google_protobuf", + sha256 = "4fc5ff1b2c339fb86cd3a25f0b5311478ab081e65ad258c6789359cd84d421f8", + strip_prefix = "protobuf-26.1", + urls = ["https://github.com/protocolbuffers/protobuf/archive/v26.1.tar.gz"], +) + +load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps") + +protobuf_deps() diff --git a/internal_deps.bzl b/internal_deps.bzl index 2ef0dc5751..a8bfd471dd 100644 --- a/internal_deps.bzl +++ b/internal_deps.bzl @@ -166,11 +166,9 @@ def rules_python_internal_deps(): http_archive( name = "rules_proto", - sha256 = "dc3fb206a2cb3441b485eb1e423165b231235a1ea9b031b4433cf7bc1fa460dd", - strip_prefix = "rules_proto-5.3.0-21.7", - urls = [ - "https://github.com/bazelbuild/rules_proto/archive/refs/tags/5.3.0-21.7.tar.gz", - ], + sha256 = "904a8097fae42a690c8e08d805210e40cccb069f5f9a0f6727cf4faa7bed2c9c", + strip_prefix = "rules_proto-6.0.0-rc1", + url = "https://github.com/bazelbuild/rules_proto/releases/download/6.0.0-rc1/rules_proto-6.0.0-rc1.tar.gz", ) http_archive( diff --git a/python/private/proto/py_proto_library.bzl b/python/private/proto/py_proto_library.bzl index 91faa2dc60..e123ff8476 100644 --- a/python/private/proto/py_proto_library.bzl +++ b/python/private/proto/py_proto_library.bzl @@ -17,7 +17,7 @@ load("@rules_proto//proto:defs.bzl", "ProtoInfo", "proto_common") load("//python:defs.bzl", "PyInfo") -ProtoLangToolchainInfo = proto_common.ProtoLangToolchainInfo +PY_PROTO_TOOLCHAIN = "@rules_python//python/proto:toolchain_type" _PyProtoInfo = provider( doc = "Encapsulates information needed by the Python proto rules.", @@ -35,6 +35,9 @@ _PyProtoInfo = provider( def _filter_provider(provider, *attrs): return [dep[provider] for attr in attrs for dep in attr if provider in dep] +def _incompatible_toolchains_enabled(): + return getattr(proto_common, "INCOMPATIBLE_ENABLE_PROTO_TOOLCHAIN_RESOLUTION", False) + def _py_proto_aspect_impl(target, ctx): """Generates and compiles Python code for a proto_library. @@ -51,7 +54,6 @@ def _py_proto_aspect_impl(target, ctx): ([_PyProtoInfo]) Providers collecting transitive information about generated files. """ - _proto_library = ctx.rule.attr # Check Proto file names @@ -61,7 +63,14 @@ def _py_proto_aspect_impl(target, ctx): proto.path, )) - proto_lang_toolchain_info = ctx.attr._aspect_proto_toolchain[ProtoLangToolchainInfo] + if _incompatible_toolchains_enabled(): + toolchain = ctx.toolchains[PY_PROTO_TOOLCHAIN] + if not toolchain: + fail("No toolchains registered for '%s'." % PY_PROTO_TOOLCHAIN) + proto_lang_toolchain_info = toolchain.proto + else: + proto_lang_toolchain_info = getattr(ctx.attr, "_aspect_proto_toolchain")[proto_common.ProtoLangToolchainInfo] + api_deps = [proto_lang_toolchain_info.runtime] generated_sources = [] @@ -123,7 +132,7 @@ def _py_proto_aspect_impl(target, ctx): _py_proto_aspect = aspect( implementation = _py_proto_aspect_impl, - attrs = { + attrs = {} if _incompatible_toolchains_enabled() else { "_aspect_proto_toolchain": attr.label( default = ":python_toolchain", ), @@ -131,6 +140,7 @@ _py_proto_aspect = aspect( attr_aspects = ["deps"], required_providers = [ProtoInfo], provides = [_PyProtoInfo], + toolchains = [PY_PROTO_TOOLCHAIN] if _incompatible_toolchains_enabled() else [], ) def _py_proto_library_rule(ctx):