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
| -rw-r--r-- | crates/rust-analyzer/src/command.rs | 26 | ||||
| -rw-r--r-- | crates/rust-analyzer/src/discover.rs | 2 | ||||
| -rw-r--r-- | crates/rust-analyzer/src/flycheck.rs | 17 | ||||
| -rw-r--r-- | crates/rust-analyzer/src/test_runner.rs | 7 |
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, + )?, }) } } |