Files
codex/prs/bolinfest/study/PR-1831-study.md
2025-09-02 15:17:45 -07:00

3.0 KiB
Raw Blame History

PR 1831 Review — PatchApplyEnd Handling: DOs and DON'Ts

DOs

  • Handle PatchApplyEnd: add a clear failure entry; ignore success.
match event {
    EventMsg::PatchApplyEnd(PatchApplyEndEvent { call_id, stdout, stderr, success }) => {
        if !success {
            self.add_to_history(HistoryCell::new_patch_failed_event(stdout, stderr));
        }
        // No history entry when success == true
    }
    _ => {}
}
  • Preserve context from PatchApplyBegin: keep changes by call_id for better failure UI.
// In struct:
patch_changes: std::collections::HashMap<u64, HashMap<PathBuf, FileChange>>,

// On begin:
EventMsg::PatchApplyBegin(PatchApplyBeginEvent { call_id, changes }) => {
    self.patch_changes.insert(call_id, changes.clone());
    self.add_to_history(HistoryCell::PendingPatch { view: TextBlock::from_changes(&changes) });
}

// On end (failure):
EventMsg::PatchApplyEnd(PatchApplyEndEvent { call_id, stdout, stderr, success }) => {
    if !success {
        let changes = self.patch_changes.remove(&call_id);
        self.add_to_history(HistoryCell::new_patch_failed_event_with_changes(call_id, stdout, stderr, changes));
    }
}
  • Omit empty stdout/stderr lines to reduce noise.
pub fn new_patch_failed_event(stdout: String, stderr: String) -> Self {
    let mut lines = vec!["patch failed".red().bold().into()];
    if !stdout.is_empty() { lines.push(stdout.into()); }
    if !stderr.is_empty() { lines.push(stderr.into()); }
    lines.push("".into());
    HistoryCell::PatchFailed { view: TextBlock::new(lines) }
}
  • Use Stylize helpers and basic into() spans for TUI text.
use ratatui::prelude::Stylize;
// Good:
let header: Line = "patch failed".red().bold().into();
let msg: Line = "apply failed on workspace".dim().into();
  • Inline variables with format! when constructing messages.
let msg = format!("patch failed (call {call_id})");
let line: Line = msg.red().bold().into();

DON'Ts

  • Dont leave protocol events unhandled (no “TODO” or silent drops).
// Bad: event silently ignored
// match event { _ => {} }
  • Dont render empty stdout/stderr placeholders.
// Bad: pushes empty lines that clutter UI
let lines = vec![
    "patch failed".red().bold().into(),
    stdout.into(), // may be ""
    stderr.into(), // may be ""
];
  • Dont discard begin/end linkage; use call_id to join events.
// Bad: throws away call_id, making it hard to correlate
EventMsg::PatchApplyEnd(PatchApplyEndEvent { call_id: _, .. }) => { /* ... */ }
  • Dont create success entries for PatchApplyEnd.
// Bad: success should be silent
if success {
    self.add_to_history(HistoryCell::new_info("patch applied")); // avoid
}
  • Dont hand-build styles via Span::styled when Stylize suffices.
// Bad
// Line::from(Span::styled("patch failed", Style::default().fg(Color::Red).add_modifier(Modifier::BOLD)));

// Good
let line: Line = "patch failed".red().bold().into();