fix(cli): report multi-target failures and return nonzero
Consume structured per-target outcomes in the streaming CLI and TUI so mixed failures remain visible while successful targets still produce output. Return a failure status when every target fails, and keep interruption behavior distinct. Add strict-timeout integration coverage for mixed continuous completion and all-open-failure exit status, plus focused TUI outcome-state tests.
This commit is contained in:
5 files changed
+428
-18
No files matched your search
@@ -193,6 +193,7 @@ fn run_group_tui(
|
||||
}
|
||||
ManagedGroupEvent::TargetFinished(target) => {
|
||||
terminal_targets.insert(target.id.as_str().to_owned());
|
||||
state.process_target_outcome(&target);
|
||||
}
|
||||
}
|
||||
render_if_due(terminal, state, next_render, false)?;
|
||||
@@ -230,8 +231,18 @@ fn run_group_tui(
|
||||
|
||||
let outcome = session.join()?;
|
||||
while let Ok(Some(group_event)) = events.try_recv() {
|
||||
if let ManagedGroupEvent::Client(target_event) = group_event {
|
||||
state.process_target_event(&target_event);
|
||||
match group_event {
|
||||
ManagedGroupEvent::Client(target_event) => state.process_target_event(&target_event),
|
||||
ManagedGroupEvent::TargetFinished(target) => {
|
||||
if terminal_targets.insert(target.id.as_str().to_owned()) {
|
||||
state.process_target_outcome(&target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for target in &outcome.targets {
|
||||
if terminal_targets.insert(target.id.as_str().to_owned()) {
|
||||
state.process_target_outcome(target);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,6 +259,23 @@ fn run_group_tui(
|
||||
}
|
||||
};
|
||||
}
|
||||
let successful_targets = outcome
|
||||
.targets
|
||||
.iter()
|
||||
.filter(|target| target.is_success())
|
||||
.count();
|
||||
let failed_targets = outcome
|
||||
.targets
|
||||
.iter()
|
||||
.filter(|target| target.end_reason.failure().is_some())
|
||||
.count();
|
||||
if !interrupted && successful_targets == 0 && failed_targets > 0 {
|
||||
state.set_status(TuiStatus::Error);
|
||||
render_if_due(terminal, state, next_render, true)?;
|
||||
return Err(
|
||||
format!("no managed target completed successfully ({failed_targets} failed)").into(),
|
||||
);
|
||||
}
|
||||
|
||||
state.set_status(TuiStatus::Complete);
|
||||
render_if_due(terminal, state, next_render, true)?;
|
||||
|
||||
Reference in new issue
Block a user