aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/build_defs/repo/jvm.bzl
diff options
context:
space:
mode:
Diffstat (limited to 'tools/build_defs/repo/jvm.bzl')
-rw-r--r--tools/build_defs/repo/jvm.bzl185
1 files changed, 185 insertions, 0 deletions
diff --git a/tools/build_defs/repo/jvm.bzl b/tools/build_defs/repo/jvm.bzl
new file mode 100644
index 0000000000..f0d80ffe3e
--- /dev/null
+++ b/tools/build_defs/repo/jvm.bzl
@@ -0,0 +1,185 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+'jvm_import_external' offers additional functionality above what maven_jar has to offer.
+In addition to downloading the jars, it allows to define this jar's dependencies.
+thus it enables the explicit definition of the entire transitive dependency graph.
+
+The rule achieves this by writing 'import' build rules in BUILD files next to the downloaded jars.
+The name of the underlying 'import' rule needs to be specified.
+An optional 'load' statement can also be provided, along with any other relevant custom attribute.
+These import rules must have the following attributes:
+- "jars"
+- "deps"
+- "runtime_deps"
+- "exports"
+
+the following macros are defined below that utilize jvm_import_external:
+
+- jvm_maven_import_external - offers a 'maven' like api for identifying jars using 'artifact' format
+- java_import_external - uses `java_import` as the underlying build rule
+"""
+
+_HEADER = "# DO NOT EDIT: generated by jvm_import_external()"
+_PASS_PROPS = (
+ "neverlink",
+ "testonly_",
+ "visibility",
+ "exports",
+ "runtime_deps",
+ "deps",
+ "tags",
+)
+
+def _jvm_import_external(repository_ctx):
+ """Implementation of `java_import_external` rule."""
+ if (repository_ctx.attr.generated_linkable_rule_name and
+ not repository_ctx.attr.neverlink):
+ fail("Only use generated_linkable_rule_name if neverlink is set")
+ name = repository_ctx.attr.generated_rule_name or repository_ctx.name
+ urls = repository_ctx.attr.jar_urls
+ sha = repository_ctx.attr.jar_sha256
+ path = repository_ctx.name + ".jar"
+ for url in urls:
+ if url.endswith(".jar"):
+ path = url[url.rindex("/") + 1:]
+ break
+ srcurls = repository_ctx.attr.srcjar_urls
+ srcsha = repository_ctx.attr.srcjar_sha256
+ srcpath = repository_ctx.name + "-src.jar" if srcurls else ""
+ for url in srcurls:
+ if url.endswith(".jar"):
+ srcpath = url[url.rindex("/") + 1:].replace("-sources.jar", "-src.jar")
+ break
+ lines = [_HEADER, ""]
+ if repository_ctx.attr.rule_load:
+ lines.append(repository_ctx.attr.rule_load)
+ lines.append("")
+ if repository_ctx.attr.default_visibility:
+ lines.append("package(default_visibility = %s)" % (
+ repository_ctx.attr.default_visibility))
+ lines.append("")
+ lines.append("licenses(%s)" % repr(repository_ctx.attr.licenses))
+ lines.append("")
+ lines.extend(_serialize_given_rule_import(
+ repository_ctx.attr.rule_name, name, path, srcpath, repository_ctx.attr, _PASS_PROPS, repository_ctx.attr.additional_rule_attrs))
+ if (repository_ctx.attr.neverlink and
+ repository_ctx.attr.generated_linkable_rule_name):
+ lines.extend(_serialize_given_rule_import(
+ repository_ctx.attr.rule_name,
+ repository_ctx.attr.generated_linkable_rule_name,
+ path,
+ srcpath,
+ repository_ctx.attr,
+ [p for p in _PASS_PROPS if p != "neverlink"],
+ repository_ctx.attr.additional_rule_attrs))
+ extra = repository_ctx.attr.extra_build_file_content
+ if extra:
+ lines.append(extra)
+ if not extra.endswith("\n"):
+ lines.append("")
+ repository_ctx.download(urls, path, sha)
+ if srcurls:
+ repository_ctx.download(srcurls, srcpath, srcsha)
+ repository_ctx.file("BUILD", "\n".join(lines))
+ repository_ctx.file("jar/BUILD", "\n".join([
+ _HEADER,
+ "",
+ "package(default_visibility = %r)" % (
+ repository_ctx.attr.visibility or
+ repository_ctx.attr.default_visibility),
+ "",
+ "alias(",
+ " name = \"jar\",",
+ " actual = \"@%s\"," % repository_ctx.name,
+ ")",
+ "",
+ ]))
+
+def _convert_to_url(artifact, server_urls):
+ parts = artifact.split(":")
+ group_id_part = parts[0].replace(".","/")
+ artifact_id = parts[1]
+ version = parts[2]
+ packaging = "jar"
+ classifier_part = ""
+ if len(parts) == 4:
+ packaging = parts[2]
+ version = parts[3]
+ elif len(parts) == 5:
+ packaging = parts[2]
+ classifier_part = "-"+parts[3]
+ version = parts[4]
+
+ final_name = artifact_id + "-" + version + classifier_part + "." + packaging
+ url_suffix = group_id_part+"/"+artifact_id + "/" + version + "/" + final_name
+ urls = []
+ for server_url in server_urls:
+ urls.append(_concat_with_needed_slash(server_url, url_suffix))
+ return urls
+
+def _concat_with_needed_slash(server_url, url_suffix):
+ if server_url.endswith("/"):
+ return server_url + url_suffix
+ else:
+ return server_url + "/" + url_suffix
+
+def _serialize_given_rule_import(rule_name, name, path, srcpath, attrs, props, additional_rule_attrs):
+ lines = [
+ "%s(" % rule_name,
+ " name = %s," % repr(name),
+ " jars = [%s]," % repr(path),
+ ]
+ if srcpath:
+ lines.append(" srcjar = %s," % repr(srcpath))
+ for prop in props:
+ value = getattr(attrs, prop, None)
+ if value:
+ if prop.endswith("_"):
+ prop = prop[:-1]
+ lines.append(" %s = %s," % (prop, repr(value)))
+ for attr_key in additional_rule_attrs:
+ lines.append(" %s = %s," % (attr_key, additional_rule_attrs[attr_key]))
+ lines.append(")")
+ lines.append("")
+ return lines
+
+jvm_import_external = repository_rule(
+ implementation=_jvm_import_external,
+ attrs={
+ "rule_name": attr.string(mandatory=True),
+ "licenses": attr.string_list(mandatory=True, allow_empty=False),
+ "jar_urls": attr.string_list(mandatory=True, allow_empty=False),
+ "jar_sha256": attr.string(),
+ "rule_load": attr.string(),
+ "additional_rule_attrs": attr.string_dict(),
+ "srcjar_urls": attr.string_list(),
+ "srcjar_sha256": attr.string(),
+ "deps": attr.string_list(),
+ "runtime_deps": attr.string_list(),
+ "testonly_": attr.bool(),
+ "exports": attr.string_list(),
+ "neverlink": attr.bool(),
+ "generated_rule_name": attr.string(),
+ "generated_linkable_rule_name": attr.string(),
+ "default_visibility": attr.string_list(default=["//visibility:public"]),
+ "extra_build_file_content": attr.string(),
+ })
+
+def jvm_maven_import_external(artifact, server_urls, **kwargs):
+ jvm_import_external(
+ jar_urls = _convert_to_url(artifact, server_urls),
+ **kwargs
+ ) \ No newline at end of file