From 455dcaab70a70d74ae79c1382f7623a34d8bfba2 Mon Sep 17 00:00:00 2001 From: Alex Eagle Date: Wed, 15 May 2024 15:17:01 -0700 Subject: [PATCH] feat: support incompatible_enable_proto_toolchain_resolution (#608) * feat: support incompatible_enable_proto_toolchain_resolution See https://github.com/bazelbuild/rules_proto/discussions/213 * Also upgrade rules_proto for WORKSPACE tests * fix: install bazel_features explicitly This seems like a bug in rules_proto that the initializer call can't bootstrap because it hits a bazel_features load --- MODULE.bazel | 5 ++--- WORKSPACE | 4 ++++ e2e/bzlmod/.bazelrc | 2 ++ e2e/bzlmod/MODULE.bazel | 1 + internal_deps.bzl | 15 ++++++++++----- ts/private/ts_proto_library.bzl | 15 ++++++++++----- 6 files changed, 29 insertions(+), 13 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 1982bd77..a11afc30 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -12,13 +12,12 @@ bazel_dep(name = "aspect_rules_js", version = "1.34.0") bazel_dep(name = "bazel_skylib", version = "1.4.1") bazel_dep(name = "platforms", version = "0.0.5") -# Only needed because rules_proto doesn't provide the protoc toolchain yet. -# TODO(alex/sahin): remove in the future +# TODO(4.x): remove support for non-toolchainized protoc bazel_dep(name = "protobuf", version = "21.7", repo_name = "com_google_protobuf") # Similar to rules_python/MODULE.bazel, see https://github.com/bazelbuild/rules_python/pull/832 # These are loaded only when using ts_proto_library -bazel_dep(name = "rules_proto", version = "5.3.0-21.7") +bazel_dep(name = "rules_proto", version = "6.0.0") ####### Dev dependencies ######## diff --git a/WORKSPACE b/WORKSPACE index c9944ea9..90316e51 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -102,6 +102,10 @@ npm_repositories() # bazel run -- @npm_typescript//:tsc --version rules_ts_dependencies(ts_version_from = "@npm//examples:typescript/resolved.json") +load("@bazel_features//:deps.bzl", "bazel_features_deps") + +bazel_features_deps() + ########################################### # Protobuf rules to test ts_proto_library load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies") diff --git a/e2e/bzlmod/.bazelrc b/e2e/bzlmod/.bazelrc index 67b4301f..edcc20ae 100644 --- a/e2e/bzlmod/.bazelrc +++ b/e2e/bzlmod/.bazelrc @@ -9,6 +9,8 @@ import %workspace%/../../.aspect/bazelrc/performance.bazelrc ### YOUR PROJECT SPECIFIC OPTIONS GO HERE ### common --@aspect_rules_ts//ts:skipLibCheck=honor_tsconfig +# NB: comment this line out to test the legacy path to @com_google_protobuf//:protoc +common --incompatible_enable_proto_toolchain_resolution # Load any settings & overrides specific to the current user from `.aspect/bazelrc/user.bazelrc`. # This file should appear in `.gitignore` so that settings are not shared with team members. This diff --git a/e2e/bzlmod/MODULE.bazel b/e2e/bzlmod/MODULE.bazel index d6fc46fa..dfe11843 100644 --- a/e2e/bzlmod/MODULE.bazel +++ b/e2e/bzlmod/MODULE.bazel @@ -8,6 +8,7 @@ local_path_override( bazel_dep(name = "aspect_rules_js", version = "1.34.0", dev_dependency = True) bazel_dep(name = "bazel_skylib", version = "1.4.1", dev_dependency = True) bazel_dep(name = "rules_proto", version = "5.3.0-21.7", dev_dependency = True) +bazel_dep(name = "toolchains_protoc", version = "0.2.4", dev_dependency = True) npm = use_extension("@aspect_rules_js//npm:extensions.bzl", "npm", dev_dependency = True) npm.npm_translate_lock( diff --git a/internal_deps.bzl b/internal_deps.bzl index 18213e3b..8e4d18de 100644 --- a/internal_deps.bzl +++ b/internal_deps.bzl @@ -37,13 +37,18 @@ def rules_ts_internal_deps(): urls = ["https://github.com/bazelbuild/stardoc/releases/download/0.6.2/stardoc-0.6.2.tar.gz"], ) + http_archive( + name = "bazel_features", + sha256 = "2cd9e57d4c38675d321731d65c15258f3a66438ad531ae09cb8bb14217dc8572", + strip_prefix = "bazel_features-1.11.0", + url = "https://github.com/bazel-contrib/bazel_features/releases/download/v1.11.0/bazel_features-v1.11.0.tar.gz", + ) + 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 = "303e86e722a520f6f326a50b41cfc16b98fe6d1955ce46642a5b7a67c11c0f5d", + strip_prefix = "rules_proto-6.0.0", + url = "https://github.com/bazelbuild/rules_proto/releases/download/6.0.0/rules_proto-6.0.0.tar.gz", ) http_archive( diff --git a/ts/private/ts_proto_library.bzl b/ts/private/ts_proto_library.bzl index 1f7bf7cb..6fa8c30f 100644 --- a/ts/private/ts_proto_library.bzl +++ b/ts/private/ts_proto_library.bzl @@ -4,6 +4,9 @@ load("@aspect_bazel_lib//lib:copy_to_bin.bzl", "COPY_FILE_TO_BIN_TOOLCHAINS") load("@aspect_rules_js//js:libs.bzl", "js_lib_helpers") load("@aspect_rules_js//js:providers.bzl", "JsInfo", "js_info") load("@rules_proto//proto:defs.bzl", "ProtoInfo", "proto_common") +load("@rules_proto//proto:proto_common.bzl", proto_toolchains = "toolchains") + +_PROTO_TOOLCHAIN_TYPE = "@rules_proto//proto:toolchain_type" # buildifier: disable=function-docstring-header def _protoc_action(ctx, proto_info, outputs, options = { @@ -43,8 +46,9 @@ def _protoc_action(ctx, proto_info, outputs, options = { args.add_all(proto_info.direct_sources) + proto_toolchain_enabled = len(proto_toolchains.use_toolchain(_PROTO_TOOLCHAIN_TYPE)) > 0 ctx.actions.run( - executable = ctx.executable.protoc, + executable = ctx.toolchains[_PROTO_TOOLCHAIN_TYPE].proto.proto_compiler if proto_toolchain_enabled else ctx.executable.protoc, progress_message = "Generating .js/.d.ts from %{label}", outputs = outputs, inputs = inputs, @@ -107,7 +111,7 @@ def _ts_proto_library_impl(ctx): ts_proto_library = rule( implementation = _ts_proto_library_impl, - attrs = { + attrs = dict({ "deps": attr.label_list( providers = [JsInfo], doc = "Other ts_proto_library rules. TODO: could we collect them with an aspect", @@ -129,7 +133,6 @@ ts_proto_library = rule( providers = [ProtoInfo], mandatory = True, ), - "protoc": attr.label(default = "@com_google_protobuf//:protoc", executable = True, cfg = "exec"), "protoc_gen_es": attr.label( doc = "protoc plugin to generate messages", mandatory = True, @@ -146,6 +149,8 @@ ts_proto_library = rule( executable = True, cfg = "exec", ), - }, - toolchains = COPY_FILE_TO_BIN_TOOLCHAINS, + }, **proto_toolchains.if_legacy_toolchain({ + "protoc": attr.label(default = "@com_google_protobuf//:protoc", executable = True, cfg = "exec"), + })), + toolchains = COPY_FILE_TO_BIN_TOOLCHAINS + proto_toolchains.use_toolchain(_PROTO_TOOLCHAIN_TYPE), )