From f09a717f2b954c23c94b30b21569355f56adedb0 Mon Sep 17 00:00:00 2001 From: nicholaslyang Date: Wed, 12 Jun 2024 11:42:42 -0400 Subject: [PATCH 1/3] Attempting to fix error by not opening UI on too small terminals --- crates/turborepo-lib/src/run/error.rs | 3 +++ crates/turborepo-lib/src/run/mod.rs | 10 ++++++++-- crates/turborepo-ui/src/tui/app.rs | 8 ++++++++ crates/turborepo-ui/src/tui/mod.rs | 2 +- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/crates/turborepo-lib/src/run/error.rs b/crates/turborepo-lib/src/run/error.rs index 006ecbe3768c2..59b3fa612ef03 100644 --- a/crates/turborepo-lib/src/run/error.rs +++ b/crates/turborepo-lib/src/run/error.rs @@ -1,6 +1,7 @@ use miette::Diagnostic; use thiserror::Error; use turborepo_repository::package_graph; +use turborepo_ui::tui; use super::graph_visualizer; use crate::{ @@ -51,4 +52,6 @@ pub enum Error { SignalHandler(std::io::Error), #[error(transparent)] Daemon(#[from] daemon::DaemonError), + #[error(transparent)] + Tui(#[from] tui::Error), } diff --git a/crates/turborepo-lib/src/run/mod.rs b/crates/turborepo-lib/src/run/mod.rs index 0d9a814dfa926..146c8d145511d 100644 --- a/crates/turborepo-lib/src/run/mod.rs +++ b/crates/turborepo-lib/src/run/mod.rs @@ -140,13 +140,19 @@ impl Run { self.experimental_ui } + pub fn should_start_ui(&self) -> Result { + Ok(self.experimental_ui + && self.opts.run_opts.dry_run.is_none() + && tui::terminal_big_enough()?) + } + 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(); } - // Don't start UI if doing a dry run - if !self.experimental_ui || self.opts.run_opts.dry_run.is_some() { + + if !self.should_start_ui().ok()? { return None; } diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index fb9aea70e84e2..2c249c9c10278 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -160,6 +160,14 @@ fn poll(input_options: InputOptions, receiver: &AppReceiver, deadline: Instant) } } +const MIN_HEIGHT: u16 = 10; +const MIN_WIDTH: u16 = 20; + +pub fn terminal_big_enough() -> Result { + let (width, height) = crossterm::terminal::size()?; + Ok(width >= MIN_WIDTH && height >= MIN_HEIGHT) +} + /// Configures terminal for rendering App fn startup() -> io::Result>> { crossterm::terminal::enable_raw_mode()?; diff --git a/crates/turborepo-ui/src/tui/mod.rs b/crates/turborepo-ui/src/tui/mod.rs index c412aaccc2521..35b0deea7ba06 100644 --- a/crates/turborepo-ui/src/tui/mod.rs +++ b/crates/turborepo-ui/src/tui/mod.rs @@ -7,7 +7,7 @@ mod spinner; mod table; mod task; -pub use app::run_app; +pub use app::{run_app, terminal_big_enough}; use event::{Event, TaskResult}; pub use handle::{AppReceiver, AppSender, TuiTask}; use input::{input, InputOptions}; From 56ed7323ff5f4270ed8262169cce92518205d790 Mon Sep 17 00:00:00 2001 From: nicholaslyang Date: Wed, 12 Jun 2024 13:17:11 -0400 Subject: [PATCH 2/3] Bumped crossterm version because it wasn't working with old version --- Cargo.lock | 2 +- crates/turborepo-ui/Cargo.toml | 2 +- crates/turborepo-ui/src/tui/app.rs | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2810131b81aa7..62ec13370aa99 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11463,7 +11463,7 @@ dependencies = [ "anyhow", "atty", "console", - "crossterm 0.26.1", + "crossterm 0.27.0", "dialoguer", "indicatif", "indoc", diff --git a/crates/turborepo-ui/Cargo.toml b/crates/turborepo-ui/Cargo.toml index 68b9aaaf9219d..ff27b2085dedd 100644 --- a/crates/turborepo-ui/Cargo.toml +++ b/crates/turborepo-ui/Cargo.toml @@ -17,7 +17,7 @@ workspace = true [dependencies] atty = { workspace = true } console = { workspace = true } -crossterm = "0.26.1" +crossterm = "0.27.0" dialoguer = { workspace = true } indicatif = { workspace = true } lazy_static = { workspace = true } diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index 2c249c9c10278..5cc9d9c3e280d 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -108,7 +108,6 @@ impl App { pub fn run_app(tasks: Vec, receiver: AppReceiver) -> Result<(), Error> { let mut terminal = startup()?; let size = terminal.size()?; - // Figure out pane width? let task_width_hint = TaskTable::width_hint(tasks.iter().map(|s| s.as_str())); // Want to maximize pane width From 8fb5b82fb8f5fbd62c9f047e7fc7f7aded3dd305 Mon Sep 17 00:00:00 2001 From: nicholaslyang Date: Wed, 12 Jun 2024 13:25:30 -0400 Subject: [PATCH 3/3] Some pre-emptive feedback --- crates/turborepo-lib/src/commands/run.rs | 2 +- crates/turborepo-lib/src/run/mod.rs | 11 +++++++---- crates/turborepo-lib/src/run/watch.rs | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/crates/turborepo-lib/src/commands/run.rs b/crates/turborepo-lib/src/commands/run.rs index 89e51d5964165..a15973a73114d 100644 --- a/crates/turborepo-lib/src/commands/run.rs +++ b/crates/turborepo-lib/src/commands/run.rs @@ -44,7 +44,7 @@ pub async fn run(base: CommandBase, telemetry: CommandEventBuilder) -> Result Option<(AppSender, JoinHandle>)> { + #[allow(clippy::type_complexity)] + pub fn start_experimental_ui( + &self, + ) -> Result>)>, Error> { // Print prelude here as this needs to happen before the UI is started if self.should_print_prelude { self.print_run_prelude(); } - if !self.should_start_ui().ok()? { - return None; + if !self.should_start_ui()? { + return Ok(None); } let task_names = self.engine.tasks_with_command(&self.pkg_dep_graph); let (sender, receiver) = AppSender::new(); let handle = tokio::task::spawn_blocking(move || tui::run_app(task_names, receiver)); - Some((sender, handle)) + Ok(Some((sender, handle))) } pub async fn run(&mut self, experimental_ui_sender: Option) -> Result { diff --git a/crates/turborepo-lib/src/run/watch.rs b/crates/turborepo-lib/src/run/watch.rs index bd78429141026..f622c0abf6bd1 100644 --- a/crates/turborepo-lib/src/run/watch.rs +++ b/crates/turborepo-lib/src/run/watch.rs @@ -118,7 +118,7 @@ impl WatchClient { let watched_packages = run.get_relevant_packages(); - let (sender, handle) = run.start_experimental_ui().unzip(); + let (sender, handle) = run.start_experimental_ui()?.unzip(); let connector = DaemonConnector { can_start_server: true,