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