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