Skip to content

Commit 72e3ba7

Browse files
leosvelperezFrozenPandaz
authored andcommitted
fix(core): do not auto-exit tui when there are multiple failed tasks (#31631)
## Current Behavior When the user hasn't interacted with the TUI and has not disabled the auto-exit functionality, it will always auto-exit regardless of the number of failed tasks. ## Expected Behavior When the user hasn't interacted with the TUI and has not disabled the auto-exit functionality, it should not auto-exit if there are multiple failed tasks. Additionally, as long as no terminal output panes are open (e.g., the run one command will always display the initiating task terminal pane), it should focus and open the first failed task. If all tasks succeed or there's only one failure, it should continue to auto-exit. (cherry picked from commit 6b2175b)
1 parent 550c7e3 commit 72e3ba7

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

packages/nx/src/native/tui/action.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,5 @@ pub enum Action {
3737
ToggleDebugMode,
3838
SendConsoleMessage(String),
3939
ConsoleMessengerAvailable(bool),
40+
EndCommand,
4041
}

packages/nx/src/native/tui/app.rs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,11 +229,32 @@ impl App {
229229
.as_ref()
230230
.and_then(|c| c.end_running_tasks());
231231

232-
// If the user has interacted with the app, or auto-exit is disabled, do nothing
232+
self.dispatch_action(Action::EndCommand);
233+
}
234+
235+
// Internal method to handle Action::EndCommand
236+
fn handle_end_command(&mut self) {
237+
// If the user has interacted with the app or auto-exit is disabled, do nothing
233238
if self.user_has_interacted || !self.tui_config.auto_exit.should_exit_automatically() {
234239
return;
235240
}
236241

242+
let failed_task_names = self.get_failed_task_names();
243+
// If there are more than 1 failed tasks, do not auto-exit
244+
if failed_task_names.len() > 1 {
245+
// If there are no visible panes (e.g. run one would have a pane open by default), focus the first failed task
246+
if !self.has_visible_panes() {
247+
self.selection_manager
248+
.lock()
249+
.unwrap()
250+
.select_task(failed_task_names.first().unwrap().clone());
251+
252+
// Display the task logs but keep focus on the task list to allow the user to navigate the failed tasks
253+
self.toggle_output_visibility();
254+
}
255+
return;
256+
}
257+
237258
if self.tasks.len() > 1 {
238259
self.begin_exit_countdown()
239260
} else {
@@ -1070,6 +1091,9 @@ impl App {
10701091
trace!("No console connection available");
10711092
}
10721093
}
1094+
Action::EndCommand => {
1095+
self.handle_end_command();
1096+
}
10731097
_ => {}
10741098
}
10751099

@@ -1138,6 +1162,22 @@ impl App {
11381162
self.pane_tasks.iter().any(|t| t.is_some())
11391163
}
11401164

1165+
/// Returns the names of tasks that have failed.
1166+
fn get_failed_task_names(&self) -> Vec<String> {
1167+
self.components
1168+
.iter()
1169+
.find_map(|c| c.as_any().downcast_ref::<TasksList>())
1170+
.map(|tasks_list| {
1171+
tasks_list
1172+
.tasks
1173+
.iter()
1174+
.filter(|task| task.status == TaskStatus::Failure)
1175+
.map(|task| task.name.clone())
1176+
.collect()
1177+
})
1178+
.unwrap_or_else(Vec::new)
1179+
}
1180+
11411181
/// Clears all output panes and resets their associated state.
11421182
fn clear_all_panes(&mut self) {
11431183
self.pane_tasks = [None, None];

0 commit comments

Comments
 (0)