Files
lispect/watcher.go
T

83 lines
1.4 KiB
Go

package main
import (
"io"
"os"
"strings"
"time"
"github.com/aymanbagabas/go-pty"
)
type Watcher struct {
ch <-chan string
lastline string
}
func NewWatcher(ptmx pty.Pty) *Watcher {
pipeline := make(chan string, 1024)
go io.Copy(ptmx, os.Stdin)
go func() {
for {
var buffer [1024]byte
n, err := ptmx.Read(buffer[:])
if err != nil {
close(pipeline)
return
}
// If the code below spends a lot of time,
// It hangs up to io.Copy(ptmx, os.Stdin)
// The reason is unknown.
os.Stdout.Write(buffer[:n])
pipeline <- string(buffer[:n])
}
}()
return &Watcher{ch: pipeline}
}
func (W *Watcher) updateLastLine() {
newLinePos := strings.LastIndexByte(W.lastline, '\n')
if newLinePos >= 0 {
W.lastline = W.lastline[newLinePos+1:]
}
}
func (W *Watcher) checkWords(token string, words []string) int {
W.lastline += token
for i, word := range words {
if strings.Contains(W.lastline, word) {
W.updateLastLine()
return i
}
}
W.updateLastLine()
return -1
}
func (W *Watcher) Expect(words ...string) int {
for token := range W.ch {
if found := W.checkWords(token, words); found >= 0 {
return found
}
}
return -1
}
func (W *Watcher) ExpectWithTimeout(d time.Duration, words ...string) int {
timer := time.NewTimer(d)
defer timer.Stop()
for {
select {
case token := <-W.ch:
if found := W.checkWords(token, words); found >= 0 {
return found
}
case <-timer.C:
return -1
}
}
}