Skip to content

Commit

Permalink
Merge pull request #163 from dnephin/reset-term-on-idle-timeout
Browse files Browse the repository at this point in the history
watch: properly reset terminal after idle timeout
  • Loading branch information
dnephin committed Nov 21, 2020
2 parents 3a094ca + 98ce04d commit 76b46f9
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 20 deletions.
45 changes: 38 additions & 7 deletions internal/filewatcher/term_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,22 @@ import (
"gotest.tools/gotestsum/log"
)

type redoHandler struct {
prevPath string
ch chan string
reset func()
}

func newRedoHandler() *redoHandler {
fd := int(os.Stdin.Fd())
reset, err := enableNonBlockingRead(fd)
if err != nil {
log.Warnf("failed to put terminal (fd %d) into raw mode: %v", fd, err)
return nil
}
return &redoHandler{ch: make(chan string), reset: reset}
}

func enableNonBlockingRead(fd int) (func(), error) {
term, err := unix.IoctlGetTermios(fd, tcGet)
if err != nil {
Expand All @@ -35,15 +51,10 @@ func enableNonBlockingRead(fd int) (func(), error) {
return reset, nil
}

func (r *redoHandler) run(ctx context.Context) {
fd := int(os.Stdin.Fd())
reset, err := enableNonBlockingRead(fd)
if err != nil {
log.Debugf("failed to put terminal (fd %d) into raw mode: %v", fd, err)
func (r *redoHandler) Run(ctx context.Context) {
if r == nil {
return
}
defer reset()

in := bufio.NewReader(os.Stdin)
for {
if ctx.Err() != nil {
Expand All @@ -65,3 +76,23 @@ func (r *redoHandler) run(ctx context.Context) {
}
}
}

func (r *redoHandler) Ch() <-chan string {
if r == nil {
return nil
}
return r.ch
}

func (r *redoHandler) Reset() {
if r != nil {
r.reset()
}
}

func (r *redoHandler) Save(path string) {
if r == nil {
return
}
r.prevPath = path
}
16 changes: 14 additions & 2 deletions internal/filewatcher/term_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@ package filewatcher

import "context"

func (r *redoHandler) run(_ context.Context) {
return
type redoHandler struct{}

func newRedoHandler() *redoHandler {
return nil
}

func (r *redoHandler) Run(_ context.Context) {}

func (r *redoHandler) Ch() <-chan string {
return nil
}

func (r *redoHandler) Reset() {}

func (r *redoHandler) Save(_ string) {}
21 changes: 10 additions & 11 deletions internal/filewatcher/watch.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,20 @@ func Watch(dirs []string, run func(pkg string) error) error {
}
}

timer := time.NewTimer(time.Hour)
timer := time.NewTimer(maxIdleTime)
defer timer.Stop()

redo := &redoHandler{ch: make(chan string)}
go redo.run(ctx)
redo := newRedoHandler()
defer redo.Reset()
go redo.Run(ctx)

h := &handler{last: time.Now(), fn: run}
for {
select {
case <-timer.C:
return fmt.Errorf("exceeded idle timeout while watching files")

case path := <-redo.ch:
case path := <-redo.Ch():
resetTimer(timer)
if err := h.runTests(path); err != nil {
return fmt.Errorf("failed to rerun tests for %v: %v", path, err)
Expand All @@ -61,19 +63,21 @@ func Watch(dirs []string, run func(pkg string) error) error {
if err := h.handleEvent(event); err != nil {
return fmt.Errorf("failed to run tests for %v: %v", event.Name, err)
}
redo.prevPath = event.Name
redo.Save(event.Name)

case err := <-watcher.Errors:
return fmt.Errorf("failed while watching files: %v", err)
}
}
}

const maxIdleTime = time.Hour

func resetTimer(timer *time.Timer) {
if !timer.Stop() {
<-timer.C
}
timer.Reset(time.Hour)
timer.Reset(maxIdleTime)
}

func findAllDirs(dirs []string, maxDepth int) []string {
Expand Down Expand Up @@ -215,8 +219,3 @@ func (h *handler) runTests(path string) error {
h.last = time.Now()
return nil
}

type redoHandler struct {
prevPath string
ch chan string
}

0 comments on commit 76b46f9

Please sign in to comment.