...

Source file src/github.com/onsi/ginkgo/v2/internal/writer.go

Documentation: github.com/onsi/ginkgo/v2/internal

     1  package internal
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io"
     7  	"sync"
     8  
     9  	"github.com/go-logr/logr"
    10  	"github.com/go-logr/logr/funcr"
    11  )
    12  
    13  type WriterMode uint
    14  
    15  const (
    16  	WriterModeStreamAndBuffer WriterMode = iota
    17  	WriterModeBufferOnly
    18  )
    19  
    20  type WriterInterface interface {
    21  	io.Writer
    22  
    23  	Truncate()
    24  	Bytes() []byte
    25  	Len() int
    26  }
    27  
    28  // Writer implements WriterInterface and GinkgoWriterInterface
    29  type Writer struct {
    30  	buffer    *bytes.Buffer
    31  	outWriter io.Writer
    32  	lock      *sync.Mutex
    33  	mode      WriterMode
    34  
    35  	streamIndent []byte
    36  	indentNext   bool
    37  
    38  	teeWriters []io.Writer
    39  }
    40  
    41  func NewWriter(outWriter io.Writer) *Writer {
    42  	return &Writer{
    43  		buffer:       &bytes.Buffer{},
    44  		lock:         &sync.Mutex{},
    45  		outWriter:    outWriter,
    46  		mode:         WriterModeStreamAndBuffer,
    47  		streamIndent: []byte("  "),
    48  		indentNext:   true,
    49  	}
    50  }
    51  
    52  func (w *Writer) SetMode(mode WriterMode) {
    53  	w.lock.Lock()
    54  	defer w.lock.Unlock()
    55  	w.mode = mode
    56  }
    57  
    58  func (w *Writer) Len() int {
    59  	w.lock.Lock()
    60  	defer w.lock.Unlock()
    61  	return w.buffer.Len()
    62  }
    63  
    64  var newline = []byte("\n")
    65  
    66  func (w *Writer) Write(b []byte) (n int, err error) {
    67  	w.lock.Lock()
    68  	defer w.lock.Unlock()
    69  
    70  	for _, teeWriter := range w.teeWriters {
    71  		teeWriter.Write(b)
    72  	}
    73  
    74  	if w.mode == WriterModeStreamAndBuffer {
    75  		line, remaining, found := []byte{}, b, false
    76  		for len(remaining) > 0 {
    77  			line, remaining, found = bytes.Cut(remaining, newline)
    78  			if len(line) > 0 {
    79  				if w.indentNext {
    80  					w.outWriter.Write(w.streamIndent)
    81  					w.indentNext = false
    82  				}
    83  				w.outWriter.Write(line)
    84  			}
    85  			if found {
    86  				w.outWriter.Write(newline)
    87  				w.indentNext = true
    88  			}
    89  		}
    90  	}
    91  	return w.buffer.Write(b)
    92  }
    93  
    94  func (w *Writer) Truncate() {
    95  	w.lock.Lock()
    96  	defer w.lock.Unlock()
    97  	w.buffer.Reset()
    98  }
    99  
   100  func (w *Writer) Bytes() []byte {
   101  	w.lock.Lock()
   102  	defer w.lock.Unlock()
   103  	b := w.buffer.Bytes()
   104  	copied := make([]byte, len(b))
   105  	copy(copied, b)
   106  	return copied
   107  }
   108  
   109  // GinkgoWriterInterface
   110  func (w *Writer) TeeTo(writer io.Writer) {
   111  	w.lock.Lock()
   112  	defer w.lock.Unlock()
   113  
   114  	w.teeWriters = append(w.teeWriters, writer)
   115  }
   116  
   117  func (w *Writer) ClearTeeWriters() {
   118  	w.lock.Lock()
   119  	defer w.lock.Unlock()
   120  
   121  	w.teeWriters = []io.Writer{}
   122  }
   123  
   124  func (w *Writer) Print(a ...interface{}) {
   125  	fmt.Fprint(w, a...)
   126  }
   127  
   128  func (w *Writer) Printf(format string, a ...interface{}) {
   129  	fmt.Fprintf(w, format, a...)
   130  }
   131  
   132  func (w *Writer) Println(a ...interface{}) {
   133  	fmt.Fprintln(w, a...)
   134  }
   135  
   136  func GinkgoLogrFunc(writer *Writer) logr.Logger {
   137  	return funcr.New(func(prefix, args string) {
   138  		if prefix == "" {
   139  			writer.Printf("%s\n", args)
   140  		} else {
   141  			writer.Printf("%s %s\n", prefix, args)
   142  		}
   143  	}, funcr.Options{})
   144  }
   145  

View as plain text