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  }