From 15d9b0073ac37903e918835596a7ad0507b172e1 Mon Sep 17 00:00:00 2001 From: Wildan M Date: Wed, 12 Nov 2025 18:27:08 +0700 Subject: [PATCH 1/3] Fix loop when error with nonstop --- src/bin/repo.rs | 94 +++++++++++++++++++++++++------------------------ 1 file changed, 48 insertions(+), 46 deletions(-) diff --git a/src/bin/repo.rs b/src/bin/repo.rs index 9cbc417b8..ad90b1ba6 100644 --- a/src/bin/repo.rs +++ b/src/bin/repo.rs @@ -1012,29 +1012,30 @@ fn run_tui_cook( cooker_status_tx .send(StatusUpdate::FailCook(recipe.clone(), e.to_string())) .unwrap_or_default(); - if !cooker_config.cook.nonstop { - while cooker_prompting.load(Ordering::SeqCst) != 0 { - thread::sleep(Duration::from_millis(101)); // wait other prompt - } - cooker_prompting.swap(1, Ordering::SeqCst); - 'wait: loop { - match cooker_prompting.load(Ordering::SeqCst) { - 0 => break 'again, - 1 => thread::sleep(Duration::from_millis(101)), - 2 => { - cooker_prompting.swap(0, Ordering::SeqCst); - break 'wait; - } // retry - 3 => { - cooker_prompting.swap(0, Ordering::SeqCst); - break 'again; - } // skip - 4 => { - cooker_prompting.swap(0, Ordering::SeqCst); - break 'done; - } // done - _ => unreachable!(), - } + if cooker_config.cook.nonstop { + break; + } + while cooker_prompting.load(Ordering::SeqCst) != 0 { + thread::sleep(Duration::from_millis(101)); // wait other prompt + } + cooker_prompting.swap(1, Ordering::SeqCst); + 'wait: loop { + match cooker_prompting.load(Ordering::SeqCst) { + 0 => break 'again, + 1 => thread::sleep(Duration::from_millis(101)), + 2 => { + cooker_prompting.swap(0, Ordering::SeqCst); + break 'wait; + } // retry + 3 => { + cooker_prompting.swap(0, Ordering::SeqCst); + break 'again; + } // skip + 4 => { + cooker_prompting.swap(0, Ordering::SeqCst); + break 'done; + } // done + _ => unreachable!(), } } } @@ -1108,29 +1109,30 @@ fn run_tui_cook( fetcher_status_tx .send(StatusUpdate::FailFetch(recipe.clone(), e.to_string())) .unwrap_or_default(); - if !fetcher_config.cook.nonstop { - while fetcher_prompting.load(Ordering::SeqCst) != 0 { - thread::sleep(Duration::from_millis(101)); // wait other prompt - } - fetcher_prompting.swap(1, Ordering::SeqCst); - 'wait: loop { - match fetcher_prompting.load(Ordering::SeqCst) { - 0 => break 'again, - 1 => thread::sleep(Duration::from_millis(101)), - 2 => { - fetcher_prompting.swap(0, Ordering::SeqCst); - break 'wait; - } // retry - 3 => { - fetcher_prompting.swap(0, Ordering::SeqCst); - break 'again; - } // skip - 4 => { - fetcher_prompting.swap(0, Ordering::SeqCst); - break 'done; - } // done - _ => unreachable!(), - } + if fetcher_config.cook.nonstop { + break; + } + while fetcher_prompting.load(Ordering::SeqCst) != 0 { + thread::sleep(Duration::from_millis(101)); // wait other prompt + } + fetcher_prompting.swap(1, Ordering::SeqCst); + 'wait: loop { + match fetcher_prompting.load(Ordering::SeqCst) { + 0 => break 'again, + 1 => thread::sleep(Duration::from_millis(101)), + 2 => { + fetcher_prompting.swap(0, Ordering::SeqCst); + break 'wait; + } // retry + 3 => { + fetcher_prompting.swap(0, Ordering::SeqCst); + break 'again; + } // skip + 4 => { + fetcher_prompting.swap(0, Ordering::SeqCst); + break 'done; + } // done + _ => unreachable!(), } } } From daa063334da943ed0fedf66e2d253f77b901650c Mon Sep 17 00:00:00 2001 From: Wildan M Date: Wed, 12 Nov 2025 19:39:30 +0700 Subject: [PATCH 2/3] Handle kill on nonstop --- src/bin/repo.rs | 63 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 18 deletions(-) diff --git a/src/bin/repo.rs b/src/bin/repo.rs index ad90b1ba6..618502dc0 100644 --- a/src/bin/repo.rs +++ b/src/bin/repo.rs @@ -1013,6 +1013,9 @@ fn run_tui_cook( .send(StatusUpdate::FailCook(recipe.clone(), e.to_string())) .unwrap_or_default(); if cooker_config.cook.nonstop { + if cooker_prompting.load(Ordering::SeqCst) == 4 { + break 'done; + } break; } while cooker_prompting.load(Ordering::SeqCst) != 0 { @@ -1110,6 +1113,9 @@ fn run_tui_cook( .send(StatusUpdate::FailFetch(recipe.clone(), e.to_string())) .unwrap_or_default(); if fetcher_config.cook.nonstop { + if fetcher_prompting.load(Ordering::SeqCst) == 4 { + break 'done; + } break; } while fetcher_prompting.load(Ordering::SeqCst) != 0 { @@ -1363,8 +1369,11 @@ fn run_tui_cook( log_paragraph, chunks[if app.fetch_complete { 1 } else { 2 }], ); - if let Some(prompt) = &app.prompt { - draw_prompt(f, prompt); + if let Some(prompt) = &mut app.prompt { + if config.cook.nonstop && prompt.selected == PromptOption::Retry { + prompt.selected = PromptOption::Skip; + } + draw_prompt(f, prompt, config.cook.nonstop); } if enable_auto_scroll { app.auto_scroll = true; @@ -1384,8 +1393,9 @@ fn run_tui_cook( app.dump_logs_on_exit = Some((name.to_owned(), join_logs(log, line))); } running.store(false, Ordering::SeqCst); + } else { + app.prompt = None; } - app.prompt = None; } else { handle_main_event(&mut app, &event); } @@ -1408,6 +1418,10 @@ fn run_tui_cook( drop(mstdout); let _ = stdout().flush(); + if config.cook.nonstop && app.prompt.is_some_and(|f| f.selected == PromptOption::Exit) { + kill_everything(); + } + fetcher_handle.join().unwrap(); cooker_handle.join().unwrap(); @@ -1439,12 +1453,7 @@ fn handle_main_event(app: &mut TuiApp, event: &Event) { } Key::Char('c') => { // as compilers still running, we use this way to stop it - let pid = std::process::id(); - Command::new("bash") - .arg("-c") - .arg(KILL_ALL_PID.replace("$PID", &pid.to_string())) - .spawn() - .expect("unable to spawn kill"); + kill_everything(); } Key::Up => { app.auto_scroll = false; @@ -1515,6 +1524,15 @@ fn handle_main_event(app: &mut TuiApp, event: &Event) { } } +fn kill_everything() { + let pid = std::process::id(); + Command::new("bash") + .arg("-c") + .arg(KILL_ALL_PID.replace("$PID", &pid.to_string())) + .spawn() + .expect("unable to spawn kill"); +} + fn handle_prompt_input<'a>( event: &Event, app: &'a mut TuiApp, @@ -1540,8 +1558,12 @@ fn handle_prompt_input<'a>( None } -fn draw_prompt(f: &mut ratatui::Frame, prompt: &FailurePrompt) { - let title = format!(" FAILURE in {} ", prompt.recipe.name); +fn draw_prompt(f: &mut ratatui::Frame, prompt: &FailurePrompt, is_nonstop: bool) { + let title = format!( + " FAILURE in {} {}", + prompt.recipe.name, + if is_nonstop { "(skipped) " } else { "" } + ); let mut error_text = prompt.error.clone(); if error_text.len() > 200 { error_text = error_text[0..100].to_string() @@ -1568,16 +1590,21 @@ fn draw_prompt(f: &mut ratatui::Frame, prompt: &FailurePrompt) { Style::default() }; + let mut buttons = vec![ + Span::styled(" [Skip] ", skip_style), + Span::raw(" "), + Span::styled(" [Exit] ", exit_style), + ]; + + if !is_nonstop { + buttons.push(Span::raw(" ")); + buttons.push(Span::styled(" [Retry] ", retry_style)); + } + let text = vec![ Line::from(error_text).style(Style::default().fg(Color::Yellow)), Line::from(""), - Line::from(vec![ - Span::styled(" [Skip] ", skip_style), - Span::raw(" "), - Span::styled(" [Exit] ", exit_style), - Span::raw(" "), - Span::styled(" [Retry] ", retry_style), - ]), + Line::from(buttons), ]; let block = Block::default() From f5f2b4d0d475bd617a6027052cc758b5524d0d25 Mon Sep 17 00:00:00 2001 From: Wildan M Date: Fri, 14 Nov 2025 12:46:28 +0700 Subject: [PATCH 3/3] Make sure nonstop can quit --- src/bin/repo.rs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/bin/repo.rs b/src/bin/repo.rs index 618502dc0..5962122c0 100644 --- a/src/bin/repo.rs +++ b/src/bin/repo.rs @@ -1006,6 +1006,11 @@ fn run_tui_cook( cooker_status_tx .send(StatusUpdate::Cooked(recipe)) .unwrap_or_default(); + if cooker_config.cook.nonstop + && cooker_prompting.load(Ordering::SeqCst) == 4 + { + break 'done; + } break; } Err(e) => { @@ -1106,6 +1111,11 @@ fn run_tui_cook( // Cooker thread died break 'done; } + if fetcher_config.cook.nonstop + && fetcher_prompting.load(Ordering::SeqCst) == 4 + { + break 'done; + } break; } Err(e) => { @@ -1386,6 +1396,7 @@ fn run_tui_cook( if let Some((app, res)) = handle_prompt_input(&event, &mut app) { prompting.swap(res as u32, Ordering::SeqCst); if res == PromptOption::Exit { + // TODO: This can be a different log with what prompted on nonstop mode let (name, log, line) = app.get_active_log(); if let Some(name) = name && let Some(log) = log @@ -1393,9 +1404,8 @@ fn run_tui_cook( app.dump_logs_on_exit = Some((name.to_owned(), join_logs(log, line))); } running.store(false, Ordering::SeqCst); - } else { - app.prompt = None; } + app.prompt = None; } else { handle_main_event(&mut app, &event); } @@ -1418,7 +1428,7 @@ fn run_tui_cook( drop(mstdout); let _ = stdout().flush(); - if config.cook.nonstop && app.prompt.is_some_and(|f| f.selected == PromptOption::Exit) { + if config.cook.nonstop && app.dump_logs_on_exit.is_some() { kill_everything(); }