Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 28 additions & 5 deletions crates/bashkit/src/interpreter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1432,29 +1432,52 @@ impl Interpreter {

/// Execute an if statement
async fn execute_if(&mut self, if_cmd: &IfCommand) -> Result<ExecResult> {
// 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
Expand Down
24 changes: 24 additions & 0 deletions crates/bashkit/tests/spec_cases/bash/exit-status.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Loading