forked from SeleniumHQ/selenium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
module.bzl
238 lines (212 loc) · 8.26 KB
/
module.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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
_GatheredModuleInfo = provider(
fields = {
"name": "Name of the module, may be `None`.",
"module_path": "depset of jars that make up the module path so far.",
"jars": "Jars to include in the module.",
"source_jars": "Source jars to include in the module.",
"java_info": "A merged JavaInfo of all the entries in `jars`.",
},
)
JavaModuleInfo = provider(
fields = {
"name": "Name of the module.",
"module_path": "depset of jars to include on the module path",
},
)
# In order to construct the module path, we do this:
# * `JavaModuleInfo`: use the module path from that
# * maven coordinates: add the runtime output jars to the module path
# * otherwise: just accumulate jars
_ATTR_ASPECTS = [
"deps",
"exports",
"runtime_deps",
]
def _infer_name(tags):
names = [tag[len("maven_coordinates="):] for tag in tags if tag.startswith("maven_coordinates=")]
if len(names) == 0:
return None
if len(names) > 1:
fail("Only one set of maven coordinates may be specified")
exploded = names[0].split(":")
# We want the group id and artifact id. If the artifact id begins
# with the last segment of the group id, then remove it.
groups = exploded[0].split(".")
final = groups[-1] + "-"
if exploded[1].startswith(final):
return (exploded[0] + "." + exploded[1][len(final):]).replace("-", "_")
return (exploded[0] + "." + exploded[1]).replace("-", "_")
def _java_module_aspect_impl(target, ctx):
name = _infer_name(ctx.rule.attr.tags)
all_deps = []
[all_deps.extend(getattr(ctx.rule.attr, attr, [])) for attr in _ATTR_ASPECTS]
all_infos = [dep[_GatheredModuleInfo] for dep in all_deps]
nameless_infos = [info for info in all_infos if not info.name]
jars = depset(direct = target[JavaInfo].runtime_output_jars, transitive = [info.jars for info in nameless_infos])
source_jars = depset(direct = target[JavaInfo].source_jars, transitive = [info.source_jars for info in nameless_infos])
derived = "unknown"
if JavaModuleInfo in target:
derived = "from java module info"
module_path = target[JavaModuleInfo].module_path
jars = target[JavaInfo].runtime_output_jars
source_jars = target[JavaInfo].source_jars
java_info = target[JavaInfo]
elif name:
derived = "by name"
module_path = depset(direct = target[JavaInfo].runtime_output_jars, transitive = [info.module_path for info in all_infos])
java_info = java_common.merge([info.java_info for info in all_infos if info.name] + [target[JavaInfo]])
else:
derived = "by default"
module_path = depset(transitive = [info.module_path for info in all_infos])
java_info = java_common.merge([info.java_info for info in all_infos if info.name])
return [
_GatheredModuleInfo(
name = name,
module_path = module_path,
jars = jars,
source_jars = source_jars,
java_info = java_info,
),
]
_java_module_aspect = aspect(
_java_module_aspect_impl,
attr_aspects = _ATTR_ASPECTS,
required_aspect_providers = [
[JavaInfo],
],
provides = [
_GatheredModuleInfo,
],
host_fragments = [
"java",
],
)
def _java_module_impl(ctx):
name = _infer_name(ctx.attr.tags)
all_infos = [dep[_GatheredModuleInfo] for dep in ctx.attr.deps]
included_jars = depset(transitive = [info.jars for info in all_infos])
raw_merged_jar = ctx.actions.declare_file("%s-pre-module.jar" % ctx.attr.name)
args = ctx.actions.args()
args.add_all(["--output", raw_merged_jar])
args.add_all(["--normalize", "--exclude_build_data"])
args.add_all(included_jars, before_each = "--sources")
ctx.actions.run(
executable = ctx.executable._singlejar,
outputs = [raw_merged_jar],
inputs = included_jars,
arguments = [args],
)
# Now that we have a single jar, derive the module info.
all_jars = depset(transitive = [info.module_path for info in all_infos]).to_list()
module_path_jars = depset(transitive = [info.module_path for info in all_infos])
module_info_jar = ctx.actions.declare_file("%s-module-info.jar" % ctx.attr.name)
args = ctx.actions.args()
args.add_all(["--module-name", name])
args.add_all(["--in", raw_merged_jar])
args.add_all(["--output", module_info_jar])
args.add_all(ctx.attr.hides, before_each = "--hides")
args.add_all(ctx.attr.uses, before_each = "--uses")
args.add_all(module_path_jars, before_each = "--module-path")
ctx.actions.run(
executable = ctx.executable._module_generator,
outputs = [module_info_jar],
inputs = depset([raw_merged_jar], transitive = [info.module_path for info in all_infos]),
arguments = [args],
)
# Now merge the input jars and the module info into a single unit.
# Bazel's singlejar strips the manifest of all useful information,
# which is suboptimal, so we don't use that.
module_jar = ctx.actions.declare_file("lib%s.jar" % ctx.attr.name)
inputs = depset([module_info_jar], transitive = [info.jars for info in all_infos])
args = ctx.actions.args()
args.add_all(["--output", module_jar])
args.add_all(inputs.to_list(), before_each = "--sources")
ctx.actions.run(
executable = ctx.executable._merge_jars,
outputs = [module_jar],
inputs = inputs,
arguments = [args],
)
# Generate the ijar
compile_jar = java_common.run_ijar(
actions = ctx.actions,
jar = module_jar,
target_label = ctx.label,
java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],
)
# Create the merged source jar
src_jar = java_common.pack_sources(
actions = ctx.actions,
output_jar = module_jar,
source_jars = depset([module_info_jar], transitive = [info.source_jars for info in all_infos if not info.name]).to_list(),
java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],
host_javabase = ctx.attr._javabase[java_common.JavaRuntimeInfo],
)
# TODO: This JavaInfo needs to have the JavaInfos of all jars included in module stripped
java_info = JavaInfo(
output_jar = module_jar,
source_jar = src_jar,
compile_jar = compile_jar,
deps = [info.java_info for info in all_infos],
exports = [ex[JavaInfo] for ex in ctx.attr.exports],
runtime_deps = [dep[JavaInfo] for dep in ctx.attr.deps],
)
return [
DefaultInfo(files = depset([module_jar, src_jar])),
JavaModuleInfo(
name = name,
module_path = depset(direct = [module_jar], transitive = [info.module_path for info in all_infos]),
),
java_info,
]
java_module = rule(
_java_module_impl,
attrs = {
"deps": attr.label_list(
mandatory = True,
providers = [
[_GatheredModuleInfo],
],
aspects = [
_java_module_aspect,
],
),
"exports": attr.label_list(
providers = [
[JavaInfo],
],
),
"hides": attr.string_list(
doc = "List of package names to hide",
default = [],
),
"uses": attr.string_list(
doc = "List of classnames that the module uses",
default = [],
),
"_javabase": attr.label(
cfg = "host",
default = "@bazel_tools//tools/jdk:current_java_runtime",
providers = [java_common.JavaRuntimeInfo],
),
"_java_toolchain": attr.label(
default = "@bazel_tools//tools/jdk:current_java_toolchain",
),
"_merge_jars": attr.label(
default = "//java/buildtools/src/dev/selenium/tools/jar:MergeJars",
executable = True,
cfg = "host",
),
"_module_generator": attr.label(
default = "//java/buildtools/src/dev/selenium/tools/modules:ModuleGenerator",
executable = True,
cfg = "host",
),
"_singlejar": attr.label(
default = "@bazel_tools//tools/jdk:singlejar",
allow_files = True,
executable = True,
cfg = "host",
),
},
)