• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (C) 2024 The Dagger Authors.
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"""See javadoc_library."""
16
17load("@rules_java//java:defs.bzl", "JavaInfo", "java_common")
18
19def _android_jar(android_api_level):
20    if android_api_level == -1:
21        return None
22    return Label("@androidsdk//:platforms/android-%s/android.jar" % android_api_level)
23
24def _javadoc_library(ctx):
25    transitive_deps = []
26    for dep in ctx.attr.deps:
27        if JavaInfo in dep:
28            transitive_deps.append(dep[JavaInfo].transitive_compile_time_jars)
29
30    if ctx.attr._android_jar:
31        transitive_deps.append(ctx.attr._android_jar.files)
32
33    classpath = depset([], transitive = transitive_deps).to_list()
34
35    java_home = str(ctx.attr._jdk[java_common.JavaRuntimeInfo].java_home)
36
37    output_dir = ctx.actions.declare_directory("%s_javadoc" % ctx.attr.name)
38
39    javadoc_arguments = ctx.actions.args()
40    javadoc_arguments.use_param_file("@%s", use_always = True)
41    javadoc_arguments.set_param_file_format("multiline")
42
43    javadoc_command = java_home + "/bin/javadoc"
44
45    javadoc_arguments.add("-use")
46    javadoc_arguments.add("-encoding", "UTF8")
47    javadoc_arguments.add_joined("-classpath", classpath, join_with = ":")
48    javadoc_arguments.add("-notimestamp")
49    javadoc_arguments.add("-d", output_dir.path)
50    javadoc_arguments.add("-Xdoclint:-missing")
51    javadoc_arguments.add("-quiet")
52
53    # Documentation for the javadoc command
54    # https://docs.oracle.com/javase/9/javadoc/javadoc-command.htm
55    if ctx.attr.root_packages:
56        # TODO(b/167433657): Reevaluate the utility of root_packages
57        # 1. Find the first directory under the working directory named '*java'.
58        # 2. Assume all files to document can be found by appending a root_package name
59        #    to that directory, or a subdirectory, replacing dots with slashes.
60        javadoc_command += ' -sourcepath $(find * -type d -name "*java" -print0 | tr "\\0" :) '
61        javadoc_arguments.add_all(ctx.attr.root_packages)
62        javadoc_arguments.add_joined("-subpackages", ctx.attr.root_packages, join_with = ":")
63    else:
64        # Document exactly the code in the specified source files.
65        javadoc_arguments.add_all(ctx.files.srcs)
66
67    if ctx.attr.doctitle:
68        javadoc_arguments.add("-doctitle", ctx.attr.doctitle, format = '"%s"')
69
70    if ctx.attr.groups:
71        groups = []
72        for k, v in ctx.attr.groups.items():
73            groups.append("-group \"%s\" \"%s\"" % (k, ":".join(v)))
74        javadoc_arguments.add_all(groups)
75
76    javadoc_arguments.add_joined("-exclude", ctx.attr.exclude_packages, join_with = ":")
77
78    javadoc_arguments.add_all(
79        ctx.attr.external_javadoc_links,
80        map_each = _format_linkoffline_value,
81    )
82
83    if ctx.attr.bottom_text:
84        javadoc_arguments.add("-bottom", ctx.attr.bottom_text, format = '"%s"')
85
86    # TODO(ronshapiro): Should we be using a different tool that doesn't include
87    # timestamp info?
88    jar_command = "%s/bin/jar cf %s -C %s ." % (java_home, ctx.outputs.jar.path, output_dir.path)
89
90    srcs = depset(transitive = [src.files for src in ctx.attr.srcs]).to_list()
91    ctx.actions.run_shell(
92        inputs = srcs + classpath + ctx.files._jdk,
93        command = "%s $@ && %s" % (javadoc_command, jar_command),
94        arguments = [javadoc_arguments],
95        outputs = [output_dir, ctx.outputs.jar],
96    )
97
98def _format_linkoffline_value(link):
99    return "-linkoffline {0} {0}".format(link)
100
101javadoc_library = rule(
102    attrs = {
103        "srcs": attr.label_list(
104            allow_empty = False,
105            allow_files = True,
106            doc = "Source files to generate Javadoc for.",
107        ),
108        "deps": attr.label_list(
109            doc = """
110Targets that contain references to other types referenced in Javadoc. These can
111be the java_library/android_library target(s) for the same sources.
112""",
113        ),
114        "doctitle": attr.string(
115            default = "",
116            doc = "Title for generated index.html. See javadoc -doctitle.",
117        ),
118       "groups": attr.string_list_dict(
119          doc = "Groups specified packages together in overview page. See javadoc -groups.",
120       ),
121        "root_packages": attr.string_list(
122            doc = """
123Java packages to include in generated Javadoc. Any subpackages not listed in
124exclude_packages will be included as well. If none are provided, each file in
125`srcs` is processed.
126""",
127        ),
128        "exclude_packages": attr.string_list(
129            doc = "Java packages to exclude from generated Javadoc.",
130        ),
131        "android_api_level": attr.int(
132            default = -1,
133            doc = """
134If Android APIs are used, the API level to compile against to generate Javadoc.
135""",
136        ),
137        "bottom_text": attr.string(
138            default = "",
139            doc = "Text passed to Javadoc's `-bottom` flag.",
140        ),
141        "external_javadoc_links": attr.string_list(
142            doc = "URLs passed to Javadoc's `-linkoffline` flag.",
143        ),
144        "_android_jar": attr.label(
145            default = _android_jar,
146            allow_single_file = True,
147        ),
148        "_jdk": attr.label(
149            default = Label("@bazel_tools//tools/jdk:current_java_runtime"),
150            providers = [java_common.JavaRuntimeInfo],
151        ),
152    },
153    outputs = {"jar": "%{name}.jar"},
154    doc = "Generates a Javadoc jar path/to/target/<name>.jar.",
155    implementation = _javadoc_library,
156)
157