mirror of
https://github.com/digital-asset/daml.git
synced 2024-11-10 10:46:11 +03:00
7287063072
052f69cde9
broke the structure of our protobufs by changing the import prefix
from "." to an empty string which ends up flattening the whole
file. This PR changes the default for tars to match the old
behavior. We can’t just change the default at the function level since
the prefix is used outside of pkg_tar and in those places an empty
string is required :(
changelog_begin
changelog_end
319 lines
11 KiB
Python
319 lines
11 KiB
Python
# Copyright (c) 2021 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
load("//bazel_tools:java.bzl", "da_java_library")
|
|
load("//bazel_tools:javadoc_library.bzl", "javadoc_library")
|
|
load("//bazel_tools:pkg.bzl", "pkg_empty_zip")
|
|
load("//bazel_tools:pom_file.bzl", "pom_file")
|
|
load("//bazel_tools:scala.bzl", "scala_source_jar", "scaladoc_jar")
|
|
load("@io_bazel_rules_scala//scala:scala.bzl", "scala_library")
|
|
load("@os_info//:os_info.bzl", "is_windows")
|
|
load("@rules_pkg//:pkg.bzl", "pkg_tar")
|
|
load("@rules_proto//proto:defs.bzl", "proto_library")
|
|
load("@scala_version//:index.bzl", "scala_major_version_suffix")
|
|
|
|
# taken from rules_proto:
|
|
# https://github.com/stackb/rules_proto/blob/f5d6eea6a4528bef3c1d3a44d486b51a214d61c2/compile.bzl#L369-L393
|
|
def get_plugin_runfiles(tool, plugin_runfiles):
|
|
"""Gather runfiles for a plugin.
|
|
"""
|
|
files = []
|
|
if not tool:
|
|
return files
|
|
|
|
info = tool[DefaultInfo]
|
|
if not info:
|
|
return files
|
|
|
|
if info.files:
|
|
files += info.files.to_list()
|
|
|
|
if info.default_runfiles:
|
|
runfiles = info.default_runfiles
|
|
if runfiles.files:
|
|
files += runfiles.files.to_list()
|
|
|
|
if info.data_runfiles:
|
|
runfiles = info.data_runfiles
|
|
if runfiles.files:
|
|
files += runfiles.files.to_list()
|
|
|
|
if plugin_runfiles:
|
|
for target in plugin_runfiles:
|
|
files += target.files.to_list()
|
|
|
|
return files
|
|
|
|
def _proto_gen_impl(ctx):
|
|
sources_out = ctx.actions.declare_directory(ctx.attr.name + "-sources")
|
|
|
|
descriptor_set_delim = "\\;" if _is_windows(ctx) else ":"
|
|
descriptors = [depset for src in ctx.attr.srcs for depset in src[ProtoInfo].transitive_descriptor_sets.to_list()]
|
|
args = [
|
|
"--descriptor_set_in=" + descriptor_set_delim.join([depset.path for depset in descriptors]),
|
|
"--{}_out={}:{}".format(ctx.attr.plugin_name, ",".join(ctx.attr.plugin_options), sources_out.path),
|
|
]
|
|
plugins = []
|
|
plugin_runfiles = []
|
|
if ctx.attr.plugin_name not in ["java", "python"]:
|
|
plugins = [ctx.executable.plugin_exec]
|
|
plugin_runfiles = get_plugin_runfiles(ctx.attr.plugin_exec, ctx.attr.plugin_runfiles)
|
|
args += [
|
|
"--plugin=protoc-gen-{}={}".format(ctx.attr.plugin_name, ctx.executable.plugin_exec.path),
|
|
]
|
|
|
|
inputs = []
|
|
|
|
for src in ctx.attr.srcs:
|
|
src_root = src[ProtoInfo].proto_source_root
|
|
for direct_source in src[ProtoInfo].direct_sources:
|
|
path = ""
|
|
|
|
# in some cases the paths of src_root and direct_source are only partially
|
|
# overlapping. the following for loop finds the maximum overlap of these two paths
|
|
for i in range(len(src_root) + 1):
|
|
if direct_source.path.startswith(src_root[-i:]):
|
|
path = direct_source.path[i:]
|
|
else:
|
|
# this noop is needed to make bazel happy
|
|
noop = ""
|
|
|
|
path = direct_source.short_path if not path else path
|
|
path = path[1:] if path.startswith("/") else path
|
|
|
|
inputs += [path]
|
|
|
|
args += inputs
|
|
|
|
posix = ctx.toolchains["@rules_sh//sh/posix:toolchain_type"]
|
|
ctx.actions.run_shell(
|
|
mnemonic = "ProtoGen",
|
|
outputs = [sources_out],
|
|
inputs = descriptors + [ctx.executable.protoc] + plugin_runfiles,
|
|
command = posix.commands["mkdir"] + " -p " + sources_out.path + " && " + ctx.executable.protoc.path + " " + " ".join(args),
|
|
tools = plugins,
|
|
)
|
|
|
|
# since we only have the output directory of the protoc compilation,
|
|
# we need to find all the files below sources_out and add them to the zipper args file
|
|
zipper_args_file = ctx.actions.declare_file(ctx.label.name + ".zipper_args")
|
|
ctx.actions.run_shell(
|
|
mnemonic = "CreateZipperArgsFile",
|
|
outputs = [zipper_args_file],
|
|
inputs = [sources_out],
|
|
command = "{find} -L {src_path} -type f | {sed} -E 's#^{src_path}/(.*)$#\\1={src_path}/\\1#' | {sort} > {args_file}".format(
|
|
find = posix.commands["find"],
|
|
sed = posix.commands["sed"],
|
|
sort = posix.commands["sort"],
|
|
src_path = sources_out.path,
|
|
args_file = zipper_args_file.path,
|
|
),
|
|
progress_message = "zipper_args_file %s" % zipper_args_file.path,
|
|
)
|
|
|
|
# Call zipper to create srcjar
|
|
zipper_args = ctx.actions.args()
|
|
zipper_args.add("c")
|
|
zipper_args.add(ctx.outputs.out.path)
|
|
zipper_args.add("@%s" % zipper_args_file.path)
|
|
ctx.actions.run(
|
|
executable = ctx.executable._zipper,
|
|
inputs = [sources_out, zipper_args_file],
|
|
outputs = [ctx.outputs.out],
|
|
arguments = [zipper_args],
|
|
progress_message = "srcjar %s" % ctx.outputs.out.short_path,
|
|
)
|
|
|
|
proto_gen = rule(
|
|
implementation = _proto_gen_impl,
|
|
attrs = {
|
|
"srcs": attr.label_list(providers = [ProtoInfo]),
|
|
"plugin_name": attr.string(),
|
|
"plugin_exec": attr.label(
|
|
cfg = "host",
|
|
executable = True,
|
|
),
|
|
"plugin_options": attr.string_list(),
|
|
"plugin_runfiles": attr.label_list(
|
|
default = [],
|
|
allow_files = True,
|
|
),
|
|
"protoc": attr.label(
|
|
default = Label("@com_google_protobuf//:protoc"),
|
|
cfg = "host",
|
|
allow_files = True,
|
|
executable = True,
|
|
),
|
|
"_zipper": attr.label(
|
|
default = Label("@bazel_tools//tools/zip:zipper"),
|
|
cfg = "host",
|
|
executable = True,
|
|
allow_files = True,
|
|
),
|
|
},
|
|
outputs = {
|
|
"out": "%{name}.srcjar",
|
|
},
|
|
output_to_genfiles = True,
|
|
toolchains = ["@rules_sh//sh/posix:toolchain_type"],
|
|
)
|
|
|
|
def _is_windows(ctx):
|
|
return ctx.configuration.host_path_separator == ";"
|
|
|
|
def _maven_tags(group, artifact_prefix, artifact_suffix):
|
|
if group and artifact_prefix:
|
|
artifact = artifact_prefix + "-" + artifact_suffix
|
|
return ["maven_coordinates=%s:%s:__VERSION__" % (group, artifact)]
|
|
else:
|
|
return []
|
|
|
|
def _proto_scala_srcs(name, grpc):
|
|
return [":%s" % name] + ([
|
|
"@com_github_googleapis_googleapis//google/rpc:code_proto",
|
|
"@com_github_googleapis_googleapis//google/rpc:status_proto",
|
|
"@com_github_grpc_grpc//src/proto/grpc/health/v1:health_proto_descriptor",
|
|
] if grpc else [])
|
|
|
|
def _proto_scala_deps(grpc, proto_deps):
|
|
return [
|
|
"@maven//:com_google_protobuf_protobuf_java",
|
|
"@maven//:com_thesamet_scalapb_lenses_{}".format(scala_major_version_suffix),
|
|
"@maven//:com_thesamet_scalapb_scalapb_runtime_{}".format(scala_major_version_suffix),
|
|
] + ([
|
|
"@maven//:com_thesamet_scalapb_scalapb_runtime_grpc_{}".format(scala_major_version_suffix),
|
|
"@maven//:io_grpc_grpc_api",
|
|
"@maven//:io_grpc_grpc_core",
|
|
"@maven//:io_grpc_grpc_protobuf",
|
|
"@maven//:io_grpc_grpc_stub",
|
|
] if grpc else []) + [
|
|
"%s_scala" % label
|
|
for label in proto_deps
|
|
]
|
|
|
|
def proto_jars(
|
|
name,
|
|
srcs,
|
|
visibility = None,
|
|
strip_import_prefix = "",
|
|
grpc = False,
|
|
deps = [],
|
|
proto_deps = [],
|
|
java_deps = [],
|
|
scala_deps = [],
|
|
javadoc_root_packages = [],
|
|
maven_group = None,
|
|
maven_artifact_prefix = None,
|
|
maven_artifact_proto_suffix = "proto",
|
|
maven_artifact_java_suffix = "java-proto",
|
|
maven_artifact_scala_suffix = "scala-proto"):
|
|
# NOTE (MK) An empty string flattens the whole structure which is
|
|
# rarely what you want, see https://github.com/bazelbuild/rules_pkg/issues/82
|
|
tar_strip_prefix = "." if not strip_import_prefix else strip_import_prefix
|
|
|
|
# Tarball containing the *.proto files.
|
|
pkg_tar(
|
|
name = "%s_tar" % name,
|
|
srcs = srcs,
|
|
extension = "tar.gz",
|
|
strip_prefix = tar_strip_prefix,
|
|
visibility = [":__subpackages__", "//release:__subpackages__"],
|
|
)
|
|
|
|
# JAR and source JAR containing the *.proto files.
|
|
da_java_library(
|
|
name = "%s_jar" % name,
|
|
srcs = None,
|
|
deps = None,
|
|
runtime_deps = ["%s_jar" % label for label in proto_deps],
|
|
resources = srcs,
|
|
resource_strip_prefix = "%s/%s/" % (native.package_name(), strip_import_prefix),
|
|
tags = _maven_tags(maven_group, maven_artifact_prefix, maven_artifact_proto_suffix),
|
|
visibility = visibility,
|
|
)
|
|
|
|
# An empty Javadoc JAR for uploading the source proto JAR to Maven Central.
|
|
pkg_empty_zip(
|
|
name = "%s_jar_javadoc" % name,
|
|
out = "%s_jar_javadoc.jar" % name,
|
|
)
|
|
|
|
# Compiled protobufs.
|
|
proto_library(
|
|
name = name,
|
|
srcs = srcs,
|
|
strip_import_prefix = strip_import_prefix,
|
|
visibility = visibility,
|
|
deps = deps + proto_deps,
|
|
)
|
|
|
|
# JAR and source JAR containing the generated Java bindings.
|
|
native.java_proto_library(
|
|
name = "%s_java" % name,
|
|
tags = _maven_tags(maven_group, maven_artifact_prefix, maven_artifact_java_suffix),
|
|
visibility = visibility,
|
|
deps = [":%s" % name],
|
|
)
|
|
|
|
if maven_group and maven_artifact_prefix:
|
|
pom_file(
|
|
name = "%s_java_pom" % name,
|
|
tags = _maven_tags(maven_group, maven_artifact_prefix, maven_artifact_java_suffix),
|
|
target = ":%s_java" % name,
|
|
visibility = visibility,
|
|
)
|
|
|
|
if javadoc_root_packages:
|
|
javadoc_library(
|
|
name = "%s_java_javadoc" % name,
|
|
srcs = [":%s_java" % name],
|
|
root_packages = javadoc_root_packages,
|
|
deps = ["@maven//:com_google_protobuf_protobuf_java"],
|
|
) if not is_windows else None
|
|
else:
|
|
# An empty Javadoc JAR for uploading the compiled proto JAR to Maven Central.
|
|
pkg_empty_zip(
|
|
name = "%s_java_javadoc" % name,
|
|
out = "%s_java_javadoc.jar" % name,
|
|
)
|
|
|
|
# JAR containing the generated Scala bindings.
|
|
proto_gen(
|
|
name = "%s_scala_sources" % name,
|
|
srcs = _proto_scala_srcs(name, grpc),
|
|
plugin_exec = "//scala-protoc-plugins/scalapb:protoc-gen-scalapb",
|
|
plugin_name = "scalapb",
|
|
plugin_options = ["grpc"] if grpc else [],
|
|
)
|
|
|
|
all_scala_deps = _proto_scala_deps(grpc, proto_deps)
|
|
|
|
scala_library(
|
|
name = "%s_scala" % name,
|
|
srcs = [":%s_scala_sources" % name],
|
|
tags = _maven_tags(maven_group, maven_artifact_prefix, maven_artifact_scala_suffix),
|
|
unused_dependency_checker_mode = "error",
|
|
visibility = visibility,
|
|
deps = all_scala_deps,
|
|
exports = all_scala_deps,
|
|
)
|
|
|
|
scala_source_jar(
|
|
name = "%s_scala_src" % name,
|
|
srcs = [":%s_scala_sources" % name],
|
|
)
|
|
|
|
scaladoc_jar(
|
|
name = "%s_scala_scaladoc" % name,
|
|
srcs = [":%s_scala_sources" % name],
|
|
tags = ["scaladoc"],
|
|
deps = [],
|
|
) if is_windows == False else None
|
|
|
|
if maven_group and maven_artifact_prefix:
|
|
pom_file(
|
|
name = "%s_scala_pom" % name,
|
|
target = ":%s_scala" % name,
|
|
visibility = visibility,
|
|
)
|