github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/hud/printer.go (about) 1 package hud 2 3 import ( 4 "io" 5 "time" 6 7 "github.com/tilt-dev/tilt/pkg/model/logstore" 8 ) 9 10 var backoffInit = 5 * time.Second 11 var backoffMultiplier = time.Duration(2) 12 13 type Stdout io.Writer 14 15 type IncrementalPrinter struct { 16 progress map[progressKey]progressStatus 17 stdout Stdout 18 } 19 20 func NewIncrementalPrinter(stdout Stdout) *IncrementalPrinter { 21 return &IncrementalPrinter{ 22 progress: make(map[progressKey]progressStatus), 23 stdout: stdout, 24 } 25 } 26 27 func (p *IncrementalPrinter) PrintNewline() { 28 _, _ = io.WriteString(p.stdout, "\n") 29 } 30 31 func (p *IncrementalPrinter) Print(lines []logstore.LogLine) { 32 for _, line := range lines { 33 // Naive progress implementation: skip lines that have already been printed 34 // recently. This works with any output stream. 35 // 36 // TODO(nick): Use ANSI codes to overwrite previous lines. It requires 37 // a little extra bookkeeping about where to find the progress line, 38 // and only works on terminals. 39 progressID := line.ProgressID 40 key := progressKey{spanID: line.SpanID, progressID: progressID} 41 if progressID != "" { 42 status, hasBeenPrinted := p.progress[key] 43 shouldPrint := line.ProgressMustPrint || 44 !hasBeenPrinted || 45 line.Time.Sub(status.lastPrinted) > status.printWait 46 if !shouldPrint { 47 continue 48 } 49 } 50 _, _ = io.WriteString(p.stdout, line.Text) 51 52 if progressID != "" { 53 status := p.progress[key] 54 newWait := backoffInit 55 if status.printWait > 0 { 56 newWait = backoffMultiplier * status.printWait 57 } 58 p.progress[key] = progressStatus{ 59 lastPrinted: line.Time, 60 printWait: newWait, 61 } 62 } 63 } 64 } 65 66 type progressKey struct { 67 spanID logstore.SpanID 68 progressID string 69 } 70 71 type progressStatus struct { 72 lastPrinted time.Time 73 printWait time.Duration 74 }