• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
33load("@rules_java//java:defs.bzl", "JavaInfo", "java_common")
34
35def _check_non_empty(value, name):
36    if not value:
37        fail("%s must be non-empty" % name)
38
39def _android_jar(android_api_level):
40    if android_api_level == -1:
41        return None
42    return Label("@androidsdk//:platforms/android-%s/android.jar" % android_api_level)
43
44def _javadoc_library(ctx):
45    _check_non_empty(ctx.attr.root_packages, "root_packages")
46
47    transitive_deps = [dep[JavaInfo].transitive_compile_time_jars for dep in ctx.attr.deps]
48    if ctx.attr._android_jar:
49        transitive_deps.append(ctx.attr._android_jar.files)
50
51    classpath = depset([], transitive = transitive_deps).to_list()
52
53    include_packages = ":".join(ctx.attr.root_packages)
54    javadoc_command = [
55        "%s/bin/javadoc" % ctx.attr._jdk[java_common.JavaRuntimeInfo].java_home,
56        "-sourcepath srcs",
57        "-use",
58        "-subpackages",
59        include_packages,
60        "-encoding UTF8",
61        "-classpath",
62        ":".join([jar.path for jar in classpath]),
63        "-notimestamp",
64        "-d tmp",
65        "-Xdoclint:-missing",
66        "-quiet",
67    ]
68
69    if ctx.attr.doctitle:
70        javadoc_command.append('-doctitle "%s"' % ctx.attr.doctitle)
71
72    if ctx.attr.exclude_packages:
73        javadoc_command.append("-exclude %s" % ":".join(ctx.attr.exclude_packages))
74
75    for link in ctx.attr.external_javadoc_links:
76        javadoc_command.append("-linkoffline {0} {0}".format(link))
77
78    if ctx.attr.bottom_text:
79        javadoc_command.append("-bottom '%s'" % ctx.attr.bottom_text)
80
81    srcs = depset(transitive = [src.files for src in ctx.attr.srcs]).to_list()
82    prepare_srcs_command = "mkdir srcs && "
83    path_prefixes = [x.replace(".", "/") for x in ctx.attr.root_packages]
84    for path_prefix in path_prefixes:
85        prepare_srcs_command = "mkdir -p srcs/%s && " % (path_prefix)
86
87    for src in srcs:
88        if src.path.endswith(".jar"):
89            prepare_srcs_command += "unzip -qq -B %s -d srcs && " % src.path
90        elif src.path.endswith(".java"):
91            for path_prefix in path_prefixes:
92                if path_prefix in src.path:
93                    prepare_srcs_command += "cp %s srcs/%s && " % (src.path, path_prefix)
94
95    jar_binary = "%s/bin/jar" % ctx.attr._jdk[java_common.JavaRuntimeInfo].java_home
96    jar_command = "%s cf %s -C tmp ." % (jar_binary, ctx.outputs.jar.path)
97
98    ctx.actions.run_shell(
99        inputs = srcs + classpath + ctx.files._jdk,
100        command = "%s %s && %s" % (prepare_srcs_command, " ".join(javadoc_command), jar_command),
101        outputs = [ctx.outputs.jar],
102    )
103
104javadoc_library = rule(
105    attrs = {
106        "srcs": attr.label_list(allow_files = True),
107        "deps": attr.label_list(),
108        "doctitle": attr.string(default = ""),
109        "root_packages": attr.string_list(),
110        "exclude_packages": attr.string_list(),
111        "android_api_level": attr.int(default = -1),
112        "bottom_text": attr.string(default = ""),
113        "external_javadoc_links": attr.string_list(),
114        "_android_jar": attr.label(
115            default = _android_jar,
116            allow_single_file = True,
117        ),
118        "_jdk": attr.label(
119            default = Label("@bazel_tools//tools/jdk:current_java_runtime"),
120            allow_files = True,
121            providers = [java_common.JavaRuntimeInfo],
122        ),
123    },
124    outputs = {"jar": "%{name}.jar"},
125    implementation = _javadoc_library,
126)
127