1// untested sections: 1 2 3package gexec 4 5import ( 6 "io" 7 "sync" 8) 9 10/* 11PrefixedWriter wraps an io.Writer, emitting the passed in prefix at the beginning of each new line. 12This can be useful when running multiple gexec.Sessions concurrently - you can prefix the log output of each 13session by passing in a PrefixedWriter: 14 15gexec.Start(cmd, NewPrefixedWriter("[my-cmd] ", GinkgoWriter), NewPrefixedWriter("[my-cmd] ", GinkgoWriter)) 16*/ 17type PrefixedWriter struct { 18 prefix []byte 19 writer io.Writer 20 lock *sync.Mutex 21 atStartOfLine bool 22} 23 24func NewPrefixedWriter(prefix string, writer io.Writer) *PrefixedWriter { 25 return &PrefixedWriter{ 26 prefix: []byte(prefix), 27 writer: writer, 28 lock: &sync.Mutex{}, 29 atStartOfLine: true, 30 } 31} 32 33func (w *PrefixedWriter) Write(b []byte) (int, error) { 34 w.lock.Lock() 35 defer w.lock.Unlock() 36 37 toWrite := []byte{} 38 39 for _, c := range b { 40 if w.atStartOfLine { 41 toWrite = append(toWrite, w.prefix...) 42 } 43 44 toWrite = append(toWrite, c) 45 46 w.atStartOfLine = c == '\n' 47 } 48 49 _, err := w.writer.Write(toWrite) 50 if err != nil { 51 return 0, err 52 } 53 54 return len(b), nil 55} 56