From 1322fc31acbf39a201603182ab565422a66c626f Mon Sep 17 00:00:00 2001 From: Breadway Date: Wed, 12 Aug 2026 09:23:37 +0800 Subject: [PATCH] bakery: fix confirm() test hang when stdin is a real tty MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit confirm() checked the actual process stdin's is_terminal() state, which is true when cargo test is run from an interactive shell rather than CI/piped input — the two confirm-dependent tests then blocked on a read_line nobody was there to answer. Force stdin_is_terminal() to false in test builds so the tests never touch real stdin at all. --- bakery/src/install.rs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/bakery/src/install.rs b/bakery/src/install.rs index ad49b3d..c046a00 100644 --- a/bakery/src/install.rs +++ b/bakery/src/install.rs @@ -1,5 +1,6 @@ use anyhow::{bail, Context, Result}; use std::collections::HashMap; +#[cfg(not(test))] use std::io::IsTerminal; use std::path::{Path, PathBuf}; use std::process::Command; @@ -23,6 +24,22 @@ fn ensure_safe_component(name: &str, what: &str) -> Result<()> { Ok(()) } +/// Whether stdin should be treated as an interactive terminal. Always +/// `false` in test builds regardless of the real process stdin — running +/// `cargo test` from an actual interactive shell (not CI, not piped) gives +/// the test binary a real tty, which previously made `confirm` block on a +/// `read_line` nobody was there to answer. +fn stdin_is_terminal() -> bool { + #[cfg(test)] + { + false + } + #[cfg(not(test))] + { + std::io::stdin().is_terminal() + } +} + /// Prompts `prompt [y/N] ` and returns the answer. `assume_yes` (the global /// `--yes` flag) skips the prompt entirely; otherwise, a non-tty stdin /// (CI, piped input) answers "no" rather than blocking on a read that will @@ -31,7 +48,7 @@ fn confirm(prompt: &str, assume_yes: bool) -> bool { if assume_yes { return true; } - if !std::io::stdin().is_terminal() { + if !stdin_is_terminal() { return false; } use std::io::Write;