diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/build_defs/repo/java.bzl | 116 | ||||
-rw-r--r-- | tools/build_defs/repo/jvm.bzl | 185 |
2 files changed, 193 insertions, 108 deletions
diff --git a/tools/build_defs/repo/java.bzl b/tools/build_defs/repo/java.bzl index 559cc77a04..9803658204 100644 --- a/tools/build_defs/repo/java.bzl +++ b/tools/build_defs/repo/java.bzl @@ -169,111 +169,11 @@ will be loaded into a runtime environment where certain dependencies can be reasonably expected to already be provided. """ -_HEADER = "# DO NOT EDIT: generated by java_import_external()" - -_PASS_PROPS = ( - "neverlink", - "testonly_", - "visibility", - "exports", - "runtime_deps", - "deps", - "tags", -) - -def _java_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.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(_make_java_import( - name, path, srcpath, repository_ctx.attr, _PASS_PROPS)) - if (repository_ctx.attr.neverlink and - repository_ctx.attr.generated_linkable_rule_name): - lines.extend(_make_java_import( - repository_ctx.attr.generated_linkable_rule_name, - path, - srcpath, - repository_ctx.attr, - [p for p in _PASS_PROPS if p != "neverlink"])) - 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 _make_java_import(name, path, srcpath, attrs, props): - lines = [ - "java_import(", - " 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))) - lines.append(")") - lines.append("") - return lines - -java_import_external = repository_rule( - implementation=_java_import_external, - attrs={ - "licenses": attr.string_list(mandatory=True, allow_empty=False), - "jar_urls": attr.string_list(mandatory=True, allow_empty=False), - "jar_sha256": attr.string(mandatory=True), - "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(), - }) +load("@bazel_tools//tools/build_defs/repo:jvm.bzl", "jvm_import_external") + +def java_import_external(jar_sha256, **kwargs): + jvm_import_external( + rule_name = "java_import", + jar_sha256 = jar_sha256, + **kwargs + ) 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 |