-
Notifications
You must be signed in to change notification settings - Fork 281
/
Copy pathscala_import.bzl
173 lines (154 loc) · 5.7 KB
/
scala_import.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
load("@io_bazel_rules_scala//scala:jars_to_labels.bzl", "JarsToLabelsInfo")
#intellij part is tested manually, tread lightly when changing there
#if you change make sure to manually re-import an intellij project and see imports
#are resolved (not red) and clickable
def _scala_import_impl(ctx):
target_data = _code_jars_and_intellij_metadata_from(
ctx.attr.jars,
ctx.file.srcjar,
)
(
current_target_compile_jars,
intellij_metadata,
) = (target_data.code_jars, target_data.intellij_metadata)
current_jars = depset(current_target_compile_jars)
exports = _collect(ctx.attr.exports)
transitive_runtime_jars = _collect_runtime(ctx.attr.runtime_deps)
jars = _collect(ctx.attr.deps)
jars2labels = {}
_collect_labels(ctx.attr.deps, jars2labels)
_collect_labels(ctx.attr.exports, jars2labels) #untested
_add_labels_of_current_code_jars(
depset(transitive = [current_jars, exports.compile_jars]),
ctx.label,
jars2labels,
) #last to override the label of the export compile jars to the current target
return struct(
scala = struct(
outputs = struct(jars = intellij_metadata),
),
providers = [
_create_provider(
current_jars,
transitive_runtime_jars,
jars,
exports,
ctx.attr.neverlink,
ctx.file.srcjar,
intellij_metadata,
),
DefaultInfo(
files = current_jars,
),
JarsToLabelsInfo(jars_to_labels = jars2labels),
],
)
def _create_provider(
current_target_compile_jars,
transitive_runtime_jars,
jars,
exports,
neverlink,
source_jar,
intellij_metadata):
transitive_runtime_jars = [
transitive_runtime_jars,
jars.transitive_runtime_jars,
exports.transitive_runtime_jars,
]
if not neverlink:
transitive_runtime_jars.append(current_target_compile_jars)
source_jars = []
if source_jar:
source_jars.append(source_jar)
else:
for metadata in intellij_metadata:
source_jars.extend(metadata.source_jars)
return java_common.create_provider(
use_ijar = False,
compile_time_jars = depset(
transitive = [current_target_compile_jars, exports.compile_jars],
),
transitive_compile_time_jars = depset(transitive = [
jars.transitive_compile_jars,
current_target_compile_jars,
exports.transitive_compile_jars,
]),
transitive_runtime_jars = depset(transitive = transitive_runtime_jars),
source_jars = source_jars,
)
def _add_labels_of_current_code_jars(code_jars, label, jars2labels):
for jar in code_jars.to_list():
jars2labels[jar.path] = label
def _code_jars_and_intellij_metadata_from(jars, srcjar):
code_jars = []
intellij_metadata = []
for jar in jars:
current_jar_code_jars = _filter_out_non_code_jars(jar.files)
current_jar_source_jars = _source_jars(jar, srcjar)
code_jars += current_jar_code_jars
for current_class_jar in current_jar_code_jars: #intellij, untested
intellij_metadata.append(
struct(
ijar = None,
class_jar = current_class_jar,
source_jars = current_jar_source_jars,
),
)
return struct(code_jars = code_jars, intellij_metadata = intellij_metadata)
def _source_jars(jar, srcjar):
if srcjar:
return [srcjar]
else:
jar_source_jars = [
file
for file in jar.files.to_list()
if _is_source_jar(file)
]
return jar_source_jars
def _filter_out_non_code_jars(files):
return [file for file in files.to_list() if not _is_source_jar(file)]
def _is_source_jar(file):
return file.basename.endswith("-sources.jar")
# TODO: it seems this could be reworked to use java_common.merge
def _collect(deps):
transitive_compile_jars = []
runtime_jars = []
compile_jars = []
for dep_target in deps:
java_provider = dep_target[JavaInfo]
compile_jars.append(java_provider.compile_jars)
transitive_compile_jars.append(java_provider.transitive_compile_time_jars)
runtime_jars.append(java_provider.transitive_runtime_jars)
return struct(
transitive_runtime_jars = depset(transitive = runtime_jars),
transitive_compile_jars = depset(transitive = transitive_compile_jars),
compile_jars = depset(transitive = compile_jars),
)
def _collect_labels(deps, jars2labels):
for dep_target in deps:
if JarsToLabelsInfo in dep_target:
jars2labels.update(dep_target[JarsToLabelsInfo].jars_to_labels)
#scala_library doesn't add labels to the direct dependency itself
java_provider = dep_target[JavaInfo]
for jar in java_provider.compile_jars.to_list():
jars2labels[jar.path] = dep_target.label
def _collect_runtime(runtime_deps):
jar_deps = []
for dep_target in runtime_deps:
java_provider = dep_target[JavaInfo]
jar_deps.append(java_provider.transitive_runtime_jars)
return depset(transitive = jar_deps)
scala_import = rule(
implementation = _scala_import_impl,
attrs = {
"jars": attr.label_list(
allow_files = True,
), #current hidden assumption is that these point to full, not ijar'd jars
"deps": attr.label_list(),
"runtime_deps": attr.label_list(),
"exports": attr.label_list(),
"neverlink": attr.bool(),
"srcjar": attr.label(allow_single_file = True),
},
)