From 88dd58e947d712c8a8b776836a038813fb278d28 Mon Sep 17 00:00:00 2001 From: atlas Date: Fri, 16 Oct 2026 23:19:00 +0200 Subject: [PATCH] swarm-builder: keep a cut last line that is longer than the window After a cut, Tail::finish dropped everything through the first newline. When the stream ended in one line longer than the window, that newline was the last byte, so the window came back empty and the reply fell back to the bare exit status. The cut line is now dropped only when something follows it. --- swarm-builder/src/nix_build.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/swarm-builder/src/nix_build.rs b/swarm-builder/src/nix_build.rs index a0649e3b..6a5721cb 100644 --- a/swarm-builder/src/nix_build.rs +++ b/swarm-builder/src/nix_build.rs @@ -237,14 +237,15 @@ impl Tail { } /// The kept bytes. When the stream was longer than `keep`, the cut line - /// at the front is dropped, so the result starts on a line boundary - /// (unless it holds no newline at all). + /// at the front is dropped, so the result starts on a line boundary, + /// unless that line is all the window holds. fn finish(mut self) -> Vec { if self.buf.len() > self.keep { self.trim(); } if self.cut && let Some(nl) = self.buf.iter().position(|&b| b == b'\n') + && nl + 1 < self.buf.len() { self.buf.drain(..=nl); } @@ -566,6 +567,10 @@ mod tests { assert_eq!(String::from_utf8(cut).expect("utf-8"), "cccc\ndddd\n"); let one_long_line = read_tail(&b"x".repeat(50)[..], 12).await.expect("read"); assert_eq!(one_long_line, b"x".repeat(12)); + let long_last_line = read_tail(format!("{}\n", "x".repeat(50)).as_bytes(), 12) + .await + .expect("read"); + assert_eq!(long_last_line, format!("{}\n", "x".repeat(11)).as_bytes()); } #[test]