1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
|
package pp
import (
"errors"
"fmt"
"io"
"os"
"runtime"
"sync"
"github.com/mattn/go-colorable"
)
var (
defaultOut = colorable.NewColorableStdout()
defaultWithLineInfo = false
defaultPrettyPrinter = newPrettyPrinter(3) // pp.* => PrettyPrinter.* => formatAll
)
type PrettyPrinter struct {
out io.Writer
currentScheme ColorScheme
// WithLineInfo add file name and line information to output
// call this function with care, because getting stack has performance penalty
WithLineInfo bool
outLock sync.Mutex
maxDepth int
coloringEnabled bool
callerLevel int
}
// New creates a new PrettyPrinter that can be used to pretty print values
func New() *PrettyPrinter {
return newPrettyPrinter(2) // PrettyPrinter.* => formatAll
}
func newPrettyPrinter(callerLevel int) *PrettyPrinter {
return &PrettyPrinter{
out: defaultOut,
currentScheme: defaultScheme,
WithLineInfo: defaultWithLineInfo,
maxDepth: -1,
coloringEnabled: true,
callerLevel: callerLevel,
}
}
// Print prints given arguments.
func (pp *PrettyPrinter) Print(a ...interface{}) (n int, err error) {
return fmt.Fprint(pp.out, pp.formatAll(a)...)
}
// Printf prints a given format.
func (pp *PrettyPrinter) Printf(format string, a ...interface{}) (n int, err error) {
return fmt.Fprintf(pp.out, format, pp.formatAll(a)...)
}
// Println prints given arguments with newline.
func (pp *PrettyPrinter) Println(a ...interface{}) (n int, err error) {
return fmt.Fprintln(pp.out, pp.formatAll(a)...)
}
// Sprint formats given arguemnts and returns the result as string.
func (pp *PrettyPrinter) Sprint(a ...interface{}) string {
return fmt.Sprint(pp.formatAll(a)...)
}
// Sprintf formats with pretty print and returns the result as string.
func (pp *PrettyPrinter) Sprintf(format string, a ...interface{}) string {
return fmt.Sprintf(format, pp.formatAll(a)...)
}
// Sprintln formats given arguemnts with newline and returns the result as string.
func (pp *PrettyPrinter) Sprintln(a ...interface{}) string {
return fmt.Sprintln(pp.formatAll(a)...)
}
// Fprint prints given arguments to a given writer.
func (pp *PrettyPrinter) Fprint(w io.Writer, a ...interface{}) (n int, err error) {
return fmt.Fprint(w, pp.formatAll(a)...)
}
// Fprintf prints format to a given writer.
func (pp *PrettyPrinter) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
return fmt.Fprintf(w, format, pp.formatAll(a)...)
}
// Fprintln prints given arguments to a given writer with newline.
func (pp *PrettyPrinter) Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
return fmt.Fprintln(w, pp.formatAll(a)...)
}
// Errorf formats given arguments and returns it as error type.
func (pp *PrettyPrinter) Errorf(format string, a ...interface{}) error {
return errors.New(pp.Sprintf(format, a...))
}
// Fatal prints given arguments and finishes execution with exit status 1.
func (pp *PrettyPrinter) Fatal(a ...interface{}) {
fmt.Fprint(pp.out, pp.formatAll(a)...)
os.Exit(1)
}
// Fatalf prints a given format and finishes execution with exit status 1.
func (pp *PrettyPrinter) Fatalf(format string, a ...interface{}) {
fmt.Fprintf(pp.out, format, pp.formatAll(a)...)
os.Exit(1)
}
// Fatalln prints given arguments with newline and finishes execution with exit status 1.
func (pp *PrettyPrinter) Fatalln(a ...interface{}) {
fmt.Fprintln(pp.out, pp.formatAll(a)...)
os.Exit(1)
}
func (pp *PrettyPrinter) SetColoringEnabled(enabled bool) {
pp.coloringEnabled = enabled
}
// SetOutput sets pp's output
func (pp *PrettyPrinter) SetOutput(o io.Writer) {
pp.outLock.Lock()
defer pp.outLock.Unlock()
pp.out = o
}
// GetOutput returns pp's output.
func (pp *PrettyPrinter) GetOutput() io.Writer {
return pp.out
}
// ResetOutput sets pp's output back to the default output
func (pp *PrettyPrinter) ResetOutput() {
pp.outLock.Lock()
defer pp.outLock.Unlock()
pp.out = defaultOut
}
// SetColorScheme takes a colorscheme used by all future Print calls.
func (pp *PrettyPrinter) SetColorScheme(scheme ColorScheme) {
scheme.fixColors()
pp.currentScheme = scheme
}
// ResetColorScheme resets colorscheme to default.
func (pp *PrettyPrinter) ResetColorScheme() {
pp.currentScheme = defaultScheme
}
func (pp *PrettyPrinter) formatAll(objects []interface{}) []interface{} {
results := []interface{}{}
// fix for backwards capability
withLineInfo := pp.WithLineInfo
if pp == defaultPrettyPrinter {
withLineInfo = WithLineInfo
}
if withLineInfo {
_, fn, line, _ := runtime.Caller(pp.callerLevel)
results = append(results, fmt.Sprintf("%s:%d\n", fn, line))
}
for _, object := range objects {
results = append(results, pp.format(object))
}
return results
}
// Print prints given arguments.
func Print(a ...interface{}) (n int, err error) {
return defaultPrettyPrinter.Print(a...)
}
// Printf prints a given format.
func Printf(format string, a ...interface{}) (n int, err error) {
return defaultPrettyPrinter.Printf(format, a...)
}
// Println prints given arguments with newline.
func Println(a ...interface{}) (n int, err error) {
return defaultPrettyPrinter.Println(a...)
}
// Sprint formats given arguemnts and returns the result as string.
func Sprint(a ...interface{}) string {
return defaultPrettyPrinter.Sprint(a...)
}
// Sprintf formats with pretty print and returns the result as string.
func Sprintf(format string, a ...interface{}) string {
return defaultPrettyPrinter.Sprintf(format, a...)
}
// Sprintln formats given arguemnts with newline and returns the result as string.
func Sprintln(a ...interface{}) string {
return defaultPrettyPrinter.Sprintln(a...)
}
// Fprint prints given arguments to a given writer.
func Fprint(w io.Writer, a ...interface{}) (n int, err error) {
return defaultPrettyPrinter.Fprint(w, a...)
}
// Fprintf prints format to a given writer.
func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
return defaultPrettyPrinter.Fprintf(w, format, a...)
}
// Fprintln prints given arguments to a given writer with newline.
func Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
return defaultPrettyPrinter.Fprintln(w, a...)
}
// Errorf formats given arguments and returns it as error type.
func Errorf(format string, a ...interface{}) error {
return defaultPrettyPrinter.Errorf(format, a...)
}
// Fatal prints given arguments and finishes execution with exit status 1.
func Fatal(a ...interface{}) {
defaultPrettyPrinter.Fatal(a...)
}
// Fatalf prints a given format and finishes execution with exit status 1.
func Fatalf(format string, a ...interface{}) {
defaultPrettyPrinter.Fatalf(format, a...)
}
// Fatalln prints given arguments with newline and finishes execution with exit status 1.
func Fatalln(a ...interface{}) {
defaultPrettyPrinter.Fatalln(a...)
}
// Change Print* functions' output to a given writer.
// For example, you can limit output by ENV.
//
// func init() {
// if os.Getenv("DEBUG") == "" {
// pp.SetDefaultOutput(ioutil.Discard)
// }
// }
func SetDefaultOutput(o io.Writer) {
defaultPrettyPrinter.SetOutput(o)
}
// GetOutput returns pp's default output.
func GetDefaultOutput() io.Writer {
return defaultPrettyPrinter.GetOutput()
}
// Change Print* functions' output to default one.
func ResetDefaultOutput() {
defaultPrettyPrinter.ResetOutput()
}
// SetColorScheme takes a colorscheme used by all future Print calls.
func SetColorScheme(scheme ColorScheme) {
defaultPrettyPrinter.SetColorScheme(scheme)
}
// ResetColorScheme resets colorscheme to default.
func ResetColorScheme() {
defaultPrettyPrinter.ResetColorScheme()
}
// SetMaxDepth sets the printer's Depth, -1 prints all
func SetDefaultMaxDepth(v int) {
defaultPrettyPrinter.maxDepth = v
}
// WithLineInfo add file name and line information to output
// call this function with care, because getting stack has performance penalty
var WithLineInfo bool
|