14
14
15
15
"""A module defining clippy rules"""
16
16
17
+ load ("@bazel_skylib//lib:structs.bzl" , "structs" )
17
18
load ("//rust/private:common.bzl" , "rust_common" )
18
- load ("//rust/private:providers.bzl" , "CaptureClippyOutputInfo" , "ClippyInfo" , "LintsInfo" )
19
+ load (
20
+ "//rust/private:providers.bzl" ,
21
+ "CaptureClippyOutputInfo" ,
22
+ "ClippyInfo" ,
23
+ "ClippyOutputDiagnosticsInfo" ,
24
+ "LintsInfo" ,
25
+ )
19
26
load (
20
27
"//rust/private:rustc.bzl" ,
21
28
"collect_deps" ,
@@ -146,6 +153,13 @@ def _clippy_aspect_impl(target, ctx):
146
153
"_clippy_error_format" if use_clippy_error_format else "_error_format" ,
147
154
)
148
155
156
+ clippy_diagnostics = None
157
+ if ctx .attr ._clippy_output_diagnostics [ClippyOutputDiagnosticsInfo ].output_diagnostics :
158
+ clippy_diagnostics = ctx .actions .declare_file (ctx .label .name + ".clippy.diagnostics" , sibling = crate_info .output )
159
+ crate_info_dict = structs .to_dict (crate_info )
160
+ crate_info_dict ["rustc_output" ] = clippy_diagnostics
161
+ crate_info = rust_common .create_crate_info (** crate_info_dict )
162
+
149
163
args , env = construct_arguments (
150
164
ctx = ctx ,
151
165
attr = ctx .rule .attr ,
@@ -165,6 +179,7 @@ def _clippy_aspect_impl(target, ctx):
165
179
build_flags_files = build_flags_files ,
166
180
emit = ["dep-info" , "metadata" ],
167
181
skip_expanding_rustc_env = True ,
182
+ use_json_output = bool (clippy_diagnostics ),
168
183
error_format = error_format ,
169
184
)
170
185
@@ -217,7 +232,7 @@ def _clippy_aspect_impl(target, ctx):
217
232
ctx .actions .run (
218
233
executable = ctx .executable ._process_wrapper ,
219
234
inputs = compile_inputs ,
220
- outputs = [clippy_out ],
235
+ outputs = [clippy_out ] + [ x for x in [ clippy_diagnostics ] if x ] ,
221
236
env = env ,
222
237
tools = [toolchain .clippy_driver ],
223
238
arguments = args .all ,
@@ -226,8 +241,12 @@ def _clippy_aspect_impl(target, ctx):
226
241
toolchain = "@rules_rust//rust:toolchain_type" ,
227
242
)
228
243
244
+ output_group_info = {"clippy_checks" : depset ([clippy_out ])}
245
+ if clippy_diagnostics :
246
+ output_group_info ["clippy_output" ] = depset ([clippy_diagnostics ])
247
+
229
248
return [
230
- OutputGroupInfo (clippy_checks = depset ([ clippy_out ]) ),
249
+ OutputGroupInfo (** output_group_info ),
231
250
ClippyInfo (output = depset ([clippy_out ])),
232
251
]
233
252
@@ -255,6 +274,10 @@ rust_clippy_aspect = aspect(
255
274
doc = "Arguments to pass to clippy" ,
256
275
default = Label ("//rust/settings:clippy_flags" ),
257
276
),
277
+ "_clippy_output_diagnostics" : attr .label (
278
+ doc = "Value of the `clippy_output_diagnostics` build setting" ,
279
+ default = "//rust/settings:clippy_output_diagnostics" ,
280
+ ),
258
281
"_config" : attr .label (
259
282
doc = "The `clippy.toml` file used for configuration" ,
260
283
allow_single_file = True ,
@@ -395,3 +418,25 @@ capture_clippy_output = rule(
395
418
implementation = _capture_clippy_output_impl ,
396
419
build_setting = config .bool (flag = True ),
397
420
)
421
+
422
+ def _clippy_output_diagnostics_impl (ctx ):
423
+ """Implementation of the `clippy_output_diagnostics` rule
424
+
425
+ Args:
426
+ ctx (ctx): The rule's context object
427
+
428
+ Returns:
429
+ list: A list containing the CaptureClippyOutputInfo provider
430
+ """
431
+ return [ClippyOutputDiagnosticsInfo (output_diagnostics = ctx .build_setting_value )]
432
+
433
+ clippy_output_diagnostics = rule (
434
+ doc = (
435
+ "Setting this flag from the command line with `--@rules_rust//rust/settings:clippy_output_diagnostics` " +
436
+ "makes rules_rust save lippy json output (suitable for consumption by rust-analyzer) in a file, " +
437
+ "available from the `clippy_output` output group. This is the clippy equivalent of " +
438
+ "`@rules_rust//settings:rustc_output_diagnostics`."
439
+ ),
440
+ implementation = _clippy_output_diagnostics_impl ,
441
+ build_setting = config .bool (flag = True ),
442
+ )
0 commit comments