Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #20806 from Veykril/veykril/push-syzoqmtxuqyt
feat: Log flycheck stdout and stderr to files
Lukas Wirth 7 months ago
parent f0b496c · parent 25c6fd7 · commit faa1184
-rw-r--r--crates/rust-analyzer/src/command.rs26
-rw-r--r--crates/rust-analyzer/src/discover.rs2
-rw-r--r--crates/rust-analyzer/src/flycheck.rs17
-rw-r--r--crates/rust-analyzer/src/test_runner.rs7
4 files changed, 46 insertions, 6 deletions
diff --git a/crates/rust-analyzer/src/command.rs b/crates/rust-analyzer/src/command.rs
index d6c80c399b..674e8623b2 100644
--- a/crates/rust-analyzer/src/command.rs
+++ b/crates/rust-analyzer/src/command.rs
@@ -3,13 +3,15 @@
use std::{
ffi::OsString,
- fmt, io,
+ fmt,
+ io::{self, BufWriter, Write},
marker::PhantomData,
path::PathBuf,
process::{ChildStderr, ChildStdout, Command, Stdio},
};
use crossbeam_channel::Sender;
+use paths::Utf8PathBuf;
use process_wrap::std::{StdChildWrapper, StdCommandWrap};
use stdx::process::streaming_output;
@@ -40,7 +42,7 @@ impl<T: Sized + Send + 'static> CargoActor<T> {
}
impl<T: Sized + Send + 'static> CargoActor<T> {
- fn run(self) -> io::Result<(bool, String)> {
+ fn run(self, outfile: Option<Utf8PathBuf>) -> io::Result<(bool, String)> {
// We manually read a line at a time, instead of using serde's
// stream deserializers, because the deserializer cannot recover
// from an error, resulting in it getting stuck, because we try to
@@ -50,6 +52,15 @@ impl<T: Sized + Send + 'static> CargoActor<T> {
// simply skip a line if it doesn't parse, which just ignores any
// erroneous output.
+ let mut stdout = outfile.as_ref().and_then(|path| {
+ _ = std::fs::create_dir_all(path);
+ Some(BufWriter::new(std::fs::File::create(path.join("stdout")).ok()?))
+ });
+ let mut stderr = outfile.as_ref().and_then(|path| {
+ _ = std::fs::create_dir_all(path);
+ Some(BufWriter::new(std::fs::File::create(path.join("stderr")).ok()?))
+ });
+
let mut stdout_errors = String::new();
let mut stderr_errors = String::new();
let mut read_at_least_one_stdout_message = false;
@@ -67,11 +78,19 @@ impl<T: Sized + Send + 'static> CargoActor<T> {
self.stdout,
self.stderr,
&mut |line| {
+ if let Some(stdout) = &mut stdout {
+ _ = stdout.write_all(line.as_bytes());
+ _ = stdout.write_all(b"\n");
+ }
if process_line(line, &mut stdout_errors) {
read_at_least_one_stdout_message = true;
}
},
&mut |line| {
+ if let Some(stderr) = &mut stderr {
+ _ = stderr.write_all(line.as_bytes());
+ _ = stderr.write_all(b"\n");
+ }
if process_line(line, &mut stderr_errors) {
read_at_least_one_stderr_message = true;
}
@@ -130,6 +149,7 @@ impl<T: Sized + Send + 'static> CommandHandle<T> {
mut command: Command,
parser: impl CargoParser<T>,
sender: Sender<T>,
+ out_file: Option<Utf8PathBuf>,
) -> std::io::Result<Self> {
command.stdout(Stdio::piped()).stderr(Stdio::piped()).stdin(Stdio::null());
@@ -150,7 +170,7 @@ impl<T: Sized + Send + 'static> CommandHandle<T> {
let actor = CargoActor::<T>::new(parser, sender, stdout, stderr);
let thread =
stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker, "CommandHandle")
- .spawn(move || actor.run())
+ .spawn(move || actor.run(out_file))
.expect("failed to spawn thread");
Ok(CommandHandle { program, arguments, current_dir, child, thread, _phantom: PhantomData })
}
diff --git a/crates/rust-analyzer/src/discover.rs b/crates/rust-analyzer/src/discover.rs
index 24c433610f..4ec0c075dd 100644
--- a/crates/rust-analyzer/src/discover.rs
+++ b/crates/rust-analyzer/src/discover.rs
@@ -67,7 +67,7 @@ impl DiscoverCommand {
cmd.args(args);
Ok(DiscoverHandle {
- _handle: CommandHandle::spawn(cmd, DiscoverProjectParser, self.sender.clone())?,
+ _handle: CommandHandle::spawn(cmd, DiscoverProjectParser, self.sender.clone(), None)?,
span: info_span!("discover_command").entered(),
})
}
diff --git a/crates/rust-analyzer/src/flycheck.rs b/crates/rust-analyzer/src/flycheck.rs
index cded34be14..b545106fe1 100644
--- a/crates/rust-analyzer/src/flycheck.rs
+++ b/crates/rust-analyzer/src/flycheck.rs
@@ -423,7 +423,21 @@ impl FlycheckActor {
tracing::debug!(?command, "will restart flycheck");
let (sender, receiver) = unbounded();
- match CommandHandle::spawn(command, CargoCheckParser, sender) {
+ match CommandHandle::spawn(
+ command,
+ CargoCheckParser,
+ sender,
+ match &self.config {
+ FlycheckConfig::CargoCommand { options, .. } => Some(
+ options
+ .target_dir
+ .as_deref()
+ .unwrap_or("target".as_ref())
+ .join(format!("rust-analyzer/flycheck{}", self.id)),
+ ),
+ _ => None,
+ },
+ ) {
Ok(command_handle) => {
tracing::debug!(command = formatted_command, "did restart flycheck");
self.command_handle = Some(command_handle);
@@ -622,6 +636,7 @@ impl FlycheckActor {
{
cmd.env("RUSTUP_TOOLCHAIN", AsRef::<std::path::Path>::as_ref(sysroot_root));
}
+ cmd.env("CARGO_LOG", "cargo::core::compiler::fingerprint=info");
cmd.arg(command);
match scope {
diff --git a/crates/rust-analyzer/src/test_runner.rs b/crates/rust-analyzer/src/test_runner.rs
index e7528dbc93..0c8658c75d 100644
--- a/crates/rust-analyzer/src/test_runner.rs
+++ b/crates/rust-analyzer/src/test_runner.rs
@@ -136,7 +136,12 @@ impl CargoTestHandle {
}
Ok(Self {
- _handle: CommandHandle::spawn(cmd, CargoTestOutputParser::new(&test_target), sender)?,
+ _handle: CommandHandle::spawn(
+ cmd,
+ CargoTestOutputParser::new(&test_target),
+ sender,
+ None,
+ )?,
})
}
}