github.com/dougm/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 }