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
44 changes: 13 additions & 31 deletions cmd/roborev/tui/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package tui
import (
"errors"
"fmt"
"io"
"net/http"
"os"
"os/exec"
"strings"
Expand Down Expand Up @@ -244,9 +242,9 @@ func (m model) triggerFix(parentJobID int64, prompt, gitRef string) tea.Cmd {
// needWorktree if the branch is not checked out anywhere.
func (m model) applyFixPatch(jobID int64) tea.Cmd {
return func() tea.Msg {
patch, jobDetail, msg := m.fetchPatchAndJob(jobID)
if msg != nil {
return *msg
patch, jobDetail, err := m.loadPatchAndJob(jobID)
if err != nil {
return applyPatchResultMsg{jobID: jobID, err: err}
}

// Resolve the target directory: if the branch has its own worktree,
Expand All @@ -271,9 +269,9 @@ func (m model) applyFixPatch(jobID int64) tea.Cmd {
// patch there, commits, and removes the worktree. The commit persists on the branch.
func (m model) applyFixPatchInWorktree(jobID int64) tea.Cmd {
return func() tea.Msg {
patch, jobDetail, msg := m.fetchPatchAndJob(jobID)
if msg != nil {
return *msg
patch, jobDetail, err := m.loadPatchAndJob(jobID)
if err != nil {
return applyPatchResultMsg{jobID: jobID, err: err}
}

// Create a temporary worktree on the branch.
Expand Down Expand Up @@ -309,32 +307,16 @@ func (m model) applyFixPatchInWorktree(jobID int64) tea.Cmd {
}
}

// fetchPatchAndJob fetches the patch content and job details for a fix job.
// Returns nil msg on success; a non-nil msg should be returned to the TUI immediately.
func (m model) fetchPatchAndJob(jobID int64) (string, *storage.ReviewJob, *applyPatchResultMsg) {
url := m.endpoint.BaseURL() + fmt.Sprintf("/api/job/patch?job_id=%d", jobID)
resp, err := m.client.Get(url)
// loadPatchAndJob fetches the patch content and job details for a fix job.
func (m model) loadPatchAndJob(jobID int64) (string, *storage.ReviewJob, error) {
patch, err := m.loadPatch(jobID)
if err != nil {
return "", nil, &applyPatchResultMsg{jobID: jobID, err: err}
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
return "", nil, &applyPatchResultMsg{jobID: jobID, err: fmt.Errorf("no patch available")}
return "", nil, err
}

patchData, err := io.ReadAll(resp.Body)
jobDetail, err := m.loadJob(jobID)
if err != nil {
return "", nil, &applyPatchResultMsg{jobID: jobID, err: err}
}
patch := string(patchData)
if patch == "" {
return "", nil, &applyPatchResultMsg{jobID: jobID, err: fmt.Errorf("empty patch")}
}

jobDetail, jErr := m.fetchJobByID(jobID)
if jErr != nil {
return "", nil, &applyPatchResultMsg{jobID: jobID, err: jErr}
return "", nil, err
}

return patch, jobDetail, nil
Expand Down Expand Up @@ -476,7 +458,7 @@ func patchFiles(patch string) ([]string, error) {
func (m model) triggerRebase(staleJobID int64) tea.Cmd {
return func() tea.Msg {
// Find the parent job ID (the original review this fix was for)
staleJob, fetchErr := m.fetchJobByID(staleJobID)
staleJob, fetchErr := m.loadJob(staleJobID)
if fetchErr != nil {
return fixTriggerResultMsg{err: fmt.Errorf("stale job %d not found: %w", staleJobID, fetchErr)}
}
Expand Down
24 changes: 24 additions & 0 deletions cmd/roborev/tui/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,30 @@ func (m model) getJSON(path string, out any) error {
return nil
}

// getText performs a GET request and returns the raw response body as text.
// Returns errNotFound for 404 responses. Other errors include the server's message.
func (m model) getText(path string) (string, error) {
url := m.endpoint.BaseURL() + path
resp, err := m.client.Get(url)
if err != nil {
return "", err
}
defer resp.Body.Close()

if resp.StatusCode == http.StatusNotFound {
return "", fmt.Errorf("%w: %s", errNotFound, readErrorBody(resp.Body, resp.Status))
}
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("%s", readErrorBody(resp.Body, resp.Status))
}

data, err := io.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("read response: %w", err)
}
return string(data), nil
}

// postJSON performs a POST request with a JSON body and decodes the response into out.
// If out is nil, the response body is discarded.
// Returns errNotFound (wrapped with server message) for 404 responses.
Expand Down
Loading
Loading