Skip to content

Commit a626ad1

Browse files
committed
[Workspace CLI] better logs streaming for validate
1 parent 2aba460 commit a626ad1

File tree

1 file changed

+40
-38
lines changed

1 file changed

+40
-38
lines changed

components/gitpod-cli/cmd/validate.go

Lines changed: 40 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package cmd
66

77
import (
88
"bufio"
9+
"bytes"
910
"context"
1011
"encoding/json"
1112
"fmt"
@@ -16,6 +17,7 @@ import (
1617
"path/filepath"
1718
"strings"
1819
"time"
20+
"unicode/utf8"
1921

2022
"github.com/gitpod-io/gitpod/common-go/log"
2123
"github.com/gitpod-io/gitpod/gitpod-cli/pkg/supervisor"
@@ -565,58 +567,58 @@ func pipeTask(ctx context.Context, task *api.TaskStatus, supervisor *supervisor.
565567
}
566568

567569
func listenTerminal(ctx context.Context, task *api.TaskStatus, supervisor *supervisor.SupervisorClient, runLog *logrus.Entry) error {
568-
listen, err := supervisor.Terminal.Listen(ctx, &api.ListenTerminalRequest{
569-
Alias: task.Terminal,
570-
})
570+
listen, err := supervisor.Terminal.Listen(ctx, &api.ListenTerminalRequest{Alias: task.Terminal})
571571
if err != nil {
572572
return err
573573
}
574574

575-
pr, pw := io.Pipe()
576-
defer pr.Close()
577-
defer pw.Close()
575+
var buffer, line bytes.Buffer
578576

579-
scanner := bufio.NewScanner(pr)
580-
const maxTokenSize = 1 * 1024 * 1024 // 1 MB
581-
buf := make([]byte, maxTokenSize)
582-
scanner.Buffer(buf, maxTokenSize)
577+
flushLine := func() {
578+
if line.Len() > 0 {
579+
runLog.Infof("%s: %s", task.Presentation.Name, line.String())
580+
line.Reset()
581+
}
582+
}
583583

584-
go func() {
585-
defer pw.Close()
586-
for {
587-
resp, err := listen.Recv()
588-
if err != nil {
589-
_ = pw.CloseWithError(err)
590-
return
584+
for {
585+
resp, err := listen.Recv()
586+
if err != nil {
587+
if err == io.EOF {
588+
flushLine()
589+
return nil
591590
}
591+
return err
592+
}
592593

593-
title := resp.GetTitle()
594-
if title != "" {
595-
task.Presentation.Name = title
596-
}
594+
if title := resp.GetTitle(); title != "" {
595+
task.Presentation.Name = title
596+
}
597597

598-
exitCode := resp.GetExitCode()
599-
if exitCode != 0 {
600-
runLog.Infof("%s: exited with code %d", task.Presentation.Name, exitCode)
601-
}
598+
if exitCode := resp.GetExitCode(); exitCode != 0 {
599+
flushLine()
600+
runLog.Infof("%s: exited with code %d", task.Presentation.Name, exitCode)
601+
}
602602

603-
data := resp.GetData()
604-
if len(data) > 0 {
605-
_, err := pw.Write(data)
606-
if err != nil {
607-
_ = pw.CloseWithError(err)
608-
return
603+
if data := resp.GetData(); len(data) > 0 {
604+
buffer.Write(data)
605+
606+
for {
607+
r, size := utf8.DecodeRune(buffer.Bytes())
608+
if r == utf8.RuneError && size == 0 {
609+
break // incomplete character at the end
610+
}
611+
612+
char := buffer.Next(size)
613+
614+
if r == '\n' || r == '\r' {
615+
flushLine()
616+
} else {
617+
line.Write(char)
609618
}
610619
}
611620
}
612-
}()
613-
614-
for scanner.Scan() {
615-
line := scanner.Text()
616-
runLog.Infof("%s: %s", task.Presentation.Name, line)
617621
}
618-
619-
return scanner.Err()
620622
}
621623

622624
var validateOpts struct {

0 commit comments

Comments
 (0)