github.com/GoogleContainerTools/skaffold@v1.39.18/pkg/skaffold/output/output.go (about) 1 /* 2 Copyright 2021 The Skaffold Authors 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package output 18 19 import ( 20 "context" 21 "io" 22 "os" 23 "time" 24 25 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/constants" 26 eventV2 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/event/v2" 27 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/output/log" 28 ) 29 30 const timestampFormat = "2006-01-02 15:04:05" 31 32 type skaffoldWriter struct { 33 MainWriter io.Writer 34 EventWriter io.Writer 35 task constants.Phase 36 subtask string 37 38 timestamps bool 39 } 40 41 func (s skaffoldWriter) Write(p []byte) (int, error) { 42 written := 0 43 if s.timestamps { 44 t, err := s.MainWriter.Write([]byte(time.Now().Format(timestampFormat) + " ")) 45 if err != nil { 46 return t, err 47 } 48 49 written += t 50 } 51 52 n, err := s.MainWriter.Write(p) 53 if err != nil { 54 return n, err 55 } 56 if n != len(p) { 57 return n, io.ErrShortWrite 58 } 59 60 written += n 61 62 s.EventWriter.Write(p) 63 64 return written, nil 65 } 66 67 func GetWriter(ctx context.Context, out io.Writer, defaultColor int, forceColors bool, timestamps bool) io.Writer { 68 if _, isSW := out.(skaffoldWriter); isSW { 69 return out 70 } 71 72 return skaffoldWriter{ 73 MainWriter: SetupColors(ctx, out, defaultColor, forceColors), 74 EventWriter: eventV2.NewLogger(constants.DevLoop, "-1"), 75 timestamps: timestamps, 76 } 77 } 78 79 func IsStdout(out io.Writer) bool { 80 sw, isSW := out.(skaffoldWriter) 81 if isSW { 82 out = sw.MainWriter 83 } 84 cw, isCW := out.(colorableWriter) 85 if isCW { 86 out = cw.Writer 87 } 88 return out == os.Stdout 89 } 90 91 // GetUnderlyingWriter returns the underlying writer if out is a colorableWriter 92 func GetUnderlyingWriter(out io.Writer) io.Writer { 93 sw, isSW := out.(skaffoldWriter) 94 if isSW { 95 out = sw.MainWriter 96 } 97 cw, isCW := out.(colorableWriter) 98 if isCW { 99 out = cw.Writer 100 } 101 return out 102 } 103 104 // WithEventContext will return a new skaffoldWriter with the given parameters to be used for the event writer. 105 // If the passed io.Writer is not a skaffoldWriter, then it is simply returned. 106 func WithEventContext(ctx context.Context, out io.Writer, phase constants.Phase, subtaskID string) (io.Writer, context.Context) { 107 ctx = context.WithValue(ctx, log.ContextKey, log.EventContext{ 108 Task: phase, 109 Subtask: subtaskID, 110 }) 111 112 if sw, isSW := out.(skaffoldWriter); isSW { 113 return skaffoldWriter{ 114 MainWriter: sw.MainWriter, 115 EventWriter: eventV2.NewLogger(phase, subtaskID), 116 task: phase, 117 subtask: subtaskID, 118 timestamps: sw.timestamps, 119 }, ctx 120 } 121 122 return out, ctx 123 }