fix(dev): preserve background build errors
This commit is contained in:
2 files changed
+37
-5
No files matched your search
@@ -4,7 +4,6 @@ import (
|
||||
"bufio"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
@@ -129,6 +128,27 @@ type pullEvent struct {
|
||||
err error
|
||||
}
|
||||
|
||||
type outputTail struct {
|
||||
data []byte
|
||||
}
|
||||
|
||||
func (tail *outputTail) Write(data []byte) (int, error) {
|
||||
const limit = 32 * 1024
|
||||
tail.data = append(tail.data, data...)
|
||||
if len(tail.data) > limit {
|
||||
tail.data = tail.data[len(tail.data)-limit:]
|
||||
}
|
||||
return len(data), nil
|
||||
}
|
||||
|
||||
func (tail *outputTail) lastLine() string {
|
||||
lines := strings.FieldsFunc(string(tail.data), func(char rune) bool { return char == '\n' || char == '\r' })
|
||||
if len(lines) == 0 {
|
||||
return ""
|
||||
}
|
||||
return strings.TrimSpace(lines[len(lines)-1])
|
||||
}
|
||||
|
||||
func splitDockerProgress(data []byte, atEOF bool) (advance int, token []byte, err error) {
|
||||
for i, b := range data {
|
||||
if b == '\n' || b == '\r' {
|
||||
@@ -174,7 +194,7 @@ func startPull(ctx context.Context, cmd *exec.Cmd, events chan<- pullEvent) tea.
|
||||
if err == nil {
|
||||
err = scanner.Err()
|
||||
} else {
|
||||
err = pullCommandError(err, lastLine)
|
||||
err = commandErrorWithDetail(err, lastLine)
|
||||
}
|
||||
events <- pullEvent{done: true, err: err}
|
||||
}()
|
||||
@@ -182,7 +202,7 @@ func startPull(ctx context.Context, cmd *exec.Cmd, events chan<- pullEvent) tea.
|
||||
}
|
||||
}
|
||||
|
||||
func pullCommandError(err error, lastLine string) error {
|
||||
func commandErrorWithDetail(err error, lastLine string) error {
|
||||
if lastLine == "" {
|
||||
return err
|
||||
}
|
||||
@@ -928,7 +948,11 @@ func (m prsModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
m.rebuildCancel = cancel
|
||||
m.status = status
|
||||
rebuild := func() tea.Msg {
|
||||
err := run.RebuildImageContext(ctx, image, io.Discard, io.Discard)
|
||||
output := &outputTail{}
|
||||
err := run.RebuildImageContext(ctx, image, output, output)
|
||||
if err != nil {
|
||||
err = commandErrorWithDetail(err, output.lastLine())
|
||||
}
|
||||
return rebuildDoneMsg{image: image, err: err, canceled: ctx.Err() != nil, action: action}
|
||||
}
|
||||
return m, tea.Batch(rebuild, m.spinner.Tick)
|
||||
|
||||
@@ -137,12 +137,20 @@ func TestPRImageCheckInProgressDoesNotLaunch(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPullErrorIncludesLastDockerMessage(t *testing.T) {
|
||||
err := pullCommandError(errors.New("exit status 1"), "manifest unknown")
|
||||
err := commandErrorWithDetail(errors.New("exit status 1"), "manifest unknown")
|
||||
if !strings.Contains(err.Error(), "manifest unknown") {
|
||||
t.Fatalf("pull error = %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOutputTailRetainsBuildFailure(t *testing.T) {
|
||||
tail := &outputTail{}
|
||||
_, _ = tail.Write([]byte("building\r\nERROR: Dockerfile not found\n"))
|
||||
if got := tail.lastLine(); got != "ERROR: Dockerfile not found" {
|
||||
t.Fatalf("last line = %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDevTableRendersLocalImageSource(t *testing.T) {
|
||||
m := newPRsModel()
|
||||
m.rows = []prRow{{
|
||||
|
||||
Reference in new issue
Block a user