java_grpc_library.bzl: workaround strict_deps

This is a sync from our internal copy, so has lots of small changes.
But the most important change is strict_deps issues are worked around
within the rule. This means there should be no longer any reason to
specify more than one dep.

Our Bazel CI is still on Bazel 0.20, so for the moment avoid requiring
Bazel 0.22 by staying on the old 'proto' provider instead of ProtoInfo.

Fixes #5314
This commit is contained in:
Eric Anderson 2019-02-11 15:17:34 -08:00 committed by GitHub
parent d47379947f
commit efa2e47335
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 121 additions and 70 deletions

View File

@ -24,3 +24,30 @@ java_grpc_library(
srcs = ["@com_google_protobuf//:api_proto"], srcs = ["@com_google_protobuf//:api_proto"],
deps = [":api_proto_java"], deps = [":api_proto_java"],
) )
java_library(
name = "java_grpc_library_deps__do_not_reference",
visibility = ["//visibility:public"],
exports = [
"//core",
"//protobuf",
"//stub",
"//stub:javax_annotation",
"@com_google_code_findbugs_jsr305//jar",
"@com_google_guava_guava//jar",
"@com_google_protobuf//:protobuf_java",
],
)
java_library(
name = "java_lite_grpc_library_deps__do_not_reference",
visibility = ["//visibility:public"],
exports = [
"//core",
"//protobuf-lite",
"//stub",
"//stub:javax_annotation",
"@com_google_code_findbugs_jsr305//jar",
"@com_google_guava_guava//jar",
],
)

View File

@ -1,60 +1,74 @@
# "repository" here is for Bazel builds that span multiple WORKSPACES.
def _path_ignoring_repository(f): def _path_ignoring_repository(f):
if (len(f.owner.workspace_root) == 0): if len(f.owner.workspace_root) == 0:
return f.short_path return f.short_path
return f.path[f.path.find(f.owner.workspace_root) + len(f.owner.workspace_root) + 1:] return f.path[f.path.find(f.owner.workspace_root) + len(f.owner.workspace_root) + 1:]
def _gensource_impl(ctx): def _create_include_path(include):
if len(ctx.attr.srcs) > 1: return "-I{0}={1}".format(_path_ignoring_repository(include), include.path)
fail("Only one src value supported", "srcs")
for s in ctx.attr.srcs:
if s.label.package != ctx.label.package:
print(("in srcs attribute of {0}: Proto source with label {1} should be in " +
"same package as consuming rule").format(ctx.label, s.label))
# Use .jar since .srcjar makes protoc think output will be a directory def _java_rpc_library_impl(ctx):
srcdotjar = ctx.new_file(ctx.label.name + "_src.jar") if len(ctx.attr.srcs) != 1:
fail("Exactly one src value supported", "srcs")
srcs = [f for dep in ctx.attr.srcs for f in dep.proto.direct_sources] if ctx.attr.srcs[0].label.package != ctx.label.package:
includes = [f for dep in ctx.attr.srcs for f in dep.proto.transitive_imports] print(("in srcs attribute of {0}: Proto source with label {1} should be in " +
"same package as consuming rule").format(ctx.label, ctx.attr.srcs[0].label))
srcs = ctx.attr.srcs[0].proto.direct_sources
includes = ctx.attr.srcs[0].proto.transitive_imports
flavor = ctx.attr.flavor flavor = ctx.attr.flavor
if flavor == "normal": if flavor == "normal":
flavor = "" flavor = ""
args = ctx.actions.args()
args.add(ctx.executable._java_plugin.path, format = "--plugin=protoc-gen-grpc-java=%s")
args.add("--grpc-java_out={0}:{1}".format(flavor, ctx.outputs.srcjar.path))
args.add_all(includes, map_each = _create_include_path)
args.add_all(srcs, map_each = _path_ignoring_repository)
ctx.action( ctx.action(
inputs = [ctx.executable._java_plugin] + srcs + includes, inputs = depset([ctx.executable._java_plugin] + srcs, transitive = [includes]),
outputs = [srcdotjar],
executable = ctx.executable._protoc,
arguments = [
"--plugin=protoc-gen-grpc-java=" + ctx.executable._java_plugin.path,
"--grpc-java_out={0},enable_deprecated={1}:{2}"
.format(flavor, str(ctx.attr.enable_deprecated).lower(), srcdotjar.path),
] +
["-I{0}={1}".format(_path_ignoring_repository(include), include.path) for include in includes] +
[_path_ignoring_repository(src) for src in srcs],
)
ctx.action(
command = "cp $1 $2",
inputs = [srcdotjar],
outputs = [ctx.outputs.srcjar], outputs = [ctx.outputs.srcjar],
arguments = [srcdotjar.path, ctx.outputs.srcjar.path], executable = ctx.executable._protoc,
arguments = [args],
) )
_gensource = rule( deps_java_info = java_common.merge([dep[JavaInfo] for dep in ctx.attr.deps])
java_info = java_common.compile(
ctx,
java_toolchain = ctx.attr._java_toolchain,
host_javabase = ctx.attr._host_javabase,
source_jars = [ctx.outputs.srcjar],
output = ctx.outputs.jar,
deps = [
java_common.make_non_strict(deps_java_info),
ctx.attr.runtime[JavaInfo],
],
)
return [java_info]
_java_rpc_library = rule(
attrs = { attrs = {
"srcs": attr.label_list( "srcs": attr.label_list(
mandatory = True, mandatory = True,
non_empty = True, non_empty = True,
providers = ["proto"], providers = ["proto"],
), ),
"deps": attr.label_list(
mandatory = True,
non_empty = True,
providers = [JavaInfo],
),
"flavor": attr.string( "flavor": attr.string(
values = [ values = [
"normal", "normal",
"lite", # Not currently supported "lite",
], ],
default = "normal", default = "normal",
), ),
"enable_deprecated": attr.bool( "runtime": attr.label(
default = False, mandatory = True,
), ),
"_protoc": attr.label( "_protoc": attr.label(
default = Label("@com_google_protobuf//:protoc"), default = Label("@com_google_protobuf//:protoc"),
@ -66,11 +80,21 @@ _gensource = rule(
executable = True, executable = True,
cfg = "host", cfg = "host",
), ),
"_java_toolchain": attr.label(
default = Label("@bazel_tools//tools/jdk:current_java_toolchain"),
),
"_host_javabase": attr.label(
cfg = "host",
default = Label("@bazel_tools//tools/jdk:current_host_java_runtime"),
),
}, },
fragments = ["java"],
outputs = { outputs = {
"srcjar": "%{name}.srcjar", "jar": "lib%{name}.jar",
"srcjar": "lib%{name}-src.jar",
}, },
implementation = _gensource_impl, provides = [JavaInfo],
implementation = _java_rpc_library_impl,
) )
def java_grpc_library( def java_grpc_library(
@ -78,15 +102,17 @@ def java_grpc_library(
srcs, srcs,
deps, deps,
flavor = None, flavor = None,
enable_deprecated = None, tags = None,
visibility = None, visibility = None,
**kwargs): **kwargs):
"""Generates and compiles gRPC Java sources for services defined in a proto """Generates and compiles gRPC Java sources for services defined in a proto
file. This rule is compatible with java_proto_library and java_lite_proto_library. file. This rule is compatible with proto_library with java_api_version,
java_proto_library, and java_lite_proto_library.
Do note that this rule only scans through the proto file for RPC services. It Do note that this rule only scans through the proto file for RPC services. It
does not generate Java classes for proto messages. You will need a separate does not generate Java classes for proto messages. You will need a separate
java_proto_library or java_lite_proto_library rule. proto_library with java_api_version, java_proto_library, or
java_lite_proto_library rule.
Args: Args:
name: (str) A unique name for this rule. Required. name: (str) A unique name for this rule. Required.
@ -99,44 +125,42 @@ def java_grpc_library(
visibility: (list) the visibility list visibility: (list) the visibility list
**kwargs: Passed through to generated targets **kwargs: Passed through to generated targets
""" """
if flavor == None:
flavor = "normal"
if len(deps) > 1: if len(deps) > 1:
print("Multiple values in 'deps' is deprecated in " + name) print("Multiple values in 'deps' is deprecated in " + name)
gensource_name = name + "__do_not_reference__srcjar" if flavor == "lite":
_gensource( inner_name = name + "__do_not_reference"
name = gensource_name, inner_visibility = ["//visibility:private"]
srcs = srcs, inner_tags = ["avoid_dep"]
flavor = flavor, runtime = "@io_grpc_grpc_java//:java_lite_grpc_library_deps__do_not_reference"
enable_deprecated = enable_deprecated,
visibility = ["//visibility:private"],
**kwargs
)
added_deps = [
"@io_grpc_grpc_java//core",
"@io_grpc_grpc_java//stub",
"@io_grpc_grpc_java//stub:javax_annotation",
"@com_google_guava_guava//jar",
]
if flavor == "normal":
added_deps += [
"@com_google_protobuf//:protobuf_java",
"@io_grpc_grpc_java//protobuf",
]
elif flavor == "lite":
added_deps += ["@io_grpc_grpc_java//protobuf-lite"]
else: else:
fail("Unknown flavor type", "flavor") inner_name = name
inner_visibility = visibility
inner_tags = tags
runtime = "@io_grpc_grpc_java//:java_grpc_library_deps__do_not_reference"
native.java_library( _java_rpc_library(
name = name, name = inner_name,
srcs = [gensource_name], srcs = srcs,
visibility = visibility, deps = deps,
deps = [ flavor = flavor,
"@com_google_code_findbugs_jsr305//jar", runtime = runtime,
] + deps + added_deps, visibility = inner_visibility,
tags = inner_tags,
**kwargs **kwargs
) )
if flavor == "lite":
# Use java_import to work around error with android_binary:
# Dependencies on .jar artifacts are not allowed in Android binaries,
# please use a java_import to depend on...
native.java_import(
name = name,
deps = deps + [runtime],
jars = [":lib{}.jar".format(inner_name)],
srcjar = ":lib{}-src.jar".format(inner_name),
visibility = visibility,
tags = tags,
**kwargs
)