diff --git a/crates/bashkit/src/interpreter/mod.rs b/crates/bashkit/src/interpreter/mod.rs index a4012044..b7fea3c2 100644 --- a/crates/bashkit/src/interpreter/mod.rs +++ b/crates/bashkit/src/interpreter/mod.rs @@ -1432,29 +1432,52 @@ impl Interpreter { /// Execute an if statement async fn execute_if(&mut self, if_cmd: &IfCommand) -> Result { + // Accumulate stdout/stderr from all condition evaluations + let mut cond_stdout = String::new(); + let mut cond_stderr = String::new(); + // Execute condition (no errexit checking - conditions are expected to fail) let condition_result = self.execute_condition_sequence(&if_cmd.condition).await?; + cond_stdout.push_str(&condition_result.stdout); + cond_stderr.push_str(&condition_result.stderr); if condition_result.exit_code == 0 { // Condition succeeded, execute then branch - return self.execute_command_sequence(&if_cmd.then_branch).await; + let mut result = self.execute_command_sequence(&if_cmd.then_branch).await?; + result.stdout = cond_stdout + &result.stdout; + result.stderr = cond_stderr + &result.stderr; + return Ok(result); } // Check elif branches for (elif_condition, elif_body) in &if_cmd.elif_branches { let elif_result = self.execute_condition_sequence(elif_condition).await?; + cond_stdout.push_str(&elif_result.stdout); + cond_stderr.push_str(&elif_result.stderr); + if elif_result.exit_code == 0 { - return self.execute_command_sequence(elif_body).await; + let mut result = self.execute_command_sequence(elif_body).await?; + result.stdout = cond_stdout + &result.stdout; + result.stderr = cond_stderr + &result.stderr; + return Ok(result); } } // Execute else branch if present if let Some(else_branch) = &if_cmd.else_branch { - return self.execute_command_sequence(else_branch).await; + let mut result = self.execute_command_sequence(else_branch).await?; + result.stdout = cond_stdout + &result.stdout; + result.stderr = cond_stderr + &result.stderr; + return Ok(result); } - // No branch executed, return success - Ok(ExecResult::ok(String::new())) + // No branch executed, return condition output with success exit code + Ok(ExecResult { + stdout: cond_stdout, + stderr: cond_stderr, + exit_code: 0, + ..Default::default() + }) } /// Execute a for loop diff --git a/crates/bashkit/tests/spec_cases/bash/exit-status.test.sh b/crates/bashkit/tests/spec_cases/bash/exit-status.test.sh index b2617e81..80578e3f 100644 --- a/crates/bashkit/tests/spec_cases/bash/exit-status.test.sh +++ b/crates/bashkit/tests/spec_cases/bash/exit-status.test.sh @@ -239,3 +239,27 @@ echo SHOULD_NOT_REACH ### expect in_func ### end + +### if_condition_stdout +# stdout from if condition is preserved +if echo "from_condition"; then echo "from_body"; fi +### expect +from_condition +from_body +### end + +### if_negated_condition_stdout +# stdout from negated if condition +if ! echo "negated"; then echo "no"; else echo "yes"; fi +### expect +negated +yes +### end + +### if_condition_pipeline_stdout +# stdout from pipeline in if condition +if echo "hello" | cat; then echo "ok"; fi +### expect +hello +ok +### end