Skip to content

Commit b85d122

Browse files
authored
Scala proto conventional stamping (#1243)
* Deprecate scalapb_proto_library * Refactor/cleanup scala_proto * proto scala move to phases (in progress 1) * Add phases to proto aspect * Add stamping phase to scala proto aspect * Add aspect customization * Lint * Lint: remove unreachable code * Fixes after review
1 parent e0051b1 commit b85d122

File tree

17 files changed

+326
-95
lines changed

17 files changed

+326
-95
lines changed

scala/private/phases/api.bzl

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,13 @@ def _adjust_phases(phases, adjustments):
4141
break
4242
return phases
4343

44-
# Execute phases
4544
def run_phases(ctx, builtin_customizable_phases):
45+
return _run_phases(ctx, builtin_customizable_phases, target = None)
46+
47+
def run_aspect_phases(ctx, builtin_customizable_phases, target):
48+
return _run_phases(ctx, builtin_customizable_phases, target)
49+
50+
def _run_phases(ctx, builtin_customizable_phases, target):
4651
# Loading custom phases
4752
# Phases must be passed in by provider
4853
phase_providers = [
@@ -62,7 +67,9 @@ def run_phases(ctx, builtin_customizable_phases):
6267
)
6368

6469
# A placeholder for data shared with later phases
65-
global_provider = {}
70+
global_provider = {
71+
"target": target,
72+
}
6673
current_provider = struct(**global_provider)
6774
acculmulated_external_providers = {}
6875
for (name, function) in adjusted_phases:

scala/private/rule_impls.bzl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ def compile_scala(
5454
scalac_jvm_flags,
5555
scalac,
5656
dependency_info,
57-
unused_dependency_checker_ignored_targets):
57+
unused_dependency_checker_ignored_targets,
58+
stamp_target_label = None):
5859
# look for any plugins:
5960
input_plugins = plugins
6061
plugins = _collect_plugin_paths(plugins)
@@ -72,6 +73,7 @@ def compile_scala(
7273
args.set_param_file_format("multiline")
7374
args.use_param_file(param_file_arg = "@%s", use_always = True)
7475
args.add("--CurrentTarget", target_label)
76+
args.add("--StampLabel", stamp_target_label if stamp_target_label != None else target_label)
7577
args.add("--JarOutput", output)
7678
args.add("--Manifest", manifest)
7779
args.add("--PrintCompileTime", print_compile_time)

scala_proto/BUILD

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
load(
22
"//scala_proto:scala_proto_toolchain.bzl",
3-
"export_scalapb_toolchain_deps",
43
"scala_proto_deps_toolchain",
54
"scala_proto_toolchain",
65
)
76
load(
8-
"//scala_proto:default_dep_sets.bzl",
7+
"//scala_proto/default:default_deps.bzl",
98
"DEFAULT_SCALAPB_COMPILE_DEPS",
109
"DEFAULT_SCALAPB_GRPC_DEPS",
1110
)
1211
load("//scala:providers.bzl", "declare_deps_provider")
12+
load("//scala_proto/private:toolchain_deps.bzl", "export_scalapb_toolchain_deps")
1313

1414
toolchain_type(
1515
name = "toolchain_type",
@@ -52,7 +52,6 @@ scala_proto_toolchain(
5252
visibility = ["//visibility:public"],
5353
with_flat_package = True,
5454
with_grpc = True,
55-
# with_java=True,
5655
with_single_line_to_string = True,
5756
)
5857

scala_proto/default/BUILD

Whitespace-only changes.
File renamed without changes.

scala_proto/private/scala_proto_default_repositories.bzl renamed to scala_proto/default/repositories.bzl

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
1-
load(
2-
"//scala:scala_cross_version.bzl",
3-
_default_maven_server_urls = "default_maven_server_urls",
4-
)
1+
load("//scala:scala_cross_version.bzl", "default_maven_server_urls")
52
load("//third_party/repositories:repositories.bzl", "repositories")
63

74
def scala_proto_default_repositories(
8-
maven_servers = _default_maven_server_urls(),
5+
maven_servers = default_maven_server_urls(),
96
overriden_artifacts = {}):
107
repositories(
118
for_artifact_ids = [
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
load("@rules_proto//proto:defs.bzl", "ProtoInfo")
2+
load(
3+
"@io_bazel_rules_scala//scala_proto/private:scala_proto_aspect_provider.bzl",
4+
"ScalaProtoAspectInfo",
5+
)
6+
load(
7+
"@io_bazel_rules_scala//scala/private:phases/api.bzl",
8+
"extras_phases",
9+
"run_phases",
10+
)
11+
load("@bazel_skylib//lib:dicts.bzl", "dicts")
12+
load("//scala_proto/private:scala_proto_aspect.bzl", "make_scala_proto_aspect")
13+
14+
def phase_merge_aspect_java_info(ctx, p):
15+
java_info = java_common.merge([dep[ScalaProtoAspectInfo].java_info for dep in ctx.attr.deps])
16+
return struct(
17+
java_info = java_info,
18+
external_providers = {
19+
"JavaInfo": java_info,
20+
},
21+
)
22+
23+
def phase_default_info(ctx, p):
24+
java_info = p.merge_aspects.java_info
25+
return struct(
26+
external_providers = {
27+
"DefaultInfo": DefaultInfo(
28+
files = depset(
29+
java_info.source_jars,
30+
transitive = [java_info.full_compile_jars],
31+
),
32+
),
33+
},
34+
)
35+
36+
def _scala_proto_library(ctx):
37+
return run_phases(
38+
ctx,
39+
[
40+
("merge_aspects", phase_merge_aspect_java_info),
41+
("default_info", phase_default_info),
42+
],
43+
)
44+
45+
scala_proto_aspect = make_scala_proto_aspect()
46+
47+
def make_scala_proto_library(*extras, aspects = [scala_proto_aspect]):
48+
attrs = {
49+
"deps": attr.label_list(providers = [ProtoInfo], aspects = aspects),
50+
}
51+
return rule(
52+
implementation = _scala_proto_library,
53+
attrs = dicts.add(
54+
attrs,
55+
extras_phases(extras),
56+
*[extra["attrs"] for extra in extras if "attrs" in extra]
57+
),
58+
fragments = ["java"],
59+
provides = [DefaultInfo, JavaInfo],
60+
)
61+
62+
scala_proto_library = make_scala_proto_library(
63+
aspects = [
64+
scala_proto_aspect,
65+
],
66+
)

scala_proto/private/scalapb_aspect.bzl renamed to scala_proto/private/scala_proto_aspect.bzl

Lines changed: 82 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,21 @@ load("//scala/private:common.bzl", "write_manifest_file")
33
load("//scala/private:dependency.bzl", "legacy_unclear_dependency_info_for_protobuf_scrooge")
44
load("//scala/private:rule_impls.bzl", "compile_scala")
55
load("//scala/private/toolchain_deps:toolchain_deps.bzl", "find_deps_info_on")
6-
load("@bazel_tools//tools/jdk:toolchain_utils.bzl", "find_java_runtime_toolchain", "find_java_toolchain")
7-
8-
ScalaPBAspectInfo = provider(fields = [
9-
"java_info",
10-
])
6+
load(
7+
"@bazel_tools//tools/jdk:toolchain_utils.bzl",
8+
"find_java_runtime_toolchain",
9+
"find_java_toolchain",
10+
)
11+
load(
12+
"@io_bazel_rules_scala//scala_proto/private:scala_proto_aspect_provider.bzl",
13+
"ScalaProtoAspectInfo",
14+
)
15+
load(
16+
"@io_bazel_rules_scala//scala/private:phases/api.bzl",
17+
"extras_phases",
18+
"run_aspect_phases",
19+
)
20+
load("@bazel_skylib//lib:dicts.bzl", "dicts")
1121

1222
def _import_paths(proto):
1323
source_root = proto.proto_source_root
@@ -75,7 +85,7 @@ def _generate_sources(ctx, toolchain, proto):
7585

7686
return outputs.values()
7787

78-
def _compile_sources(ctx, toolchain, proto, src_jars, deps):
88+
def _compile_sources(ctx, toolchain, proto, src_jars, deps, stamp_label):
7989
output = ctx.actions.declare_file(ctx.label.name + "_scalapb.jar")
8090
manifest = ctx.actions.declare_file(ctx.label.name + "_MANIFEST.MF")
8191
write_manifest_file(ctx.actions, manifest, None)
@@ -111,6 +121,7 @@ def _compile_sources(ctx, toolchain, proto, src_jars, deps):
111121
scalac = toolchain.scalac,
112122
dependency_info = legacy_unclear_dependency_info_for_protobuf_scrooge(ctx),
113123
unused_dependency_checker_ignored_targets = [],
124+
stamp_target_label = stamp_label,
114125
)
115126

116127
return JavaInfo(
@@ -122,27 +133,60 @@ def _compile_sources(ctx, toolchain, proto, src_jars, deps):
122133
runtime_deps = compile_deps,
123134
)
124135

125-
####
126-
# This is applied to the DAG of proto_librarys reachable from a deps
127-
# or a scalapb_scala_library. Each proto_library will be one scalapb
128-
# invocation assuming it has some sources.
129-
def _scalapb_aspect_impl(target, ctx):
136+
def _phase_proto_provider(ctx, p):
137+
return p.target[ProtoInfo]
138+
139+
def _phase_deps(ctx, p):
140+
return [d[ScalaProtoAspectInfo].java_info for d in ctx.rule.attr.deps]
141+
142+
def _phase_generate_and_compile(ctx, p):
143+
proto = p.proto_info
144+
deps = p.deps
145+
stamp_label = p.stamp_label
130146
toolchain = ctx.toolchains["@io_bazel_rules_scala//scala_proto:toolchain_type"]
131-
proto = target[ProtoInfo]
132-
deps = [d[ScalaPBAspectInfo].java_info for d in ctx.rule.attr.deps]
133147

134148
if proto.direct_sources and _code_should_be_generated(ctx, toolchain):
135149
src_jars = _generate_sources(ctx, toolchain, proto)
136-
java_info = _compile_sources(ctx, toolchain, proto, src_jars, deps)
137-
return [ScalaPBAspectInfo(java_info = java_info)]
150+
java_info = _compile_sources(ctx, toolchain, proto, src_jars, deps, stamp_label)
151+
return java_info
138152
else:
139153
# this target is only an aggregation target
140-
return [ScalaPBAspectInfo(java_info = java_common.merge(deps))]
154+
return java_common.merge(deps)
155+
156+
def _phase_aspect_provider(ctx, p):
157+
return struct(
158+
external_providers = {
159+
"ScalaProtoAspectInfo": ScalaProtoAspectInfo(java_info = p.generate_and_compile),
160+
},
161+
)
162+
163+
def _phase_stamp_label(ctx, p):
164+
rule_label = str(p.target.label)
165+
toolchain = ctx.toolchains["@io_bazel_rules_scala//scala_proto:toolchain_type"]
141166

142-
scalapb_aspect = aspect(
143-
implementation = _scalapb_aspect_impl,
144-
attr_aspects = ["deps"],
145-
incompatible_use_toolchain_transition = True,
167+
if toolchain.stamp_by_convention and rule_label.endswith("_proto"):
168+
return rule_label.rstrip("_proto") + "_scala_proto"
169+
else:
170+
return rule_label
171+
172+
####
173+
# This is applied to the DAG of proto_librarys reachable from a deps
174+
# or a scalapb_scala_library. Each proto_library will be one scalapb
175+
# invocation assuming it has some sources.
176+
def _scala_proto_aspect_impl(target, ctx):
177+
return run_aspect_phases(
178+
ctx,
179+
[
180+
("proto_info", _phase_proto_provider),
181+
("deps", _phase_deps),
182+
("stamp_label", _phase_stamp_label),
183+
("generate_and_compile", _phase_generate_and_compile),
184+
("aspect_provider", _phase_aspect_provider),
185+
],
186+
target = target,
187+
)
188+
189+
def make_scala_proto_aspect(*extras):
146190
attrs = {
147191
"_java_toolchain": attr.label(
148192
default = Label("@bazel_tools//tools/jdk:current_java_toolchain"),
@@ -151,10 +195,21 @@ scalapb_aspect = aspect(
151195
default = Label("@bazel_tools//tools/jdk:current_java_runtime"),
152196
cfg = "exec",
153197
),
154-
},
155-
toolchains = [
156-
"@io_bazel_rules_scala//scala:toolchain_type",
157-
"@io_bazel_rules_scala//scala_proto:toolchain_type",
158-
"@io_bazel_rules_scala//scala_proto:deps_toolchain_type",
159-
],
160-
)
198+
}
199+
return aspect(
200+
implementation = _scala_proto_aspect_impl,
201+
attr_aspects = ["deps"],
202+
incompatible_use_toolchain_transition = True,
203+
attrs = dicts.add(
204+
attrs,
205+
extras_phases(extras),
206+
*[extra["attrs"] for extra in extras if "attrs" in extra]
207+
),
208+
toolchains = [
209+
"@io_bazel_rules_scala//scala:toolchain_type",
210+
"@io_bazel_rules_scala//scala_proto:toolchain_type",
211+
"@io_bazel_rules_scala//scala_proto:deps_toolchain_type",
212+
],
213+
)
214+
215+
scala_proto_aspect = make_scala_proto_aspect()
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
ScalaProtoAspectInfo = provider(fields = [
2+
"java_info",
3+
])
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
load(
2+
"@io_bazel_rules_scala//scala/private/toolchain_deps:toolchain_deps.bzl",
3+
"expose_toolchain_deps",
4+
)
5+
6+
def _export_scalapb_toolchain_deps(ctx):
7+
return expose_toolchain_deps(ctx, "@io_bazel_rules_scala//scala_proto:deps_toolchain_type")
8+
9+
export_scalapb_toolchain_deps = rule(
10+
_export_scalapb_toolchain_deps,
11+
attrs = {
12+
"deps_id": attr.string(
13+
mandatory = True,
14+
),
15+
},
16+
incompatible_use_toolchain_transition = True,
17+
toolchains = ["@io_bazel_rules_scala//scala_proto:deps_toolchain_type"],
18+
)

0 commit comments

Comments
 (0)