-
-
Notifications
You must be signed in to change notification settings - Fork 289
Expand file tree
/
Copy pathtoolchains.bzl
More file actions
256 lines (222 loc) · 9.08 KB
/
toolchains.bzl
File metadata and controls
256 lines (222 loc) · 9.08 KB
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
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
"""Macros to instantiate and register @rules_scala_toolchains"""
load("@rules_scala_config//:config.bzl", "SCALA_VERSIONS")
load("//jmh/toolchain:toolchain.bzl", "jmh_artifact_ids")
load("//junit:junit.bzl", "junit_artifact_ids")
load("//scala:scala_cross_version.bzl", "default_maven_server_urls")
load("//scala:toolchains_repo.bzl", "scala_toolchains_repo")
load(
"//scala/private:macros/scala_repositories.bzl",
"scala_version_artifact_ids",
"setup_scala_compiler_sources",
)
load("//scala/private:toolchain_defaults.bzl", "TOOLCHAIN_DEFAULTS")
load("//scala/scalafmt:scalafmt_repositories.bzl", "scalafmt_artifact_ids")
load("//scala_proto/default:repositories.bzl", "scala_proto_artifact_ids")
load("//scalatest:scalatest.bzl", "scalatest_artifact_ids")
load("//specs2:specs2.bzl", "specs2_artifact_ids")
load("//specs2:specs2_junit.bzl", "specs2_junit_artifact_ids")
load("//third_party/repositories:repositories.bzl", "repositories")
load(
"//twitter_scrooge/toolchain:toolchain.bzl",
"twitter_scrooge_artifact_ids",
)
_DEFAULT_TOOLCHAINS_REPO_NAME = "rules_scala_toolchains"
def _toolchain_opts(tc_arg):
"""Converts a toolchain parameter to a (bool, dict of options).
Used by `scala_toolchains` to parse toolchain arguments as True, False,
None, or a dict of options.
Args:
tc_arg: a bool, dict, or None
Returns:
a bool indicating whether the toolchain is enabled, and a dict
containing any provided toolchain options
"""
if tc_arg == False or tc_arg == None:
return False, {}
return True, ({} if tc_arg == True else tc_arg)
def _process_toolchain_options(toolchain_defaults, **kwargs):
"""Checks the validity of toolchain options and provides defaults.
Updates each toolchain option dictionary with defaults for every missing
entry.
Args:
toolchain_defaults: a dict of `{toolchain_name: default options dict}`
**kwargs: keyword arguments of the form `toolchain_name = options_dict`
Returns:
a list of error messages for invalid toolchains or options
"""
errors = []
for tc, options in kwargs.items():
defaults = toolchain_defaults.get(tc, None)
if defaults == None:
errors.append("unknown toolchain or doesn't have defaults: " + tc)
continue
unexpected = [a for a in options if a not in defaults]
if unexpected:
plural = "s" if len(unexpected) != 1 else ""
errors.append(
"unexpected %s toolchain attribute%s: " % (tc, plural) +
", ".join(unexpected),
)
options.update({
k: v
for k, v in defaults.items()
if k not in options and v != None
})
return errors
def scala_toolchains(
name = _DEFAULT_TOOLCHAINS_REPO_NAME,
maven_servers = default_maven_server_urls(),
overridden_artifacts = {},
fetch_sources = False,
validate_scala_version = True,
scala_compiler_srcjars = {},
scala = True,
scalatest = False,
junit = False,
specs2 = False,
scalafmt = False,
scala_proto = False,
jmh = False,
twitter_scrooge = False):
"""Instantiates rules_scala toolchains and all their dependencies.
Provides a unified interface to configuring `rules_scala` both directly in a
`WORKSPACE` file and in a Bazel module extension.
Instantiates a repository containing all configured toolchains. Under
`WORKSPACE`, you will need to call `scala_register_toolchains()`. Under
Bzlmod, the `MODULE.bazel` file from `rules_scala` does this automatically.
All arguments are optional.
Args:
name: Name of the generated toolchains repository
maven_servers: Maven servers used to fetch dependency jar files
overridden_artifacts: artifacts overriding the defaults for the
configured Scala version, in the format:
```starlark
"repo_name": {
"artifact": "<maven coordinates>",
"sha256": "<checksum>",
"deps": [
"repository_labels_of_dependencies",
],
}
```
The default artifacts are defined by the
`third_party/repositories/scala_*.bzl` file matching the Scala
version.
fetch_sources: whether to download dependency source jars
validate_scala_version: Whether to check if the configured Scala
versions matches the default versions supported by rules_scala. Only
takes effect if `scala` is `True`.
scala_compiler_srcjars: optional dictionary of Scala version string to
compiler srcjar metadata dictionaries containing:
- exactly one "label", "url", or "urls" key
- optional "integrity" or "sha256" keys
scala: whether to instantiate default Scala toolchains for configured
Scala versions
scalatest: whether to instantiate the ScalaTest toolchain
junit: whether to instantiate the JUnit toolchain
specs2: whether to instantiate the Specs2 JUnit toolchain
scalafmt: boolean or dictionary of Scalafmt options:
- default_config: default Scalafmt config file target
scala_proto: boolean or dictionary of `setup_scala_proto_toolchain()`
options
jmh: whether to instantiate the Java Microbenchmarks Harness toolchain
twitter_scrooge: bool or dictionary of `setup_scrooge_toolchain()`
options
"""
scalafmt, scalafmt_options = _toolchain_opts(scalafmt)
scala_proto, scala_proto_options = _toolchain_opts(scala_proto)
twitter_scrooge, twitter_scrooge_options = _toolchain_opts(twitter_scrooge)
errors = _process_toolchain_options(
TOOLCHAIN_DEFAULTS,
scalafmt = scalafmt_options,
scala_proto = scala_proto_options,
twitter_scrooge = twitter_scrooge_options,
)
if errors:
fail("\n".join(errors))
setup_scala_compiler_sources(scala_compiler_srcjars)
if specs2:
junit = True
artifact_ids_to_fetch_sources = {}
if scalatest:
artifact_ids_to_fetch_sources.update({
id: True
for id in scalatest_artifact_ids()
})
if junit:
artifact_ids_to_fetch_sources.update({
id: True
for id in junit_artifact_ids()
})
if jmh:
artifact_ids_to_fetch_sources.update({
id: False
for id in jmh_artifact_ids()
})
if twitter_scrooge:
artifact_ids_to_fetch_sources.update({
id: False
for id in twitter_scrooge_artifact_ids(**twitter_scrooge_options)
})
for scala_version in SCALA_VERSIONS:
version_specific_artifact_ids = {}
if scala:
version_specific_artifact_ids.update({
id: fetch_sources
for id in scala_version_artifact_ids(scala_version)
})
if scala_proto:
version_specific_artifact_ids.update({
id: True
for id in scala_proto_artifact_ids(scala_version)
})
if scalafmt:
version_specific_artifact_ids.update({
id: fetch_sources
for id in scalafmt_artifact_ids(scala_version)
})
if specs2:
version_specific_artifact_ids.update({
id: True
for id in specs2_artifact_ids(scala_version) + specs2_junit_artifact_ids()
})
all_artifacts = (
artifact_ids_to_fetch_sources | version_specific_artifact_ids
)
repositories(
scala_version = scala_version,
for_artifact_ids = all_artifacts.keys(),
maven_servers = maven_servers,
fetch_sources = fetch_sources,
fetch_sources_by_id = all_artifacts,
# Note the internal macro parameter misspells "overriden".
overriden_artifacts = overridden_artifacts,
validate_scala_version = (scala and validate_scala_version),
)
scala_toolchains_repo(
name = name,
scalatest = scalatest,
junit = junit,
specs2 = specs2,
scalafmt = scalafmt,
scalafmt_default_config = scalafmt_options["default_config"],
scala_proto = scala_proto,
scala_proto_options = scala_proto_options["default_gen_opts"],
jmh = jmh,
twitter_scrooge = twitter_scrooge,
# When we _really_ drop Bazel 6 entirely, this attribute can become an
# attr.string_keyed_label_dict, and this conversion won't be necessary.
twitter_scrooge_deps = {
k: str(v)
for k, v in twitter_scrooge_options.items()
},
)
def scala_register_toolchains(name = _DEFAULT_TOOLCHAINS_REPO_NAME):
native.register_toolchains(
"@%s//...:all" % name,
"//protoc:all", # //protoc:scala_protoc_toolchain creates a cycle
)
def scala_register_unused_deps_toolchains():
native.register_toolchains(
"//scala:unused_dependency_checker_error_toolchain",
)