From 8fe3e239c8599d6a4ff500f282128343caecf3a4 Mon Sep 17 00:00:00 2001 From: marshmallow Date: Fri, 28 Aug 2026 12:09:43 +1000 Subject: [PATCH] truncate status bar to terminal cols --- CHANGELOG.md | 4 ++ Cargo.lock | 74 ++++++++++++++++----------------- crates/core/Cargo.toml | 2 +- crates/core/src/commands/mod.rs | 10 ++--- crates/core/src/status.rs | 27 ++++++++---- 5 files changed, 65 insertions(+), 52 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d72bcfc..4a75ccb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 to switch to a newer version of the wire binary that will support switching this value to a semver string. +### Fixed + +- Status bar overflowing the terminal's width. + ## [0.4.0] - 2025-07-20 In this release garnix has been replaced with our own binary cache as garnix has shutdown. diff --git a/Cargo.lock b/Cargo.lock index a4f546d..6ee2e50 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -68,7 +68,7 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -79,7 +79,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -322,7 +322,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 3.0.4", + "syn 3.0.3", ] [[package]] @@ -362,6 +362,18 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "console" +version = "0.16.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fe5f465a4f6fee88fad41b85d990f84c835335e85b5d9e6e63e0d06d28cba7c" +dependencies = [ + "encode_unicode", + "libc", + "unicode-width 0.2.2", + "windows-sys 0.61.2", +] + [[package]] name = "const-oid" version = "0.9.6" @@ -662,6 +674,12 @@ dependencies = [ "serde", ] +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + [[package]] name = "enum-display-derive" version = "0.1.1" @@ -698,7 +716,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -862,7 +880,7 @@ checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" dependencies = [ "proc-macro2", "quote", - "syn 3.0.4", + "syn 3.0.3", ] [[package]] @@ -1182,7 +1200,7 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -1487,7 +1505,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -1550,9 +1568,9 @@ checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "owo-colors" -version = "4.4.0" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c45bb4a6ae1280ec0803b1ef9d3455eb50f01efbbe1447ab020f1d54fba9d8" +checksum = "d211803b9b6b570f68772237e415a029d5a50c65d382910b879fb19d3271f94d" dependencies = [ "supports-color 2.1.0", "supports-color 3.0.2", @@ -1912,7 +1930,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -1960,7 +1978,7 @@ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn 3.0.4", + "syn 3.0.3", ] [[package]] @@ -2152,7 +2170,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -2362,15 +2380,6 @@ dependencies = [ "unicode-properties", ] -[[package]] -name = "strip-ansi-escapes" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a8f8038e7e7969abb3f1b7c2a811225e9296da208539e0f79c5251d6cac0025" -dependencies = [ - "vte", -] - [[package]] name = "strsim" version = "0.11.1" @@ -2438,9 +2447,9 @@ dependencies = [ [[package]] name = "syn" -version = "3.0.4" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6275cddf4610d1775e6d1fe9469b2e77d0f39fd98fb7450901b821e0c53649f" +checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" dependencies = [ "proc-macro2", "quote", @@ -2477,7 +2486,7 @@ dependencies = [ "fastrand", "once_cell", "rustix", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -2487,7 +2496,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "230a1b821ccbd75b185820a1f1ff7b14d21da1e442e22c0863ea5f08771a8874" dependencies = [ "rustix", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -2547,7 +2556,7 @@ checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" dependencies = [ "proc-macro2", "quote", - "syn 3.0.4", + "syn 3.0.3", ] [[package]] @@ -2842,15 +2851,6 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" -[[package]] -name = "vte" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "231fdcd7ef3037e8330d8e17e61011a2c244126acc0a982f4040ac3f9f0bc077" -dependencies = [ - "memchr", -] - [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" @@ -3079,6 +3079,7 @@ dependencies = [ "aho-corasick", "anyhow", "base64 0.23.1", + "console", "derive_more", "enum_dispatch", "futures", @@ -3099,8 +3100,7 @@ dependencies = [ "serde_json", "sha2 0.11.0", "sqlx", - "strip-ansi-escapes", - "syn 3.0.4", + "syn 3.0.3", "tempdir", "termion", "thiserror 2.0.20", diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index 896ea52..c4f71d6 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -34,7 +34,6 @@ enum_dispatch = "0.3.13" sha2 = { workspace = true } base64 = { workspace = true } nix-compat = { workspace = true } -strip-ansi-escapes = "0.2.1" aho-corasick = "1.1.4" owo-colors = { workspace = true } termion = "4.0.6" @@ -43,6 +42,7 @@ zstd = "0.13.3" wire-nix-client = { path = "../nix_client" } memchr = "2" semver = "1.0.28" +console = "0.16.4" [dev-dependencies] tempdir = "0.3" diff --git a/crates/core/src/commands/mod.rs b/crates/core/src/commands/mod.rs index 17d58e8..7953246 100644 --- a/crates/core/src/commands/mod.rs +++ b/crates/core/src/commands/mod.rs @@ -224,14 +224,14 @@ pub(crate) fn trace_nix_log_message( return None; } - let msg = strip_ansi_escapes::strip_str(msg); + let msg = console::strip_ansi_codes(&msg); if let Some(name) = name && let Some(sender) = UI_SENDER.get() { let _ = sender.send(UiMessage::ContextLogLine { name, - log: msg.clone(), + log: msg.to_string(), build_name: build_name.clone(), }); } @@ -239,7 +239,7 @@ pub(crate) fn trace_nix_log_message( let level = log_print(&level, build_name.as_ref(), &msg); if matches!(level, tracing::Level::ERROR | tracing::Level::WARN) { - return Some(msg); + return Some(msg.to_string()); } None @@ -257,7 +257,7 @@ impl ChildOutputMode { let (slice, name) = match self { Self::Generic => { let string = String::from_utf8_lossy(line); - let stripped = strip_ansi_escapes::strip_str(&string); + let stripped = console::strip_ansi_codes(&string); warn!("{stripped}"); return Some(string.to_string()); } @@ -289,7 +289,7 @@ impl ChildOutputMode { fn log_print( level: &VerbosityLevel, build_name: Option<&Arc>, - msg: &String, + msg: &Cow<'_, str>, ) -> tracing::Level { let level: tracing::Level = match level { VerbosityLevel::Info => tracing::Level::INFO, diff --git a/crates/core/src/status.rs b/crates/core/src/status.rs index 397a352..e1f6c78 100644 --- a/crates/core/src/status.rs +++ b/crates/core/src/status.rs @@ -78,6 +78,7 @@ pub struct Status { pub static UI_SENDER: OnceLock> = OnceLock::new(); const MAX_NODE_NAME_LENGTH: usize = 20; const FALLBACK_TERMINAL_ROWS: usize = 24; +const FALLBACK_TERMINAL_COLS: usize = 100; impl NodeStatus { // manually implemented Ord for NodeStatus, since we want to ignore the @@ -189,13 +190,9 @@ impl Status { ) } - #[must_use] - pub fn get_msg(&self) -> String { - if self.statuses.is_empty() { - return String::new(); - } - + fn get_header(&self) -> String { let count = self.count_statuses(); + let mut msg = format!("[{} / {}", count.finished, self.statuses.len()); let failed = if count.failed >= 1 { @@ -228,6 +225,19 @@ impl Status { let _ = write!(&mut msg, " {}s", self.began.elapsed().as_secs()); + msg + } + + #[must_use] + pub fn get_msg(&self) -> String { + if self.statuses.is_empty() { + return String::new(); + } + + let rows = terminal_size().map_or(FALLBACK_TERMINAL_ROWS, |(_, r)| r as usize); + let cols = terminal_size().map_or(FALLBACK_TERMINAL_COLS, |(c, _)| c as usize); + let mut msg = console::truncate_str(&self.get_header(), cols, "...").to_string(); + let mut entries: Vec<(String, &NodeStatus)> = self .statuses .iter() @@ -259,7 +269,6 @@ impl Status { // cap the displayed node lines to half the terminal height. // this keeps the status bar from overflowing. - let rows = terminal_size().map_or(FALLBACK_TERMINAL_ROWS, |(_, r)| r as usize); let cap = rows.saturating_sub(1).max(1) / 2; let mut shown = 0; @@ -268,13 +277,13 @@ impl Status { break; } - let _ = write!( - &mut msg, + let line = format!( "\n {}{} {}", truncated.if_supports_color(Stream::Stderr, |x| x.bold()), " ".repeat(max_name_len.saturating_sub(truncated.len())), status.render() ); + let _ = write!(&mut msg, "{}", console::truncate_str(&line, cols, "...")); shown += 1; } -- 2.51.2