Skip to content

Commit

Permalink
add extra clippy json output for rust analyzer
Browse files Browse the repository at this point in the history
  • Loading branch information
zapkub committed Mar 22, 2023
1 parent c1a9fd8 commit 6622d81
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 4 deletions.
12 changes: 11 additions & 1 deletion rust/private/clippy.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -126,19 +126,23 @@ def _clippy_aspect_impl(target, ctx):
build_env_files = build_env_files,
build_flags_files = build_flags_files,
emit = ["dep-info", "metadata"],
use_json_output = True,
)

if crate_info.is_test:
args.rustc_flags.add("--test")

clippy_flags = ctx.attr._clippy_flags[ClippyFlagsInfo].clippy_flags


# For remote execution purposes, the clippy_out file must be a sibling of crate_info.output
# or rustc may fail to create intermediate output files because the directory does not exist.
if ctx.attr._capture_output[CaptureClippyOutputInfo].capture_output:
clippy_out = ctx.actions.declare_file(ctx.label.name + ".clippy.out", sibling = crate_info.output)
args.process_wrapper_flags.add("--stderr-file", clippy_out.path)



if clippy_flags:
fail("""Combining @rules_rust//:clippy_flags with @rules_rust//:capture_clippy_output=true is currently not supported.
See https://github.com/bazelbuild/rules_rust/pull/1264#discussion_r853241339 for more detail.""")
Expand Down Expand Up @@ -170,10 +174,16 @@ See https://github.com/bazelbuild/rules_rust/pull/1264#discussion_r853241339 for
env["CLIPPY_CONF_DIR"] = "${{pwd}}/{}".format(ctx.file._config.dirname)
compile_inputs = depset([ctx.file._config], transitive = [compile_inputs])


clippy_json_out = ctx.actions.declare_file(ctx.label.name + ".clippy.json.out", sibling = crate_info.output)
args.process_wrapper_flags.add("--json-output", clippy_json_out.path)

outputs = [clippy_out, clippy_json_out]

ctx.actions.run(
executable = ctx.executable._process_wrapper,
inputs = compile_inputs,
outputs = [clippy_out],
outputs = outputs,
env = env,
tools = [toolchain.clippy_driver],
arguments = args.all,
Expand Down
2 changes: 2 additions & 0 deletions test/clippy/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
fn main() {
let x = 0;
let y = 0;
println!("Hello world");
}
18 changes: 16 additions & 2 deletions util/process_wrapper/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,20 @@ fn main() {
Box::new(io::stderr())
};

let mut json_output: Box<dyn io::Write> = if let Some(json_output_file) = opts.json_output {
Box::new(
OpenOptions::new()
.create(true)
.truncate(true)
.write(true)
.open(json_output_file)
.expect("process wrapper error: unable to open stderr file"),
)
} else {
Box::new(io::sink())
};


let mut child_stderr = child.stderr.take().unwrap();

let mut was_killed = false;
Expand All @@ -96,7 +110,7 @@ fn main() {
// that we emitted a metadata file.
let mut me = false;
let metadata_emitted = &mut me;
let result = process_output(&mut child_stderr, stderr.as_mut(), move |line| {
let result = process_output(&mut child_stderr, stderr.as_mut(), json_output.as_mut(), move |line| {
if quit_on_rmeta {
rustc::stop_on_rmeta_completion(line, format, metadata_emitted)
} else {
Expand All @@ -112,7 +126,7 @@ fn main() {
result
} else {
// Process output normally by forwarding stderr
process_output(&mut child_stderr, stderr.as_mut(), LineOutput::Message)
process_output(&mut child_stderr, stderr.as_mut(), json_output.as_mut(), LineOutput::Message)
};
result.expect("process wrapper error: failed to process stderr");

Expand Down
10 changes: 10 additions & 0 deletions util/process_wrapper/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ pub(crate) struct Options {
pub(crate) stdout_file: Option<String>,
// If set, redirects the child process stderr to this file.
pub(crate) stderr_file: Option<String>,

pub(crate) json_output: Option<String>,

// If set, it configures rustc to emit an rmeta file and then
// quit.
pub(crate) rustc_quit_on_rmeta: bool,
Expand All @@ -61,6 +64,7 @@ pub(crate) fn options() -> Result<Options, OptionError> {
let mut copy_output_raw = None;
let mut stdout_file = None;
let mut stderr_file = None;
let mut json_output = None;
let mut rustc_quit_on_rmeta_raw = None;
let mut rustc_output_format_raw = None;
let mut flags = Flags::new();
Expand Down Expand Up @@ -93,6 +97,11 @@ pub(crate) fn options() -> Result<Options, OptionError> {
"Redirect subprocess stderr in this file.",
&mut stderr_file,
);
flags.define_flag(
"--json-output",
"Redirect subprocess stderr in this file.",
&mut json_output,
);
flags.define_flag(
"--rustc-quit-on-rmeta",
"If enabled, this wrapper will terminate rustc after rmeta has been emitted.",
Expand Down Expand Up @@ -201,6 +210,7 @@ pub(crate) fn options() -> Result<Options, OptionError> {
copy_output,
stdout_file,
stderr_file,
json_output,
rustc_quit_on_rmeta,
rustc_output_format,
})
Expand Down
9 changes: 8 additions & 1 deletion util/process_wrapper/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,28 @@ pub(crate) enum LineOutput {
pub(crate) fn process_output<F>(
read_end: &mut dyn Read,
write_end: &mut dyn Write,
json_write_end: &mut dyn Write,
mut process_line: F,
) -> io::Result<()>
where
F: FnMut(String) -> LineOutput,
{
let mut reader = io::BufReader::new(read_end);
let mut writer = io::LineWriter::new(write_end);
let mut raw_writer = io::LineWriter::new(json_write_end);
loop {
let mut line = String::new();
let read_bytes = reader.read_line(&mut line)?;
if read_bytes == 0 {
break;
}

let raw_line = line.clone();
match process_line(line) {
LineOutput::Message(to_write) => writer.write_all(to_write.as_bytes())?,
LineOutput::Message(to_write) => {
writer.write_all(to_write.as_bytes())?;
raw_writer.write_all(raw_line.as_bytes())?;
},
LineOutput::Skip => {}
LineOutput::Terminate => return Ok(()),
};
Expand Down

0 comments on commit 6622d81

Please sign in to comment.