1# Copyright 2020 Google LLC 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15""" 16Generates a Javadoc jar path/to/target/<name>.jar. 17 18Arguments: 19 srcs: source files to process. This might contain .java files or gen_rule that 20 generates source jars. 21 deps: targets that contain references to other types referenced in Javadoc. This can be the 22 java_library/android_library target(s) for the same sources 23 root_packages: Java packages to include in generated Javadoc. Any subpackages not listed in 24 exclude_packages will be included as well 25 exclude_packages: Java packages to exclude from generated Javadoc 26 android_api_level: If Android APIs are used, the API level to compile against to generate 27 Javadoc 28 doctitle: title for Javadoc's index.html. See javadoc -doctitle 29 bottom_text: text passed to javadoc's `-bottom` flag 30 external_javadoc_links: a list of URLs that are passed to Javadoc's `-linkoffline` flag 31""" 32 33def _check_non_empty(value, name): 34 if not value: 35 fail("%s must be non-empty" % name) 36 37def _android_jar(android_api_level): 38 if android_api_level == -1: 39 return None 40 return Label("@androidsdk//:platforms/android-%s/android.jar" % android_api_level) 41 42def _javadoc_library(ctx): 43 _check_non_empty(ctx.attr.root_packages, "root_packages") 44 45 transitive_deps = [dep[JavaInfo].transitive_compile_time_jars for dep in ctx.attr.deps] 46 if ctx.attr._android_jar: 47 transitive_deps.append(ctx.attr._android_jar.files) 48 49 classpath = depset([], transitive = transitive_deps).to_list() 50 51 include_packages = ":".join(ctx.attr.root_packages) 52 javadoc_command = [ 53 "%s/bin/javadoc" % ctx.attr._jdk[java_common.JavaRuntimeInfo].java_home, 54 "-sourcepath srcs", 55 "-use", 56 "-subpackages", 57 include_packages, 58 "-encoding UTF8", 59 "-classpath", 60 ":".join([jar.path for jar in classpath]), 61 "-notimestamp", 62 "-d tmp", 63 "-Xdoclint:-missing", 64 "-quiet", 65 ] 66 67 if ctx.attr.doctitle: 68 javadoc_command.append('-doctitle "%s"' % ctx.attr.doctitle) 69 70 if ctx.attr.exclude_packages: 71 javadoc_command.append("-exclude %s" % ":".join(ctx.attr.exclude_packages)) 72 73 for link in ctx.attr.external_javadoc_links: 74 javadoc_command.append("-linkoffline {0} {0}".format(link)) 75 76 if ctx.attr.bottom_text: 77 javadoc_command.append("-bottom '%s'" % ctx.attr.bottom_text) 78 79 srcs = depset(transitive = [src.files for src in ctx.attr.srcs]).to_list() 80 prepare_srcs_command = "mkdir srcs && " 81 path_prefixes = [x.replace(".", "/") for x in ctx.attr.root_packages] 82 for path_prefix in path_prefixes: 83 prepare_srcs_command = "mkdir -p srcs/%s && " % (path_prefix) 84 85 for src in srcs: 86 if src.path.endswith(".jar"): 87 prepare_srcs_command += "unzip -qq -B %s -d srcs && " % src.path 88 elif src.path.endswith(".java"): 89 for path_prefix in path_prefixes: 90 if path_prefix in src.path: 91 prepare_srcs_command += "cp %s srcs/%s && " % (src.path, path_prefix) 92 93 jar_binary = "%s/bin/jar" % ctx.attr._jdk[java_common.JavaRuntimeInfo].java_home 94 jar_command = "%s cf %s -C tmp ." % (jar_binary, ctx.outputs.jar.path) 95 96 ctx.actions.run_shell( 97 inputs = srcs + classpath + ctx.files._jdk, 98 command = "%s %s && %s" % (prepare_srcs_command, " ".join(javadoc_command), jar_command), 99 outputs = [ctx.outputs.jar], 100 ) 101 102javadoc_library = rule( 103 attrs = { 104 "srcs": attr.label_list(allow_files = True), 105 "deps": attr.label_list(), 106 "doctitle": attr.string(default = ""), 107 "root_packages": attr.string_list(), 108 "exclude_packages": attr.string_list(), 109 "android_api_level": attr.int(default = -1), 110 "bottom_text": attr.string(default = ""), 111 "external_javadoc_links": attr.string_list(), 112 "_android_jar": attr.label( 113 default = _android_jar, 114 allow_single_file = True, 115 ), 116 "_jdk": attr.label( 117 default = Label("@bazel_tools//tools/jdk:current_java_runtime"), 118 allow_files = True, 119 providers = [java_common.JavaRuntimeInfo], 120 ), 121 }, 122 outputs = {"jar": "%{name}.jar"}, 123 implementation = _javadoc_library, 124) 125