github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/filteredwriter/filtered_writer.go (about)

     1  package filteredwriter
     2  
     3  import (
     4  	"io"
     5  	"sync"
     6  )
     7  
     8  type filteredWriter struct {
     9  	underlying io.Writer
    10  	filterFunc func(s string) bool
    11  	leftover   []byte
    12  	mu         sync.Mutex
    13  }
    14  
    15  func (fw *filteredWriter) Write(buf []byte) (int, error) {
    16  	fw.mu.Lock()
    17  	defer fw.mu.Unlock()
    18  	buf = append([]byte{}, append(fw.leftover, buf...)...)
    19  	start := 0
    20  	written := 0
    21  	for i, b := range buf {
    22  		if b == '\n' {
    23  			end := i
    24  			if buf[i-1] == '\r' {
    25  				end--
    26  			}
    27  			s := string(buf[start:end])
    28  
    29  			if !fw.filterFunc(s) {
    30  				n, err := fw.underlying.Write(buf[start : i+1])
    31  				written += n
    32  				if err != nil {
    33  					fw.leftover = append([]byte{}, buf[i+1:]...)
    34  					return len(buf), err
    35  				}
    36  			}
    37  
    38  			start = i + 1
    39  		}
    40  	}
    41  
    42  	fw.leftover = append([]byte{}, buf[start:]...)
    43  
    44  	return len(buf), nil
    45  }
    46  
    47  // lines matching `filterFunc` will not be output to the underlying writer
    48  func New(underlying io.Writer, filterFunc func(s string) bool) io.Writer {
    49  	return &filteredWriter{underlying: underlying, filterFunc: filterFunc}
    50  }