Skip to content

Commit

Permalink
adds support for lines which are longer than the read buffer (fixes c…
Browse files Browse the repository at this point in the history
  • Loading branch information
phillipgziprecruiter committed Apr 22, 2022
1 parent 6083f9d commit ac11c9c
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 2 deletions.
19 changes: 17 additions & 2 deletions shell/shell.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,27 @@ func (e *Executor) Stop() error {
func logOutput(wg *sync.WaitGroup, fp io.ReadCloser, out func(string, ...interface{})) {
defer wg.Done()
r := bufio.NewReader(fp)

var partial = false
var fullLine = ""
for {
line, _, err := r.ReadLine()
line, isPrefix, err := r.ReadLine()
if err != nil {
return
}
out("%s", string(line))

if !isPrefix && !partial {
out("%s", string(line))
} else if !isPrefix && partial {
out("%s", fullLine+string(line))
fullLine = ""
partial = false
} else if isPrefix && !partial {
fullLine = string(line)
partial = true
} else if isPrefix && partial {
fullLine += string(line)
}
}
}

Expand Down
79 changes: 79 additions & 0 deletions shell/shell_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package shell

import (
"fmt"
"io/ioutil"
"os"
"runtime"
"strings"
"syscall"
"testing"
"time"

Expand Down Expand Up @@ -196,3 +198,80 @@ func TestCaseInsensitivePath(t *testing.T) {
},
)
}

func generateLongLines() *string {
var sb strings.Builder

// Each line should be at least twice as large as the buffer used in `logOutput` (4k)
for i := 0; i < 10000; i++ {
sb.WriteRune(rune('A' + (i % 26)))
}

var longLine = sb.String()
var lines = strings.Join([]string{longLine, longLine, longLine, longLine}, "\n")

return &lines
}

func writeTempFile(s *string, f *os.File) error {
defer f.Close()
_, err := f.WriteString(*s)
if err != nil {
return err
}
err = f.Sync()
return err
}

func TestVeryLongLine(t *testing.T) {
f, err := ioutil.TempFile("", "testVeryLongLines")
if err != nil {
panic(err)
}
defer syscall.Unlink(f.Name())

shellTesting = true
var longLines = generateLongLines()

err = writeTempFile(longLines, f)
if err != nil {
panic(err)
}

var shells []string
var command string
if runtime.GOOS == "windows" {
shells = []string{
"modd",
"powershell",
}
command = fmt.Sprintf("type %s", f.Name())
} else {
shells = []string{
"sh",
"bash",
"modd",
"powershell",
}
command = fmt.Sprintf("cat %s", f.Name())
}
for _, sh := range shells {

longLineTest := cmdTest{
name: "long-line-test",
cmd: command,
logHas: *longLines,
}

t.Run(
fmt.Sprintf("%s/%s", sh, longLineTest.name),
func(t *testing.T) {
if _, err := CheckShell(sh); err != nil {
t.Skipf("skipping - %s", err)
return
}
testCmd(t, sh, longLineTest)
},
)
}
}

0 comments on commit ac11c9c

Please sign in to comment.