Skip to content

Commit f9b0b88

Browse files
authored
feat: introduce toolchain helper (#194)
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.
1 parent 7188888 commit f9b0b88

File tree

6 files changed

+103
-0
lines changed

6 files changed

+103
-0
lines changed

MODULE.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ bazel_dep(name = "stardoc", version = "0.5.6", dev_dependency = True, repo_name
1515
bazel_dep(name = "rules_cc", version = "0.0.1", dev_dependency = True)
1616
bazel_dep(name = "googletest", version = "1.11.0", dev_dependency = True, repo_name = "com_google_googletest")
1717
bazel_dep(name = "protobuf", version = "21.7", dev_dependency = True, repo_name = "com_google_protobuf")
18+
bazel_dep(name = "platforms", version = "0.0.8", dev_dependency = True)

WORKSPACE

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ load(":dev_deps.bzl", "rules_proto_dev_deps")
1111

1212
rules_proto_dev_deps()
1313

14+
load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
15+
16+
bazel_skylib_workspace()
17+
1418
load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
1519

1620
protobuf_deps()

proto/proto_common.bzl

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,33 @@ load("//proto/private:native.bzl", "native_proto_common")
2222
proto_common = native_proto_common
2323

2424
ProtoLangToolchainInfo = proto_common.ProtoLangToolchainInfo
25+
26+
def _incompatible_toolchains_enabled():
27+
return getattr(proto_common, "INCOMPATIBLE_ENABLE_PROTO_TOOLCHAIN_RESOLUTION", False)
28+
29+
def _find_toolchain(ctx, legacy_attr, toolchain_type):
30+
if _incompatible_toolchains_enabled():
31+
toolchain = ctx.toolchains[toolchain_type]
32+
if not toolchain:
33+
fail("No toolchains registered for '%s'." % toolchain_type)
34+
return toolchain.proto
35+
else:
36+
return getattr(ctx.attr, legacy_attr)[ProtoLangToolchainInfo]
37+
38+
def _use_toolchain(toolchain_type):
39+
if _incompatible_toolchains_enabled():
40+
return [config_common.toolchain_type(toolchain_type, mandatory = False)]
41+
else:
42+
return []
43+
44+
def _if_legacy_toolchain(legacy_attr_dict):
45+
if _incompatible_toolchains_enabled():
46+
return {}
47+
else:
48+
return legacy_attr_dict
49+
50+
toolchains = struct(
51+
use_toolchain = _use_toolchain,
52+
find_toolchain = _find_toolchain,
53+
if_legacy_toolchain = _if_legacy_toolchain,
54+
)

tests/BUILD

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,18 @@
1+
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag")
12
load("//proto:defs.bzl", "proto_library")
3+
load("//proto:proto_common.bzl", "proto_common")
4+
5+
config_setting(
6+
name = "incompatible_enable_proto_toolchain_resolution",
7+
flag_values = {
8+
":incompatible_enable_proto_toolchain_resolution_flag": "true",
9+
},
10+
)
11+
12+
bool_flag(
13+
name = "incompatible_enable_proto_toolchain_resolution_flag",
14+
build_setting_default = getattr(proto_common, "INCOMPATIBLE_ENABLE_PROTO_TOOLCHAIN_RESOLUTION", False),
15+
)
216

317
proto_library(
418
name = "empty_proto",

tests/proto_common/BUILD.bazel

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
load(":toolchains.bzl", "unittest_toolchains")
2+
3+
unittest_toolchains()

tests/proto_common/toolchains.bzl

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
"unit tests for proto_common.toolchains"
2+
3+
load("@bazel_skylib//lib:partial.bzl", "partial")
4+
load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest")
5+
load("//proto:proto_common.bzl", "toolchains")
6+
7+
def _test_toolchains_without_incompatible_flag(ctx):
8+
env = unittest.begin(ctx)
9+
10+
asserts.equals(env, {}, toolchains.if_legacy_toolchain({}))
11+
asserts.equals(env, None, toolchains.if_legacy_toolchain(None))
12+
asserts.equals(env, False, toolchains.if_legacy_toolchain(False))
13+
14+
return unittest.end(env)
15+
16+
toolchains_without_incompatible_flags_test = unittest.make(_test_toolchains_without_incompatible_flag)
17+
18+
def _test_toolchains_with_incompatible_flag(ctx):
19+
env = unittest.begin(ctx)
20+
21+
asserts.equals(env, {}, toolchains.if_legacy_toolchain({}))
22+
asserts.equals(env, {}, toolchains.if_legacy_toolchain(None))
23+
asserts.equals(env, {}, toolchains.if_legacy_toolchain(False))
24+
toolchain = toolchains.use_toolchain("//nonexistent:toolchain_type")
25+
asserts.equals(env, 1, len(toolchain))
26+
asserts.equals(env, False, toolchain[0].mandatory)
27+
asserts.equals(env, str(Label("//nonexistent:toolchain_type")), str(toolchain[0].toolchain_type))
28+
29+
return unittest.end(env)
30+
31+
toolchains_with_incompatible_flag_test = unittest.make(_test_toolchains_with_incompatible_flag)
32+
33+
# buildifier: disable=unnamed-macro
34+
def unittest_toolchains():
35+
unittest.suite(
36+
"test_toolchains",
37+
partial.make(
38+
toolchains_without_incompatible_flags_test,
39+
target_compatible_with = select({
40+
"//tests:incompatible_enable_proto_toolchain_resolution": ["@platforms//:incompatible"],
41+
"//conditions:default": [],
42+
}),
43+
),
44+
partial.make(
45+
toolchains_with_incompatible_flag_test,
46+
target_compatible_with = select({
47+
"//tests:incompatible_enable_proto_toolchain_resolution": [],
48+
"//conditions:default": ["@platforms//:incompatible"],
49+
}),
50+
),
51+
)

0 commit comments

Comments
 (0)