github.com/bazelbuild/bazel-watcher@v0.25.2/internal/ibazel/log/log.go (about) 1 package log 2 3 import ( 4 "fmt" 5 "io" 6 "os" 7 "strings" 8 "time" 9 ) 10 11 type color string 12 13 var osExit = os.Exit 14 var timeNow = time.Now 15 16 type writerLogger struct { 17 w io.Writer 18 } 19 20 func NewWriterLogger(w io.Writer) Logger { 21 return &writerLogger{w} 22 } 23 24 func (w *writerLogger) Log(a ...interface{}) { 25 fmt.Fprint(w.w, a...) 26 fmt.Fprint(w.w, "\n") 27 } 28 29 var logger Logger = &writerLogger{os.Stderr} 30 31 type Logger interface{ Log(...interface{}) } 32 33 const ( 34 resetColor color = "\033[0m" 35 bannerColor color = "\033[33m" 36 errorColor color = "\033[31m" 37 fatalColor color = "\033[41m" 38 logColor color = "\033[96m" 39 ) 40 41 func log(c color, msg string, args ...interface{}) { 42 if t, ok := logger.(interface { 43 Helper() 44 }); ok { 45 t.Helper() 46 } 47 48 userMsg := fmt.Sprintf(msg, args...) 49 logger.Log(fmt.Sprintf("%siBazel [%s]%s: %s", 50 c, 51 timeNow().Local().Format(time.Kitchen), 52 resetColor, 53 userMsg)) 54 } 55 56 // NewLine prints a new line to the screen without any preamble. 57 func NewLine() { 58 if t, ok := logger.(interface { 59 Helper() 60 }); ok { 61 t.Helper() 62 } 63 64 logger.Log("") 65 } 66 67 // Print out a banner surrounded by # to draw attention to the eye. 68 func Banner(lines ...string) { 69 if t, ok := logger.(interface { 70 Helper() 71 }); ok { 72 t.Helper() 73 } 74 75 NewLine() 76 logger.Log(fmt.Sprintf("%s%s%s", bannerColor, strings.Repeat("#", 80), resetColor)) 77 78 for _, line := range lines { 79 logger.Log(fmt.Sprintf("%s#%s %-76s %s#%s", bannerColor, resetColor, line, bannerColor, resetColor)) 80 } 81 82 logger.Log(fmt.Sprintf("%s%s%s", bannerColor, strings.Repeat("#", 80), resetColor)) 83 NewLine() 84 } 85 86 // Error prints an error to the screen with a preamble. 87 func Error(msg string) { 88 if t, ok := logger.(interface { 89 Helper() 90 }); ok { 91 t.Helper() 92 } 93 94 Errorf(msg) 95 } 96 97 // Errorf prints an error to the screen with a preamble. 98 func Errorf(msg string, args ...interface{}) { 99 if t, ok := logger.(interface { 100 Helper() 101 }); ok { 102 t.Helper() 103 } 104 105 log(errorColor, msg, args...) 106 } 107 108 // Fatal prints a fatal error to the screen with a preamble. 109 func Fatal(msg string) { 110 if t, ok := logger.(interface { 111 Helper() 112 }); ok { 113 t.Helper() 114 } 115 116 Fatalf(msg) 117 } 118 119 // Fatalf prints a fatal error to the screen with a preamble. 120 func Fatalf(msg string, args ...interface{}) { 121 if t, ok := logger.(interface { 122 Helper() 123 }); ok { 124 t.Helper() 125 } 126 127 log(fatalColor, msg, args...) 128 exit(1) 129 } 130 131 // Log prints a message to the screen with a preamble. 132 func Log(msg string) { 133 if t, ok := logger.(interface { 134 Helper() 135 }); ok { 136 t.Helper() 137 } 138 Logf(msg) 139 } 140 141 // Logf prints a message to the screen with a preamble. 142 func Logf(msg string, args ...interface{}) { 143 if t, ok := logger.(interface { 144 Helper() 145 }); ok { 146 t.Helper() 147 } 148 149 log(logColor, msg, args...) 150 } 151 152 func SetTesting(t interface { 153 Log(...interface{}) 154 Fail() 155 }) { 156 logger = t 157 } 158 159 // SetLogger decides which io.Writer to write logs to. 160 func SetLogger(l Logger) { 161 logger = l 162 } 163 164 // FakeExit makes the Fatal log methods not exit. 165 func FakeExit() { 166 osExit = func(int) {} 167 } 168 169 func exit(code int) { 170 osExit(code) 171 }