Skip to content

Commit 3cdf80e

Browse files
committed
Implements the 'output_to_workspace' option
1 parent d6c18b6 commit 3cdf80e

File tree

8 files changed

+116
-79
lines changed

8 files changed

+116
-79
lines changed

bzl/base/class.bzl

Lines changed: 53 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,56 @@
1+
def implement_compile_attributes(lang, self):
2+
"""Add attributes for the X_proto_compile rule"""
3+
4+
name = lang.name
5+
attrs = self["attrs"]
6+
7+
# Add "gen_java = X" option where X is True if this is the first
8+
# language specified.
9+
flag = "gen_" + name
10+
attrs[flag] = attr.bool(
11+
default = True,
12+
)
13+
14+
# Add a "gen_java_plugin_options=[]".
15+
opts = flag + "_plugin_options"
16+
attrs[opts] = attr.string_list()
17+
18+
# If there is a plugin binary, create this label now.
19+
if hasattr(lang, "protobuf") and hasattr(lang.protobuf, "executable"):
20+
attrs["gen_protobuf_" + name + "_plugin"] = attr.label(
21+
default = Label(lang.protobuf.executable),
22+
cfg = HOST_CFG,
23+
executable = True,
24+
)
25+
26+
# If this language supports gRPC, add this boolean flag in.
27+
# However, if we didn't load grpc, we don't actually want to
28+
# generate the label for the executable lest we actually need to
29+
# have the executable available. TODO: figure out how to write a
30+
# variable in the loading phase of workspace and read it here.
31+
32+
if hasattr(lang, "grpc"):
33+
attrs["gen_grpc_" + name] = attr.bool()
34+
if hasattr(lang.grpc, "executable"):
35+
attrs["gen_grpc_" + name + "_plugin"] = attr.label(
36+
default = Label(lang.grpc.executable),
37+
cfg = HOST_CFG,
38+
executable = True,
39+
)
40+
41+
42+
def implement_compile_outputs(lang, self):
43+
"""Add customizable outputs for the proto_compile rule"""
44+
if hasattr(lang, "protobuf") and hasattr(lang.protobuf, "outputs"):
45+
self["outputs"] += lang.protobuf.outputs
46+
if hasattr(lang, "grpc") and hasattr(lang.grpc, "outputs"):
47+
self["outputs"] += lang.grpc.outputs
48+
49+
50+
def implement_compile_output_to_genfiles(lang, self):
51+
self["output_to_genfiles"] = getattr(lang, "output_to_genfiles", self["output_to_genfiles"])
52+
53+
154
def get_generated_filename_extensions(lang, self):
255
ctx = self.get("ctx", None)
356
with_grpc = self["with_grpc"]
@@ -132,59 +185,6 @@ def post_execute(lang, self):
132185
pass
133186

134187

135-
def implement_compile_attributes(lang, self):
136-
"""Add attributes for the X_proto_compile rule"""
137-
138-
name = lang.name
139-
attrs = self["attrs"]
140-
141-
# Add "gen_java = X" option where X is True if this is the first
142-
# language specified.
143-
flag = "gen_" + name
144-
attrs[flag] = attr.bool(
145-
default = True,
146-
)
147-
148-
# Add a "gen_java_plugin_options=[]".
149-
opts = flag + "_plugin_options"
150-
attrs[opts] = attr.string_list()
151-
152-
# If there is a plugin binary, create this label now.
153-
if hasattr(lang, "protobuf") and hasattr(lang.protobuf, "executable"):
154-
attrs["gen_protobuf_" + name + "_plugin"] = attr.label(
155-
default = Label(lang.protobuf.executable),
156-
cfg = HOST_CFG,
157-
executable = True,
158-
)
159-
160-
# If this language supports gRPC, add this boolean flag in.
161-
# However, if we didn't load grpc, we don't actually want to
162-
# generate the label for the executable lest we actually need to
163-
# have the executable available. TODO: figure out how to write a
164-
# variable in the loading phase of workspace and read it here.
165-
166-
if hasattr(lang, "grpc"):
167-
attrs["gen_grpc_" + name] = attr.bool()
168-
if hasattr(lang.grpc, "executable"):
169-
attrs["gen_grpc_" + name + "_plugin"] = attr.label(
170-
default = Label(lang.grpc.executable),
171-
cfg = HOST_CFG,
172-
executable = True,
173-
)
174-
175-
176-
def implement_compile_outputs(lang, self):
177-
"""Add customizable outputs for the proto_compile rule"""
178-
if hasattr(lang, "protobuf") and hasattr(lang.protobuf, "outputs"):
179-
self["outputs"] += lang.protobuf.outputs
180-
if hasattr(lang, "grpc") and hasattr(lang.grpc, "outputs"):
181-
self["outputs"] += lang.grpc.outputs
182-
183-
184-
def implement_compile_output_to_genfiles(lang, self):
185-
self["output_to_genfiles"] = getattr(lang, "output_to_genfiles", self["output_to_genfiles"])
186-
187-
188188
CLASS = struct(
189189
name = "base",
190190

bzl/cpp/rules.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ def cc_proto_library(
1212
grpc_plugin_options = [],
1313
imports = [],
1414
lang = CPP,
15+
output_to_workspace = False,
1516
protobuf_plugin_options = [],
1617
protobuf_plugin = None,
1718
proto_compile = cc_proto_compile,
@@ -33,6 +34,7 @@ def cc_proto_library(
3334
args["gen_protobuf_" + lang.name + "_plugin"] = protobuf_plugin
3435
args["gen_" + lang.name + "_plugin_options"] = protobuf_plugin_options
3536
args["gen_grpc_" + lang.name + "_plugin"] = grpc_plugin
37+
args["output_to_workspace"] = output_to_workspace
3638
args["proto_deps"] = [d + ".pb" for d in proto_deps]
3739
args["protoc"] = protoc
3840
args["protos"] = protos

bzl/go/rules.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ def go_proto_library(
1212
grpc_plugin_options = [],
1313
imports = [],
1414
lang = GO,
15+
output_to_workspace = False,
1516
protobuf_plugin_options = [],
1617
protobuf_plugin = None,
1718
proto_compile = go_proto_compile,
@@ -34,6 +35,7 @@ def go_proto_library(
3435
args["gen_protobuf_" + lang.name + "_plugin"] = protobuf_plugin
3536
args["gen_" + lang.name + "_plugin_options"] = protobuf_plugin_options
3637
args["gen_grpc_" + lang.name + "_plugin"] = grpc_plugin
38+
args["output_to_workspace"] = output_to_workspace
3739
args["protoc"] = protoc
3840
args["protos"] = protos
3941
args["verbose"] = verbose

bzl/grpc_gateway/rules.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ def grpc_gateway_proto_library(
1414
grpc_plugin_options = [],
1515
imports = [],
1616
lang = GATEWAY,
17+
output_to_workspace = False,
1718
protobuf_plugin_options = [],
1819
protobuf_plugin = None,
1920
proto_compile = grpc_gateway_proto_compile,
@@ -50,6 +51,7 @@ def grpc_gateway_proto_library(
5051
args["gen_protobuf_" + GO.name + "_plugin"] = GO.protobuf.executable
5152
args[GO.name + "_import_map"] = go_import_map + GATEWAY.default_go_import_map
5253

54+
args["output_to_workspace"] = output_to_workspace
5355
args["proto_deps"] = [d + ".pb" for d in proto_deps]
5456
args["protoc"] = protoc
5557
args["protos"] = protos

bzl/java/class.bzl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
load("//bzl:base/class.bzl", BASE = "CLASS", "build_plugin_out")
2+
load("//bzl:util.bzl", "invoke", "invokesuper")
23

34

45
def _build_generated_files(lang, self):
56
"""Build a jar file for protoc to dump java classes into."""
67

78
ctx = self.get("ctx", None)
8-
if ctx == None:
9-
fail("Java implementation requires bazel context")
109

1110
srcjar = ctx.outputs.srcjar
1211
basename = srcjar.basename[:-len(".srcjar")]

bzl/java/rules.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ def java_proto_library(
1111
grpc_plugin_options = [],
1212
imports = [],
1313
lang = JAVA,
14+
output_to_workspace = False,
1415
protobuf_plugin_options = [],
1516
protobuf_plugin = None,
1617
proto_compile = java_proto_compile,
@@ -32,6 +33,7 @@ def java_proto_library(
3233
args["gen_protobuf_" + lang.name + "_plugin"] = protobuf_plugin
3334
args["gen_" + lang.name + "_plugin_options"] = protobuf_plugin_options
3435
args["gen_grpc_" + lang.name + "_plugin"] = grpc_plugin
36+
args["output_to_workspace"] = output_to_workspace
3537
args["proto_deps"] = [d + "_pb" for d in deps]
3638
args["protoc"] = protoc
3739
args["protos"] = protos

bzl/protoc.bzl

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,31 @@ def _execute_rule(self):
3232
for i in range(len(outputs)):
3333
print(" > output%s: %s" % (i, outputs[i]))
3434

35+
if ctx.attr.output_to_workspace:
36+
manifest = ["//" + file.short_path for file in self["provides"]]
37+
print(
38+
"""
39+
>**************************************************************************
40+
* - Generating files into the workspace... This is potentially *
41+
* dangerous (may overwrite existing files) and violates bazel's *
42+
* sandbox policy. *
43+
* - Disregard "ERROR: output 'foo.pb.*' was not created." messages. *
44+
* - Build will halt following the "not all outputs were created" message. *
45+
* - Output manifest is printed below. *
46+
**************************************************************************<
47+
%s
48+
>*************************************************************************<
49+
""" % "\n".join(manifest)
50+
)
51+
3552
ctx.action(
36-
mnemonic="ProtoCompile",
37-
executable=ctx.executable.protoc,
38-
arguments=arguments,
39-
inputs=inputs,
40-
outputs=outputs,
53+
mnemonic="ProtoCompile",
54+
executable=ctx.executable.protoc,
55+
arguments=arguments,
56+
inputs=inputs,
57+
outputs=outputs,
58+
env = {
59+
}
4160
)
4261

4362

@@ -81,7 +100,9 @@ def _protoc_rule_impl(ctx):
81100

82101
gendir = _get_gendir(ctx)
83102
outdir = gendir
84-
#outdir = gendir + "/" + ctx.label.package
103+
104+
if ctx.attr.output_to_workspace:
105+
outdir = "."
85106

86107
self = {
87108
"ctx": ctx,
@@ -220,11 +241,17 @@ def implement(spec):
220241
invoke("implement_compile_outputs", lang, self)
221242
invoke("implement_compile_output_to_genfiles", lang, self)
222243

223-
# Generation location. cpp requires genfiles, everyone else not.
244+
# Flag to place generated files in bazel-genfiles. cpp requires
245+
# genfiles, everyone else not.
224246
attrs["output_to_genfiles"] = attr.bool(
225247
default = self["output_to_genfiles"],
226248
)
227249

250+
# Flag to place generated files in the bazel workspace. May violate sandbox constraints.
251+
attrs["output_to_workspace"] = attr.bool(
252+
default = False,
253+
)
254+
228255
return rule(
229256
implementation = _protoc_rule_impl,
230257
attrs = self["attrs"],

examples/helloworld/grpc_gateway/BUILD

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,29 @@ load("//bzl:go/class.bzl", GO = "CLASS")
55
load("//bzl:grpc_gateway/class.bzl", GRPC_GATEWAY = "CLASS")
66
load("//bzl:grpc_gateway/rules.bzl", "grpc_gateway_proto_library", "grpc_gateway_binary")
77

8+
9+
go_test(
10+
name = "greeter_test",
11+
size = "small",
12+
srcs = [
13+
"greeter.go",
14+
"greeter_test.go",
15+
],
16+
deps = [
17+
":gateway",
18+
"//examples/helloworld/go/server:greeter",
19+
"//examples/helloworld/proto:go",
20+
"@com_github_golang_protobuf//:jsonpb",
21+
] + GRPC_GATEWAY.grpc.compile_deps,
22+
)
23+
24+
# Alternate form
25+
#
826
# grpc_gateway_proto_library(
927
# name = "gateway",
28+
# output_to_workspace = True,
1029
# protos = ["helloworld.proto"],
11-
# verbose = 2,
30+
# verbose = 0,
1231
# )
1332

1433
grpc_gateway_binary(
@@ -32,19 +51,3 @@ grpc_gateway_binary(
3251
# "@org_golang_x_net//:context",
3352
# ],
3453
# )
35-
36-
37-
go_test(
38-
name = "greeter_test",
39-
size = "small",
40-
srcs = [
41-
"greeter.go",
42-
"greeter_test.go",
43-
],
44-
deps = [
45-
":gateway",
46-
"//examples/helloworld/go/server:greeter",
47-
"//examples/helloworld/proto:go",
48-
"@com_github_golang_protobuf//:jsonpb",
49-
] + GRPC_GATEWAY.grpc.compile_deps,
50-
)

0 commit comments

Comments
 (0)