github.com/bazelbuild/remote-apis-sdks@v0.0.0-20240425170053-8a36686a6350/go/pkg/outerr/outerr.go (about) 1 // Package outerr contains types to record/pass system out-err streams. 2 package outerr 3 4 import ( 5 "bytes" 6 "io" 7 "os" 8 9 log "github.com/golang/glog" 10 ) 11 12 // OutErr is a general consumer of stdout and stderr. 13 type OutErr interface { 14 WriteOut([]byte) 15 WriteErr([]byte) 16 } 17 18 // StreamOutErr passes the stdout and stderr to two provided writers. 19 type StreamOutErr struct { 20 OutWriter, ErrWriter io.Writer 21 } 22 23 // NewStreamOutErr creates an OutErr from two Writers. 24 func NewStreamOutErr(out, err io.Writer) *StreamOutErr { 25 return &StreamOutErr{out, err} 26 } 27 28 // SystemOutErr is a constant wrapping the standard stdout/stderr streams. 29 var SystemOutErr = NewStreamOutErr(os.Stdout, os.Stderr) 30 31 // WriteOut writes the given bytes to stdout. 32 func (s *StreamOutErr) WriteOut(buf []byte) { 33 if _, e := s.OutWriter.Write(buf); e != nil { 34 log.Errorf("Error writing to stdout stream: %v", e) 35 } 36 } 37 38 // WriteErr writes the given bytes to stderr. 39 func (s *StreamOutErr) WriteErr(buf []byte) { 40 if _, e := s.ErrWriter.Write(buf); e != nil { 41 log.Errorf("Error writing to stderr stream: %v", e) 42 } 43 } 44 45 // RecordingOutErr is an OutErr capable of recording and returning its contents. 46 type RecordingOutErr struct { 47 StreamOutErr 48 out, err bytes.Buffer 49 } 50 51 // NewRecordingOutErr initializes a new RecordingOutErr. 52 func NewRecordingOutErr() *RecordingOutErr { 53 res := &RecordingOutErr{} 54 res.StreamOutErr = *NewStreamOutErr(&res.out, &res.err) 55 return res 56 } 57 58 // Stdout returns the full recorded stdout contents. 59 func (s *RecordingOutErr) Stdout() []byte { 60 return s.out.Bytes() 61 } 62 63 // Stderr returns the full recorded stderr contents. 64 func (s *RecordingOutErr) Stderr() []byte { 65 return s.err.Bytes() 66 } 67 68 // outWriter is a Writer that writes to the out stream of an OutErr. 69 type outWriter struct { 70 OutErr 71 } 72 73 // NewOutWriter provides an io.Writer implementation for writing to the out 74 // stream of an OutErr. 75 func NewOutWriter(oe OutErr) io.Writer { 76 return &outWriter{OutErr: oe} 77 } 78 79 // Write writes to the out stream of the OutErr. This method always returns len(p), nil. 80 func (o *outWriter) Write(p []byte) (int, error) { 81 o.WriteOut(p) 82 return len(p), nil 83 } 84 85 // errWriter is a Writer that writes to the err stream of an OutErr. 86 type errWriter struct { 87 OutErr 88 } 89 90 // NewErrWriter provides an io.Writer implementation for writing to the err 91 // stream of an OutErr. 92 func NewErrWriter(oe OutErr) io.Writer { 93 return &errWriter{OutErr: oe} 94 } 95 96 // Write writes to the stderr stream of the OutErr. This method always returns len(p), nil. 97 func (e *errWriter) Write(p []byte) (int, error) { 98 e.WriteErr(p) 99 return len(p), nil 100 }