From 395f5ce819f2b69a9cec81b39d0a1b81d258ee56 Mon Sep 17 00:00:00 2001 From: Chris Olszewski Date: Fri, 31 May 2024 11:40:32 -0700 Subject: [PATCH] fix(ui): ensure prelude gets printed before ui starts (#8265) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Description We had a race previously between switching to the alternative screen and the prelude being run. This PR moves the prelude printing to always happen before we switch to the alternative screen. We also now flush `stdout` to ensure all of the prelude has been written before switching to the alternative screen. ### Testing Instructions No longer have bleed in `Terminal.app` Screenshot 2024-05-31 at 10 52 23 AM --- crates/turborepo-lib/src/run/mod.rs | 7 ++++--- crates/turborepo-ui/src/tui/app.rs | 4 +++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/crates/turborepo-lib/src/run/mod.rs b/crates/turborepo-lib/src/run/mod.rs index 073dc728ea8e9..bb5937e66faf3 100644 --- a/crates/turborepo-lib/src/run/mod.rs +++ b/crates/turborepo-lib/src/run/mod.rs @@ -141,6 +141,10 @@ impl Run { } pub fn start_experimental_ui(&self) -> Option<(AppSender, JoinHandle>)> { + // Print prelude here as this needs to happen before the UI is started + if self.should_print_prelude { + self.print_run_prelude(); + } if !self.experimental_ui { return None; } @@ -153,9 +157,6 @@ impl Run { } pub async fn run(&mut self, experimental_ui_sender: Option) -> Result { - if self.should_print_prelude { - self.print_run_prelude(); - } if let Some(subscriber) = self.signal_handler.subscribe() { let run_cache = self.run_cache.clone(); tokio::spawn(async move { diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index d0ab438cda9cc..ce57ea9b078ee 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -1,5 +1,5 @@ use std::{ - io::{self, Stdout}, + io::{self, Stdout, Write}, time::{Duration, Instant}, }; @@ -160,6 +160,8 @@ fn poll(interact: bool, receiver: &AppReceiver, deadline: Instant) -> Option io::Result>> { crossterm::terminal::enable_raw_mode()?; let mut stdout = io::stdout(); + // Ensure all pending writes are flushed before we switch to alternative screen + stdout.flush()?; crossterm::execute!( stdout, crossterm::event::EnableMouseCapture,