github.com/nguyentm83/docker@v1.5.0/utils/streamformatter.go (about)

     1  package utils
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io"
     7  )
     8  
     9  type StreamFormatter struct {
    10  	json bool
    11  }
    12  
    13  func NewStreamFormatter(json bool) *StreamFormatter {
    14  	return &StreamFormatter{json}
    15  }
    16  
    17  const streamNewline = "\r\n"
    18  
    19  var streamNewlineBytes = []byte(streamNewline)
    20  
    21  func (sf *StreamFormatter) FormatStream(str string) []byte {
    22  	if sf.json {
    23  		b, err := json.Marshal(&JSONMessage{Stream: str})
    24  		if err != nil {
    25  			return sf.FormatError(err)
    26  		}
    27  		return append(b, streamNewlineBytes...)
    28  	}
    29  	return []byte(str + "\r")
    30  }
    31  
    32  func (sf *StreamFormatter) FormatStatus(id, format string, a ...interface{}) []byte {
    33  	str := fmt.Sprintf(format, a...)
    34  	if sf.json {
    35  		b, err := json.Marshal(&JSONMessage{ID: id, Status: str})
    36  		if err != nil {
    37  			return sf.FormatError(err)
    38  		}
    39  		return append(b, streamNewlineBytes...)
    40  	}
    41  	return []byte(str + streamNewline)
    42  }
    43  
    44  func (sf *StreamFormatter) FormatError(err error) []byte {
    45  	if sf.json {
    46  		jsonError, ok := err.(*JSONError)
    47  		if !ok {
    48  			jsonError = &JSONError{Message: err.Error()}
    49  		}
    50  		if b, err := json.Marshal(&JSONMessage{Error: jsonError, ErrorMessage: err.Error()}); err == nil {
    51  			return append(b, streamNewlineBytes...)
    52  		}
    53  		return []byte("{\"error\":\"format error\"}" + streamNewline)
    54  	}
    55  	return []byte("Error: " + err.Error() + streamNewline)
    56  }
    57  
    58  func (sf *StreamFormatter) FormatProgress(id, action string, progress *JSONProgress) []byte {
    59  	if progress == nil {
    60  		progress = &JSONProgress{}
    61  	}
    62  	if sf.json {
    63  
    64  		b, err := json.Marshal(&JSONMessage{
    65  			Status:          action,
    66  			ProgressMessage: progress.String(),
    67  			Progress:        progress,
    68  			ID:              id,
    69  		})
    70  		if err != nil {
    71  			return nil
    72  		}
    73  		return b
    74  	}
    75  	endl := "\r"
    76  	if progress.String() == "" {
    77  		endl += "\n"
    78  	}
    79  	return []byte(action + " " + progress.String() + endl)
    80  }
    81  
    82  func (sf *StreamFormatter) Json() bool {
    83  	return sf.json
    84  }
    85  
    86  type StdoutFormater struct {
    87  	io.Writer
    88  	*StreamFormatter
    89  }
    90  
    91  func (sf *StdoutFormater) Write(buf []byte) (int, error) {
    92  	formattedBuf := sf.StreamFormatter.FormatStream(string(buf))
    93  	n, err := sf.Writer.Write(formattedBuf)
    94  	if n != len(formattedBuf) {
    95  		return n, io.ErrShortWrite
    96  	}
    97  	return len(buf), err
    98  }
    99  
   100  type StderrFormater struct {
   101  	io.Writer
   102  	*StreamFormatter
   103  }
   104  
   105  func (sf *StderrFormater) Write(buf []byte) (int, error) {
   106  	formattedBuf := sf.StreamFormatter.FormatStream("\033[91m" + string(buf) + "\033[0m")
   107  	n, err := sf.Writer.Write(formattedBuf)
   108  	if n != len(formattedBuf) {
   109  		return n, io.ErrShortWrite
   110  	}
   111  	return len(buf), err
   112  }