Skip to content

Commit

Permalink
feat: introduce toolchain helper (#194)
Browse files Browse the repository at this point in the history
This is not final yet, I just want to test out with rules_python first.
Welcome to review though.

Also due to bazelbuild/bazel#20297 i can't
write unit tests for the incompatible flag. I'll look for a workaround.
  • Loading branch information
thesayyn authored Nov 29, 2023
1 parent 7188888 commit f9b0b88
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 0 deletions.
1 change: 1 addition & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ bazel_dep(name = "stardoc", version = "0.5.6", dev_dependency = True, repo_name
bazel_dep(name = "rules_cc", version = "0.0.1", dev_dependency = True)
bazel_dep(name = "googletest", version = "1.11.0", dev_dependency = True, repo_name = "com_google_googletest")
bazel_dep(name = "protobuf", version = "21.7", dev_dependency = True, repo_name = "com_google_protobuf")
bazel_dep(name = "platforms", version = "0.0.8", dev_dependency = True)
4 changes: 4 additions & 0 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ load(":dev_deps.bzl", "rules_proto_dev_deps")

rules_proto_dev_deps()

load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")

bazel_skylib_workspace()

load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")

protobuf_deps()
Expand Down
30 changes: 30 additions & 0 deletions proto/proto_common.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,33 @@ load("//proto/private:native.bzl", "native_proto_common")
proto_common = native_proto_common

ProtoLangToolchainInfo = proto_common.ProtoLangToolchainInfo

def _incompatible_toolchains_enabled():
return getattr(proto_common, "INCOMPATIBLE_ENABLE_PROTO_TOOLCHAIN_RESOLUTION", False)

def _find_toolchain(ctx, legacy_attr, toolchain_type):
if _incompatible_toolchains_enabled():
toolchain = ctx.toolchains[toolchain_type]
if not toolchain:
fail("No toolchains registered for '%s'." % toolchain_type)
return toolchain.proto
else:
return getattr(ctx.attr, legacy_attr)[ProtoLangToolchainInfo]

def _use_toolchain(toolchain_type):
if _incompatible_toolchains_enabled():
return [config_common.toolchain_type(toolchain_type, mandatory = False)]
else:
return []

def _if_legacy_toolchain(legacy_attr_dict):
if _incompatible_toolchains_enabled():
return {}
else:
return legacy_attr_dict

toolchains = struct(
use_toolchain = _use_toolchain,
find_toolchain = _find_toolchain,
if_legacy_toolchain = _if_legacy_toolchain,
)
14 changes: 14 additions & 0 deletions tests/BUILD
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag")
load("//proto:defs.bzl", "proto_library")
load("//proto:proto_common.bzl", "proto_common")

config_setting(
name = "incompatible_enable_proto_toolchain_resolution",
flag_values = {
":incompatible_enable_proto_toolchain_resolution_flag": "true",
},
)

bool_flag(
name = "incompatible_enable_proto_toolchain_resolution_flag",
build_setting_default = getattr(proto_common, "INCOMPATIBLE_ENABLE_PROTO_TOOLCHAIN_RESOLUTION", False),
)

proto_library(
name = "empty_proto",
Expand Down
3 changes: 3 additions & 0 deletions tests/proto_common/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
load(":toolchains.bzl", "unittest_toolchains")

unittest_toolchains()
51 changes: 51 additions & 0 deletions tests/proto_common/toolchains.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
"unit tests for proto_common.toolchains"

load("@bazel_skylib//lib:partial.bzl", "partial")
load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest")
load("//proto:proto_common.bzl", "toolchains")

def _test_toolchains_without_incompatible_flag(ctx):
env = unittest.begin(ctx)

asserts.equals(env, {}, toolchains.if_legacy_toolchain({}))
asserts.equals(env, None, toolchains.if_legacy_toolchain(None))
asserts.equals(env, False, toolchains.if_legacy_toolchain(False))

return unittest.end(env)

toolchains_without_incompatible_flags_test = unittest.make(_test_toolchains_without_incompatible_flag)

def _test_toolchains_with_incompatible_flag(ctx):
env = unittest.begin(ctx)

asserts.equals(env, {}, toolchains.if_legacy_toolchain({}))
asserts.equals(env, {}, toolchains.if_legacy_toolchain(None))
asserts.equals(env, {}, toolchains.if_legacy_toolchain(False))
toolchain = toolchains.use_toolchain("//nonexistent:toolchain_type")
asserts.equals(env, 1, len(toolchain))
asserts.equals(env, False, toolchain[0].mandatory)
asserts.equals(env, str(Label("//nonexistent:toolchain_type")), str(toolchain[0].toolchain_type))

return unittest.end(env)

toolchains_with_incompatible_flag_test = unittest.make(_test_toolchains_with_incompatible_flag)

# buildifier: disable=unnamed-macro
def unittest_toolchains():
unittest.suite(
"test_toolchains",
partial.make(
toolchains_without_incompatible_flags_test,
target_compatible_with = select({
"//tests:incompatible_enable_proto_toolchain_resolution": ["@platforms//:incompatible"],
"//conditions:default": [],
}),
),
partial.make(
toolchains_with_incompatible_flag_test,
target_compatible_with = select({
"//tests:incompatible_enable_proto_toolchain_resolution": [],
"//conditions:default": ["@platforms//:incompatible"],
}),
),
)

0 comments on commit f9b0b88

Please sign in to comment.