kidjung 4 年之前
父節點
當前提交
ecb664d7fe
共有 5 個檔案被更改,包括 1154 行新增0 行删除
  1. 618
    0
      src/github.com/fatih/color.go
  2. 385
    0
      src/github.com/fatih/color_test.go
  3. 135
    0
      src/github.com/fatih/doc.go
  4. 8
    0
      src/github.com/fatih/go.mod
  5. 8
    0
      src/github.com/fatih/go.sum

+ 618
- 0
src/github.com/fatih/color.go 查看文件

@@ -0,0 +1,618 @@
1
+package color
2
+
3
+import (
4
+	"fmt"
5
+	"io"
6
+	"os"
7
+	"strconv"
8
+	"strings"
9
+	"sync"
10
+
11
+	"github.com/mattn/go-colorable"
12
+	"github.com/mattn/go-isatty"
13
+)
14
+
15
+var (
16
+	// NoColor defines if the output is colorized or not. It's dynamically set to
17
+	// false or true based on the stdout's file descriptor referring to a terminal
18
+	// or not. It's also set to true if the NO_COLOR environment variable is
19
+	// set (regardless of its value). This is a global option and affects all
20
+	// colors. For more control over each color block use the methods
21
+	// DisableColor() individually.
22
+	NoColor = noColorExists() || os.Getenv("TERM") == "dumb" ||
23
+		(!isatty.IsTerminal(os.Stdout.Fd()) && !isatty.IsCygwinTerminal(os.Stdout.Fd()))
24
+
25
+	// Output defines the standard output of the print functions. By default
26
+	// os.Stdout is used.
27
+	Output = colorable.NewColorableStdout()
28
+
29
+	// Error defines a color supporting writer for os.Stderr.
30
+	Error = colorable.NewColorableStderr()
31
+
32
+	// colorsCache is used to reduce the count of created Color objects and
33
+	// allows to reuse already created objects with required Attribute.
34
+	colorsCache   = make(map[Attribute]*Color)
35
+	colorsCacheMu sync.Mutex // protects colorsCache
36
+)
37
+
38
+// noColorExists returns true if the environment variable NO_COLOR exists.
39
+func noColorExists() bool {
40
+	_, exists := os.LookupEnv("NO_COLOR")
41
+	return exists
42
+}
43
+
44
+// Color defines a custom color object which is defined by SGR parameters.
45
+type Color struct {
46
+	params  []Attribute
47
+	noColor *bool
48
+}
49
+
50
+// Attribute defines a single SGR Code
51
+type Attribute int
52
+
53
+const escape = "\x1b"
54
+
55
+// Base attributes
56
+const (
57
+	Reset Attribute = iota
58
+	Bold
59
+	Faint
60
+	Italic
61
+	Underline
62
+	BlinkSlow
63
+	BlinkRapid
64
+	ReverseVideo
65
+	Concealed
66
+	CrossedOut
67
+)
68
+
69
+// Foreground text colors
70
+const (
71
+	FgBlack Attribute = iota + 30
72
+	FgRed
73
+	FgGreen
74
+	FgYellow
75
+	FgBlue
76
+	FgMagenta
77
+	FgCyan
78
+	FgWhite
79
+)
80
+
81
+// Foreground Hi-Intensity text colors
82
+const (
83
+	FgHiBlack Attribute = iota + 90
84
+	FgHiRed
85
+	FgHiGreen
86
+	FgHiYellow
87
+	FgHiBlue
88
+	FgHiMagenta
89
+	FgHiCyan
90
+	FgHiWhite
91
+)
92
+
93
+// Background text colors
94
+const (
95
+	BgBlack Attribute = iota + 40
96
+	BgRed
97
+	BgGreen
98
+	BgYellow
99
+	BgBlue
100
+	BgMagenta
101
+	BgCyan
102
+	BgWhite
103
+)
104
+
105
+// Background Hi-Intensity text colors
106
+const (
107
+	BgHiBlack Attribute = iota + 100
108
+	BgHiRed
109
+	BgHiGreen
110
+	BgHiYellow
111
+	BgHiBlue
112
+	BgHiMagenta
113
+	BgHiCyan
114
+	BgHiWhite
115
+)
116
+
117
+// New returns a newly created color object.
118
+func New(value ...Attribute) *Color {
119
+	c := &Color{
120
+		params: make([]Attribute, 0),
121
+	}
122
+
123
+	if noColorExists() {
124
+		c.noColor = boolPtr(true)
125
+	}
126
+
127
+	c.Add(value...)
128
+	return c
129
+}
130
+
131
+// Set sets the given parameters immediately. It will change the color of
132
+// output with the given SGR parameters until color.Unset() is called.
133
+func Set(p ...Attribute) *Color {
134
+	c := New(p...)
135
+	c.Set()
136
+	return c
137
+}
138
+
139
+// Unset resets all escape attributes and clears the output. Usually should
140
+// be called after Set().
141
+func Unset() {
142
+	if NoColor {
143
+		return
144
+	}
145
+
146
+	fmt.Fprintf(Output, "%s[%dm", escape, Reset)
147
+}
148
+
149
+// Set sets the SGR sequence.
150
+func (c *Color) Set() *Color {
151
+	if c.isNoColorSet() {
152
+		return c
153
+	}
154
+
155
+	fmt.Fprintf(Output, c.format())
156
+	return c
157
+}
158
+
159
+func (c *Color) unset() {
160
+	if c.isNoColorSet() {
161
+		return
162
+	}
163
+
164
+	Unset()
165
+}
166
+
167
+func (c *Color) setWriter(w io.Writer) *Color {
168
+	if c.isNoColorSet() {
169
+		return c
170
+	}
171
+
172
+	fmt.Fprintf(w, c.format())
173
+	return c
174
+}
175
+
176
+func (c *Color) unsetWriter(w io.Writer) {
177
+	if c.isNoColorSet() {
178
+		return
179
+	}
180
+
181
+	if NoColor {
182
+		return
183
+	}
184
+
185
+	fmt.Fprintf(w, "%s[%dm", escape, Reset)
186
+}
187
+
188
+// Add is used to chain SGR parameters. Use as many as parameters to combine
189
+// and create custom color objects. Example: Add(color.FgRed, color.Underline).
190
+func (c *Color) Add(value ...Attribute) *Color {
191
+	c.params = append(c.params, value...)
192
+	return c
193
+}
194
+
195
+func (c *Color) prepend(value Attribute) {
196
+	c.params = append(c.params, 0)
197
+	copy(c.params[1:], c.params[0:])
198
+	c.params[0] = value
199
+}
200
+
201
+// Fprint formats using the default formats for its operands and writes to w.
202
+// Spaces are added between operands when neither is a string.
203
+// It returns the number of bytes written and any write error encountered.
204
+// On Windows, users should wrap w with colorable.NewColorable() if w is of
205
+// type *os.File.
206
+func (c *Color) Fprint(w io.Writer, a ...interface{}) (n int, err error) {
207
+	c.setWriter(w)
208
+	defer c.unsetWriter(w)
209
+
210
+	return fmt.Fprint(w, a...)
211
+}
212
+
213
+// Print formats using the default formats for its operands and writes to
214
+// standard output. Spaces are added between operands when neither is a
215
+// string. It returns the number of bytes written and any write error
216
+// encountered. This is the standard fmt.Print() method wrapped with the given
217
+// color.
218
+func (c *Color) Print(a ...interface{}) (n int, err error) {
219
+	c.Set()
220
+	defer c.unset()
221
+
222
+	return fmt.Fprint(Output, a...)
223
+}
224
+
225
+// Fprintf formats according to a format specifier and writes to w.
226
+// It returns the number of bytes written and any write error encountered.
227
+// On Windows, users should wrap w with colorable.NewColorable() if w is of
228
+// type *os.File.
229
+func (c *Color) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
230
+	c.setWriter(w)
231
+	defer c.unsetWriter(w)
232
+
233
+	return fmt.Fprintf(w, format, a...)
234
+}
235
+
236
+// Printf formats according to a format specifier and writes to standard output.
237
+// It returns the number of bytes written and any write error encountered.
238
+// This is the standard fmt.Printf() method wrapped with the given color.
239
+func (c *Color) Printf(format string, a ...interface{}) (n int, err error) {
240
+	c.Set()
241
+	defer c.unset()
242
+
243
+	return fmt.Fprintf(Output, format, a...)
244
+}
245
+
246
+// Fprintln formats using the default formats for its operands and writes to w.
247
+// Spaces are always added between operands and a newline is appended.
248
+// On Windows, users should wrap w with colorable.NewColorable() if w is of
249
+// type *os.File.
250
+func (c *Color) Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
251
+	c.setWriter(w)
252
+	defer c.unsetWriter(w)
253
+
254
+	return fmt.Fprintln(w, a...)
255
+}
256
+
257
+// Println formats using the default formats for its operands and writes to
258
+// standard output. Spaces are always added between operands and a newline is
259
+// appended. It returns the number of bytes written and any write error
260
+// encountered. This is the standard fmt.Print() method wrapped with the given
261
+// color.
262
+func (c *Color) Println(a ...interface{}) (n int, err error) {
263
+	c.Set()
264
+	defer c.unset()
265
+
266
+	return fmt.Fprintln(Output, a...)
267
+}
268
+
269
+// Sprint is just like Print, but returns a string instead of printing it.
270
+func (c *Color) Sprint(a ...interface{}) string {
271
+	return c.wrap(fmt.Sprint(a...))
272
+}
273
+
274
+// Sprintln is just like Println, but returns a string instead of printing it.
275
+func (c *Color) Sprintln(a ...interface{}) string {
276
+	return c.wrap(fmt.Sprintln(a...))
277
+}
278
+
279
+// Sprintf is just like Printf, but returns a string instead of printing it.
280
+func (c *Color) Sprintf(format string, a ...interface{}) string {
281
+	return c.wrap(fmt.Sprintf(format, a...))
282
+}
283
+
284
+// FprintFunc returns a new function that prints the passed arguments as
285
+// colorized with color.Fprint().
286
+func (c *Color) FprintFunc() func(w io.Writer, a ...interface{}) {
287
+	return func(w io.Writer, a ...interface{}) {
288
+		c.Fprint(w, a...)
289
+	}
290
+}
291
+
292
+// PrintFunc returns a new function that prints the passed arguments as
293
+// colorized with color.Print().
294
+func (c *Color) PrintFunc() func(a ...interface{}) {
295
+	return func(a ...interface{}) {
296
+		c.Print(a...)
297
+	}
298
+}
299
+
300
+// FprintfFunc returns a new function that prints the passed arguments as
301
+// colorized with color.Fprintf().
302
+func (c *Color) FprintfFunc() func(w io.Writer, format string, a ...interface{}) {
303
+	return func(w io.Writer, format string, a ...interface{}) {
304
+		c.Fprintf(w, format, a...)
305
+	}
306
+}
307
+
308
+// PrintfFunc returns a new function that prints the passed arguments as
309
+// colorized with color.Printf().
310
+func (c *Color) PrintfFunc() func(format string, a ...interface{}) {
311
+	return func(format string, a ...interface{}) {
312
+		c.Printf(format, a...)
313
+	}
314
+}
315
+
316
+// FprintlnFunc returns a new function that prints the passed arguments as
317
+// colorized with color.Fprintln().
318
+func (c *Color) FprintlnFunc() func(w io.Writer, a ...interface{}) {
319
+	return func(w io.Writer, a ...interface{}) {
320
+		c.Fprintln(w, a...)
321
+	}
322
+}
323
+
324
+// PrintlnFunc returns a new function that prints the passed arguments as
325
+// colorized with color.Println().
326
+func (c *Color) PrintlnFunc() func(a ...interface{}) {
327
+	return func(a ...interface{}) {
328
+		c.Println(a...)
329
+	}
330
+}
331
+
332
+// SprintFunc returns a new function that returns colorized strings for the
333
+// given arguments with fmt.Sprint(). Useful to put into or mix into other
334
+// string. Windows users should use this in conjunction with color.Output, example:
335
+//
336
+//	put := New(FgYellow).SprintFunc()
337
+//	fmt.Fprintf(color.Output, "This is a %s", put("warning"))
338
+func (c *Color) SprintFunc() func(a ...interface{}) string {
339
+	return func(a ...interface{}) string {
340
+		return c.wrap(fmt.Sprint(a...))
341
+	}
342
+}
343
+
344
+// SprintfFunc returns a new function that returns colorized strings for the
345
+// given arguments with fmt.Sprintf(). Useful to put into or mix into other
346
+// string. Windows users should use this in conjunction with color.Output.
347
+func (c *Color) SprintfFunc() func(format string, a ...interface{}) string {
348
+	return func(format string, a ...interface{}) string {
349
+		return c.wrap(fmt.Sprintf(format, a...))
350
+	}
351
+}
352
+
353
+// SprintlnFunc returns a new function that returns colorized strings for the
354
+// given arguments with fmt.Sprintln(). Useful to put into or mix into other
355
+// string. Windows users should use this in conjunction with color.Output.
356
+func (c *Color) SprintlnFunc() func(a ...interface{}) string {
357
+	return func(a ...interface{}) string {
358
+		return c.wrap(fmt.Sprintln(a...))
359
+	}
360
+}
361
+
362
+// sequence returns a formatted SGR sequence to be plugged into a "\x1b[...m"
363
+// an example output might be: "1;36" -> bold cyan
364
+func (c *Color) sequence() string {
365
+	format := make([]string, len(c.params))
366
+	for i, v := range c.params {
367
+		format[i] = strconv.Itoa(int(v))
368
+	}
369
+
370
+	return strings.Join(format, ";")
371
+}
372
+
373
+// wrap wraps the s string with the colors attributes. The string is ready to
374
+// be printed.
375
+func (c *Color) wrap(s string) string {
376
+	if c.isNoColorSet() {
377
+		return s
378
+	}
379
+
380
+	return c.format() + s + c.unformat()
381
+}
382
+
383
+func (c *Color) format() string {
384
+	return fmt.Sprintf("%s[%sm", escape, c.sequence())
385
+}
386
+
387
+func (c *Color) unformat() string {
388
+	return fmt.Sprintf("%s[%dm", escape, Reset)
389
+}
390
+
391
+// DisableColor disables the color output. Useful to not change any existing
392
+// code and still being able to output. Can be used for flags like
393
+// "--no-color". To enable back use EnableColor() method.
394
+func (c *Color) DisableColor() {
395
+	c.noColor = boolPtr(true)
396
+}
397
+
398
+// EnableColor enables the color output. Use it in conjunction with
399
+// DisableColor(). Otherwise this method has no side effects.
400
+func (c *Color) EnableColor() {
401
+	c.noColor = boolPtr(false)
402
+}
403
+
404
+func (c *Color) isNoColorSet() bool {
405
+	// check first if we have user set action
406
+	if c.noColor != nil {
407
+		return *c.noColor
408
+	}
409
+
410
+	// if not return the global option, which is disabled by default
411
+	return NoColor
412
+}
413
+
414
+// Equals returns a boolean value indicating whether two colors are equal.
415
+func (c *Color) Equals(c2 *Color) bool {
416
+	if len(c.params) != len(c2.params) {
417
+		return false
418
+	}
419
+
420
+	for _, attr := range c.params {
421
+		if !c2.attrExists(attr) {
422
+			return false
423
+		}
424
+	}
425
+
426
+	return true
427
+}
428
+
429
+func (c *Color) attrExists(a Attribute) bool {
430
+	for _, attr := range c.params {
431
+		if attr == a {
432
+			return true
433
+		}
434
+	}
435
+
436
+	return false
437
+}
438
+
439
+func boolPtr(v bool) *bool {
440
+	return &v
441
+}
442
+
443
+func getCachedColor(p Attribute) *Color {
444
+	colorsCacheMu.Lock()
445
+	defer colorsCacheMu.Unlock()
446
+
447
+	c, ok := colorsCache[p]
448
+	if !ok {
449
+		c = New(p)
450
+		colorsCache[p] = c
451
+	}
452
+
453
+	return c
454
+}
455
+
456
+func colorPrint(format string, p Attribute, a ...interface{}) {
457
+	c := getCachedColor(p)
458
+
459
+	if !strings.HasSuffix(format, "\n") {
460
+		format += "\n"
461
+	}
462
+
463
+	if len(a) == 0 {
464
+		c.Print(format)
465
+	} else {
466
+		c.Printf(format, a...)
467
+	}
468
+}
469
+
470
+func colorString(format string, p Attribute, a ...interface{}) string {
471
+	c := getCachedColor(p)
472
+
473
+	if len(a) == 0 {
474
+		return c.SprintFunc()(format)
475
+	}
476
+
477
+	return c.SprintfFunc()(format, a...)
478
+}
479
+
480
+// Black is a convenient helper function to print with black foreground. A
481
+// newline is appended to format by default.
482
+func Black(format string, a ...interface{}) { colorPrint(format, FgBlack, a...) }
483
+
484
+// Red is a convenient helper function to print with red foreground. A
485
+// newline is appended to format by default.
486
+func Red(format string, a ...interface{}) { colorPrint(format, FgRed, a...) }
487
+
488
+// Green is a convenient helper function to print with green foreground. A
489
+// newline is appended to format by default.
490
+func Green(format string, a ...interface{}) { colorPrint(format, FgGreen, a...) }
491
+
492
+// Yellow is a convenient helper function to print with yellow foreground.
493
+// A newline is appended to format by default.
494
+func Yellow(format string, a ...interface{}) { colorPrint(format, FgYellow, a...) }
495
+
496
+// Blue is a convenient helper function to print with blue foreground. A
497
+// newline is appended to format by default.
498
+func Blue(format string, a ...interface{}) { colorPrint(format, FgBlue, a...) }
499
+
500
+// Magenta is a convenient helper function to print with magenta foreground.
501
+// A newline is appended to format by default.
502
+func Magenta(format string, a ...interface{}) { colorPrint(format, FgMagenta, a...) }
503
+
504
+// Cyan is a convenient helper function to print with cyan foreground. A
505
+// newline is appended to format by default.
506
+func Cyan(format string, a ...interface{}) { colorPrint(format, FgCyan, a...) }
507
+
508
+// White is a convenient helper function to print with white foreground. A
509
+// newline is appended to format by default.
510
+func White(format string, a ...interface{}) { colorPrint(format, FgWhite, a...) }
511
+
512
+// BlackString is a convenient helper function to return a string with black
513
+// foreground.
514
+func BlackString(format string, a ...interface{}) string { return colorString(format, FgBlack, a...) }
515
+
516
+// RedString is a convenient helper function to return a string with red
517
+// foreground.
518
+func RedString(format string, a ...interface{}) string { return colorString(format, FgRed, a...) }
519
+
520
+// GreenString is a convenient helper function to return a string with green
521
+// foreground.
522
+func GreenString(format string, a ...interface{}) string { return colorString(format, FgGreen, a...) }
523
+
524
+// YellowString is a convenient helper function to return a string with yellow
525
+// foreground.
526
+func YellowString(format string, a ...interface{}) string { return colorString(format, FgYellow, a...) }
527
+
528
+// BlueString is a convenient helper function to return a string with blue
529
+// foreground.
530
+func BlueString(format string, a ...interface{}) string { return colorString(format, FgBlue, a...) }
531
+
532
+// MagentaString is a convenient helper function to return a string with magenta
533
+// foreground.
534
+func MagentaString(format string, a ...interface{}) string {
535
+	return colorString(format, FgMagenta, a...)
536
+}
537
+
538
+// CyanString is a convenient helper function to return a string with cyan
539
+// foreground.
540
+func CyanString(format string, a ...interface{}) string { return colorString(format, FgCyan, a...) }
541
+
542
+// WhiteString is a convenient helper function to return a string with white
543
+// foreground.
544
+func WhiteString(format string, a ...interface{}) string { return colorString(format, FgWhite, a...) }
545
+
546
+// HiBlack is a convenient helper function to print with hi-intensity black foreground. A
547
+// newline is appended to format by default.
548
+func HiBlack(format string, a ...interface{}) { colorPrint(format, FgHiBlack, a...) }
549
+
550
+// HiRed is a convenient helper function to print with hi-intensity red foreground. A
551
+// newline is appended to format by default.
552
+func HiRed(format string, a ...interface{}) { colorPrint(format, FgHiRed, a...) }
553
+
554
+// HiGreen is a convenient helper function to print with hi-intensity green foreground. A
555
+// newline is appended to format by default.
556
+func HiGreen(format string, a ...interface{}) { colorPrint(format, FgHiGreen, a...) }
557
+
558
+// HiYellow is a convenient helper function to print with hi-intensity yellow foreground.
559
+// A newline is appended to format by default.
560
+func HiYellow(format string, a ...interface{}) { colorPrint(format, FgHiYellow, a...) }
561
+
562
+// HiBlue is a convenient helper function to print with hi-intensity blue foreground. A
563
+// newline is appended to format by default.
564
+func HiBlue(format string, a ...interface{}) { colorPrint(format, FgHiBlue, a...) }
565
+
566
+// HiMagenta is a convenient helper function to print with hi-intensity magenta foreground.
567
+// A newline is appended to format by default.
568
+func HiMagenta(format string, a ...interface{}) { colorPrint(format, FgHiMagenta, a...) }
569
+
570
+// HiCyan is a convenient helper function to print with hi-intensity cyan foreground. A
571
+// newline is appended to format by default.
572
+func HiCyan(format string, a ...interface{}) { colorPrint(format, FgHiCyan, a...) }
573
+
574
+// HiWhite is a convenient helper function to print with hi-intensity white foreground. A
575
+// newline is appended to format by default.
576
+func HiWhite(format string, a ...interface{}) { colorPrint(format, FgHiWhite, a...) }
577
+
578
+// HiBlackString is a convenient helper function to return a string with hi-intensity black
579
+// foreground.
580
+func HiBlackString(format string, a ...interface{}) string {
581
+	return colorString(format, FgHiBlack, a...)
582
+}
583
+
584
+// HiRedString is a convenient helper function to return a string with hi-intensity red
585
+// foreground.
586
+func HiRedString(format string, a ...interface{}) string { return colorString(format, FgHiRed, a...) }
587
+
588
+// HiGreenString is a convenient helper function to return a string with hi-intensity green
589
+// foreground.
590
+func HiGreenString(format string, a ...interface{}) string {
591
+	return colorString(format, FgHiGreen, a...)
592
+}
593
+
594
+// HiYellowString is a convenient helper function to return a string with hi-intensity yellow
595
+// foreground.
596
+func HiYellowString(format string, a ...interface{}) string {
597
+	return colorString(format, FgHiYellow, a...)
598
+}
599
+
600
+// HiBlueString is a convenient helper function to return a string with hi-intensity blue
601
+// foreground.
602
+func HiBlueString(format string, a ...interface{}) string { return colorString(format, FgHiBlue, a...) }
603
+
604
+// HiMagentaString is a convenient helper function to return a string with hi-intensity magenta
605
+// foreground.
606
+func HiMagentaString(format string, a ...interface{}) string {
607
+	return colorString(format, FgHiMagenta, a...)
608
+}
609
+
610
+// HiCyanString is a convenient helper function to return a string with hi-intensity cyan
611
+// foreground.
612
+func HiCyanString(format string, a ...interface{}) string { return colorString(format, FgHiCyan, a...) }
613
+
614
+// HiWhiteString is a convenient helper function to return a string with hi-intensity white
615
+// foreground.
616
+func HiWhiteString(format string, a ...interface{}) string {
617
+	return colorString(format, FgHiWhite, a...)
618
+}

+ 385
- 0
src/github.com/fatih/color_test.go 查看文件

@@ -0,0 +1,385 @@
1
+package color
2
+
3
+import (
4
+	"bytes"
5
+	"fmt"
6
+	"os"
7
+	"testing"
8
+
9
+	"github.com/mattn/go-colorable"
10
+)
11
+
12
+// Testing colors is kinda different. First we test for given colors and their
13
+// escaped formatted results. Next we create some visual tests to be tested.
14
+// Each visual test includes the color name to be compared.
15
+func TestColor(t *testing.T) {
16
+	rb := new(bytes.Buffer)
17
+	Output = rb
18
+
19
+	NoColor = false
20
+
21
+	testColors := []struct {
22
+		text string
23
+		code Attribute
24
+	}{
25
+		{text: "black", code: FgBlack},
26
+		{text: "red", code: FgRed},
27
+		{text: "green", code: FgGreen},
28
+		{text: "yellow", code: FgYellow},
29
+		{text: "blue", code: FgBlue},
30
+		{text: "magent", code: FgMagenta},
31
+		{text: "cyan", code: FgCyan},
32
+		{text: "white", code: FgWhite},
33
+		{text: "hblack", code: FgHiBlack},
34
+		{text: "hred", code: FgHiRed},
35
+		{text: "hgreen", code: FgHiGreen},
36
+		{text: "hyellow", code: FgHiYellow},
37
+		{text: "hblue", code: FgHiBlue},
38
+		{text: "hmagent", code: FgHiMagenta},
39
+		{text: "hcyan", code: FgHiCyan},
40
+		{text: "hwhite", code: FgHiWhite},
41
+	}
42
+
43
+	for _, c := range testColors {
44
+		New(c.code).Print(c.text)
45
+
46
+		line, _ := rb.ReadString('\n')
47
+		scannedLine := fmt.Sprintf("%q", line)
48
+		colored := fmt.Sprintf("\x1b[%dm%s\x1b[0m", c.code, c.text)
49
+		escapedForm := fmt.Sprintf("%q", colored)
50
+
51
+		fmt.Printf("%s\t: %s\n", c.text, line)
52
+
53
+		if scannedLine != escapedForm {
54
+			t.Errorf("Expecting %s, got '%s'\n", escapedForm, scannedLine)
55
+		}
56
+	}
57
+
58
+	for _, c := range testColors {
59
+		line := New(c.code).Sprintf("%s", c.text)
60
+		scannedLine := fmt.Sprintf("%q", line)
61
+		colored := fmt.Sprintf("\x1b[%dm%s\x1b[0m", c.code, c.text)
62
+		escapedForm := fmt.Sprintf("%q", colored)
63
+
64
+		fmt.Printf("%s\t: %s\n", c.text, line)
65
+
66
+		if scannedLine != escapedForm {
67
+			t.Errorf("Expecting %s, got '%s'\n", escapedForm, scannedLine)
68
+		}
69
+	}
70
+}
71
+
72
+func TestColorEquals(t *testing.T) {
73
+	fgblack1 := New(FgBlack)
74
+	fgblack2 := New(FgBlack)
75
+	bgblack := New(BgBlack)
76
+	fgbgblack := New(FgBlack, BgBlack)
77
+	fgblackbgred := New(FgBlack, BgRed)
78
+	fgred := New(FgRed)
79
+	bgred := New(BgRed)
80
+
81
+	if !fgblack1.Equals(fgblack2) {
82
+		t.Error("Two black colors are not equal")
83
+	}
84
+
85
+	if fgblack1.Equals(bgblack) {
86
+		t.Error("Fg and bg black colors are equal")
87
+	}
88
+
89
+	if fgblack1.Equals(fgbgblack) {
90
+		t.Error("Fg black equals fg/bg black color")
91
+	}
92
+
93
+	if fgblack1.Equals(fgred) {
94
+		t.Error("Fg black equals Fg red")
95
+	}
96
+
97
+	if fgblack1.Equals(bgred) {
98
+		t.Error("Fg black equals Bg red")
99
+	}
100
+
101
+	if fgblack1.Equals(fgblackbgred) {
102
+		t.Error("Fg black equals fg black bg red")
103
+	}
104
+}
105
+
106
+func TestNoColor(t *testing.T) {
107
+	rb := new(bytes.Buffer)
108
+	Output = rb
109
+
110
+	testColors := []struct {
111
+		text string
112
+		code Attribute
113
+	}{
114
+		{text: "black", code: FgBlack},
115
+		{text: "red", code: FgRed},
116
+		{text: "green", code: FgGreen},
117
+		{text: "yellow", code: FgYellow},
118
+		{text: "blue", code: FgBlue},
119
+		{text: "magent", code: FgMagenta},
120
+		{text: "cyan", code: FgCyan},
121
+		{text: "white", code: FgWhite},
122
+		{text: "hblack", code: FgHiBlack},
123
+		{text: "hred", code: FgHiRed},
124
+		{text: "hgreen", code: FgHiGreen},
125
+		{text: "hyellow", code: FgHiYellow},
126
+		{text: "hblue", code: FgHiBlue},
127
+		{text: "hmagent", code: FgHiMagenta},
128
+		{text: "hcyan", code: FgHiCyan},
129
+		{text: "hwhite", code: FgHiWhite},
130
+	}
131
+
132
+	for _, c := range testColors {
133
+		p := New(c.code)
134
+		p.DisableColor()
135
+		p.Print(c.text)
136
+
137
+		line, _ := rb.ReadString('\n')
138
+		if line != c.text {
139
+			t.Errorf("Expecting %s, got '%s'\n", c.text, line)
140
+		}
141
+	}
142
+
143
+	// global check
144
+	NoColor = true
145
+	t.Cleanup(func() {
146
+		NoColor = false
147
+	})
148
+
149
+	for _, c := range testColors {
150
+		p := New(c.code)
151
+		p.Print(c.text)
152
+
153
+		line, _ := rb.ReadString('\n')
154
+		if line != c.text {
155
+			t.Errorf("Expecting %s, got '%s'\n", c.text, line)
156
+		}
157
+	}
158
+}
159
+
160
+func TestNoColor_Env(t *testing.T) {
161
+	rb := new(bytes.Buffer)
162
+	Output = rb
163
+
164
+	testColors := []struct {
165
+		text string
166
+		code Attribute
167
+	}{
168
+		{text: "black", code: FgBlack},
169
+		{text: "red", code: FgRed},
170
+		{text: "green", code: FgGreen},
171
+		{text: "yellow", code: FgYellow},
172
+		{text: "blue", code: FgBlue},
173
+		{text: "magent", code: FgMagenta},
174
+		{text: "cyan", code: FgCyan},
175
+		{text: "white", code: FgWhite},
176
+		{text: "hblack", code: FgHiBlack},
177
+		{text: "hred", code: FgHiRed},
178
+		{text: "hgreen", code: FgHiGreen},
179
+		{text: "hyellow", code: FgHiYellow},
180
+		{text: "hblue", code: FgHiBlue},
181
+		{text: "hmagent", code: FgHiMagenta},
182
+		{text: "hcyan", code: FgHiCyan},
183
+		{text: "hwhite", code: FgHiWhite},
184
+	}
185
+
186
+	os.Setenv("NO_COLOR", "")
187
+	t.Cleanup(func() {
188
+		os.Unsetenv("NO_COLOR")
189
+	})
190
+
191
+	for _, c := range testColors {
192
+		p := New(c.code)
193
+		p.Print(c.text)
194
+
195
+		line, _ := rb.ReadString('\n')
196
+		if line != c.text {
197
+			t.Errorf("Expecting %s, got '%s'\n", c.text, line)
198
+		}
199
+	}
200
+
201
+}
202
+
203
+func TestColorVisual(t *testing.T) {
204
+	// First Visual Test
205
+	Output = colorable.NewColorableStdout()
206
+
207
+	New(FgRed).Printf("red\t")
208
+	New(BgRed).Print("         ")
209
+	New(FgRed, Bold).Println(" red")
210
+
211
+	New(FgGreen).Printf("green\t")
212
+	New(BgGreen).Print("         ")
213
+	New(FgGreen, Bold).Println(" green")
214
+
215
+	New(FgYellow).Printf("yellow\t")
216
+	New(BgYellow).Print("         ")
217
+	New(FgYellow, Bold).Println(" yellow")
218
+
219
+	New(FgBlue).Printf("blue\t")
220
+	New(BgBlue).Print("         ")
221
+	New(FgBlue, Bold).Println(" blue")
222
+
223
+	New(FgMagenta).Printf("magenta\t")
224
+	New(BgMagenta).Print("         ")
225
+	New(FgMagenta, Bold).Println(" magenta")
226
+
227
+	New(FgCyan).Printf("cyan\t")
228
+	New(BgCyan).Print("         ")
229
+	New(FgCyan, Bold).Println(" cyan")
230
+
231
+	New(FgWhite).Printf("white\t")
232
+	New(BgWhite).Print("         ")
233
+	New(FgWhite, Bold).Println(" white")
234
+	fmt.Println("")
235
+
236
+	// Second Visual test
237
+	Black("black")
238
+	Red("red")
239
+	Green("green")
240
+	Yellow("yellow")
241
+	Blue("blue")
242
+	Magenta("magenta")
243
+	Cyan("cyan")
244
+	White("white")
245
+	HiBlack("hblack")
246
+	HiRed("hred")
247
+	HiGreen("hgreen")
248
+	HiYellow("hyellow")
249
+	HiBlue("hblue")
250
+	HiMagenta("hmagenta")
251
+	HiCyan("hcyan")
252
+	HiWhite("hwhite")
253
+
254
+	// Third visual test
255
+	fmt.Println()
256
+	Set(FgBlue)
257
+	fmt.Println("is this blue?")
258
+	Unset()
259
+
260
+	Set(FgMagenta)
261
+	fmt.Println("and this magenta?")
262
+	Unset()
263
+
264
+	// Fourth Visual test
265
+	fmt.Println()
266
+	blue := New(FgBlue).PrintlnFunc()
267
+	blue("blue text with custom print func")
268
+
269
+	red := New(FgRed).PrintfFunc()
270
+	red("red text with a printf func: %d\n", 123)
271
+
272
+	put := New(FgYellow).SprintFunc()
273
+	warn := New(FgRed).SprintFunc()
274
+
275
+	fmt.Fprintf(Output, "this is a %s and this is %s.\n", put("warning"), warn("error"))
276
+
277
+	info := New(FgWhite, BgGreen).SprintFunc()
278
+	fmt.Fprintf(Output, "this %s rocks!\n", info("package"))
279
+
280
+	notice := New(FgBlue).FprintFunc()
281
+	notice(os.Stderr, "just a blue notice to stderr")
282
+
283
+	// Fifth Visual Test
284
+	fmt.Println()
285
+
286
+	fmt.Fprintln(Output, BlackString("black"))
287
+	fmt.Fprintln(Output, RedString("red"))
288
+	fmt.Fprintln(Output, GreenString("green"))
289
+	fmt.Fprintln(Output, YellowString("yellow"))
290
+	fmt.Fprintln(Output, BlueString("blue"))
291
+	fmt.Fprintln(Output, MagentaString("magenta"))
292
+	fmt.Fprintln(Output, CyanString("cyan"))
293
+	fmt.Fprintln(Output, WhiteString("white"))
294
+	fmt.Fprintln(Output, HiBlackString("hblack"))
295
+	fmt.Fprintln(Output, HiRedString("hred"))
296
+	fmt.Fprintln(Output, HiGreenString("hgreen"))
297
+	fmt.Fprintln(Output, HiYellowString("hyellow"))
298
+	fmt.Fprintln(Output, HiBlueString("hblue"))
299
+	fmt.Fprintln(Output, HiMagentaString("hmagenta"))
300
+	fmt.Fprintln(Output, HiCyanString("hcyan"))
301
+	fmt.Fprintln(Output, HiWhiteString("hwhite"))
302
+}
303
+
304
+func TestNoFormat(t *testing.T) {
305
+	fmt.Printf("%s   %%s = ", BlackString("Black"))
306
+	Black("%s")
307
+
308
+	fmt.Printf("%s     %%s = ", RedString("Red"))
309
+	Red("%s")
310
+
311
+	fmt.Printf("%s   %%s = ", GreenString("Green"))
312
+	Green("%s")
313
+
314
+	fmt.Printf("%s  %%s = ", YellowString("Yellow"))
315
+	Yellow("%s")
316
+
317
+	fmt.Printf("%s    %%s = ", BlueString("Blue"))
318
+	Blue("%s")
319
+
320
+	fmt.Printf("%s %%s = ", MagentaString("Magenta"))
321
+	Magenta("%s")
322
+
323
+	fmt.Printf("%s    %%s = ", CyanString("Cyan"))
324
+	Cyan("%s")
325
+
326
+	fmt.Printf("%s   %%s = ", WhiteString("White"))
327
+	White("%s")
328
+
329
+	fmt.Printf("%s   %%s = ", HiBlackString("HiBlack"))
330
+	HiBlack("%s")
331
+
332
+	fmt.Printf("%s     %%s = ", HiRedString("HiRed"))
333
+	HiRed("%s")
334
+
335
+	fmt.Printf("%s   %%s = ", HiGreenString("HiGreen"))
336
+	HiGreen("%s")
337
+
338
+	fmt.Printf("%s  %%s = ", HiYellowString("HiYellow"))
339
+	HiYellow("%s")
340
+
341
+	fmt.Printf("%s    %%s = ", HiBlueString("HiBlue"))
342
+	HiBlue("%s")
343
+
344
+	fmt.Printf("%s %%s = ", HiMagentaString("HiMagenta"))
345
+	HiMagenta("%s")
346
+
347
+	fmt.Printf("%s    %%s = ", HiCyanString("HiCyan"))
348
+	HiCyan("%s")
349
+
350
+	fmt.Printf("%s   %%s = ", HiWhiteString("HiWhite"))
351
+	HiWhite("%s")
352
+}
353
+
354
+func TestNoFormatString(t *testing.T) {
355
+	tests := []struct {
356
+		f      func(string, ...interface{}) string
357
+		format string
358
+		args   []interface{}
359
+		want   string
360
+	}{
361
+		{BlackString, "%s", nil, "\x1b[30m%s\x1b[0m"},
362
+		{RedString, "%s", nil, "\x1b[31m%s\x1b[0m"},
363
+		{GreenString, "%s", nil, "\x1b[32m%s\x1b[0m"},
364
+		{YellowString, "%s", nil, "\x1b[33m%s\x1b[0m"},
365
+		{BlueString, "%s", nil, "\x1b[34m%s\x1b[0m"},
366
+		{MagentaString, "%s", nil, "\x1b[35m%s\x1b[0m"},
367
+		{CyanString, "%s", nil, "\x1b[36m%s\x1b[0m"},
368
+		{WhiteString, "%s", nil, "\x1b[37m%s\x1b[0m"},
369
+		{HiBlackString, "%s", nil, "\x1b[90m%s\x1b[0m"},
370
+		{HiRedString, "%s", nil, "\x1b[91m%s\x1b[0m"},
371
+		{HiGreenString, "%s", nil, "\x1b[92m%s\x1b[0m"},
372
+		{HiYellowString, "%s", nil, "\x1b[93m%s\x1b[0m"},
373
+		{HiBlueString, "%s", nil, "\x1b[94m%s\x1b[0m"},
374
+		{HiMagentaString, "%s", nil, "\x1b[95m%s\x1b[0m"},
375
+		{HiCyanString, "%s", nil, "\x1b[96m%s\x1b[0m"},
376
+		{HiWhiteString, "%s", nil, "\x1b[97m%s\x1b[0m"},
377
+	}
378
+
379
+	for i, test := range tests {
380
+		s := fmt.Sprintf("%s", test.f(test.format, test.args...))
381
+		if s != test.want {
382
+			t.Errorf("[%d] want: %q, got: %q", i, test.want, s)
383
+		}
384
+	}
385
+}

+ 135
- 0
src/github.com/fatih/doc.go 查看文件

@@ -0,0 +1,135 @@
1
+/*
2
+Package color is an ANSI color package to output colorized or SGR defined
3
+output to the standard output. The API can be used in several way, pick one
4
+that suits you.
5
+
6
+Use simple and default helper functions with predefined foreground colors:
7
+
8
+    color.Cyan("Prints text in cyan.")
9
+
10
+    // a newline will be appended automatically
11
+    color.Blue("Prints %s in blue.", "text")
12
+
13
+    // More default foreground colors..
14
+    color.Red("We have red")
15
+    color.Yellow("Yellow color too!")
16
+    color.Magenta("And many others ..")
17
+
18
+    // Hi-intensity colors
19
+    color.HiGreen("Bright green color.")
20
+    color.HiBlack("Bright black means gray..")
21
+    color.HiWhite("Shiny white color!")
22
+
23
+However there are times where custom color mixes are required. Below are some
24
+examples to create custom color objects and use the print functions of each
25
+separate color object.
26
+
27
+    // Create a new color object
28
+    c := color.New(color.FgCyan).Add(color.Underline)
29
+    c.Println("Prints cyan text with an underline.")
30
+
31
+    // Or just add them to New()
32
+    d := color.New(color.FgCyan, color.Bold)
33
+    d.Printf("This prints bold cyan %s\n", "too!.")
34
+
35
+
36
+    // Mix up foreground and background colors, create new mixes!
37
+    red := color.New(color.FgRed)
38
+
39
+    boldRed := red.Add(color.Bold)
40
+    boldRed.Println("This will print text in bold red.")
41
+
42
+    whiteBackground := red.Add(color.BgWhite)
43
+    whiteBackground.Println("Red text with White background.")
44
+
45
+    // Use your own io.Writer output
46
+    color.New(color.FgBlue).Fprintln(myWriter, "blue color!")
47
+
48
+    blue := color.New(color.FgBlue)
49
+    blue.Fprint(myWriter, "This will print text in blue.")
50
+
51
+You can create PrintXxx functions to simplify even more:
52
+
53
+    // Create a custom print function for convenient
54
+    red := color.New(color.FgRed).PrintfFunc()
55
+    red("warning")
56
+    red("error: %s", err)
57
+
58
+    // Mix up multiple attributes
59
+    notice := color.New(color.Bold, color.FgGreen).PrintlnFunc()
60
+    notice("don't forget this...")
61
+
62
+You can also FprintXxx functions to pass your own io.Writer:
63
+
64
+    blue := color.New(FgBlue).FprintfFunc()
65
+    blue(myWriter, "important notice: %s", stars)
66
+
67
+    // Mix up with multiple attributes
68
+    success := color.New(color.Bold, color.FgGreen).FprintlnFunc()
69
+    success(myWriter, don't forget this...")
70
+
71
+
72
+Or create SprintXxx functions to mix strings with other non-colorized strings:
73
+
74
+    yellow := New(FgYellow).SprintFunc()
75
+    red := New(FgRed).SprintFunc()
76
+
77
+    fmt.Printf("this is a %s and this is %s.\n", yellow("warning"), red("error"))
78
+
79
+    info := New(FgWhite, BgGreen).SprintFunc()
80
+    fmt.Printf("this %s rocks!\n", info("package"))
81
+
82
+Windows support is enabled by default. All Print functions work as intended.
83
+However only for color.SprintXXX functions, user should use fmt.FprintXXX and
84
+set the output to color.Output:
85
+
86
+    fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS"))
87
+
88
+    info := New(FgWhite, BgGreen).SprintFunc()
89
+    fmt.Fprintf(color.Output, "this %s rocks!\n", info("package"))
90
+
91
+Using with existing code is possible. Just use the Set() method to set the
92
+standard output to the given parameters. That way a rewrite of an existing
93
+code is not required.
94
+
95
+    // Use handy standard colors.
96
+    color.Set(color.FgYellow)
97
+
98
+    fmt.Println("Existing text will be now in Yellow")
99
+    fmt.Printf("This one %s\n", "too")
100
+
101
+    color.Unset() // don't forget to unset
102
+
103
+    // You can mix up parameters
104
+    color.Set(color.FgMagenta, color.Bold)
105
+    defer color.Unset() // use it in your function
106
+
107
+    fmt.Println("All text will be now bold magenta.")
108
+
109
+There might be a case where you want to disable color output (for example to
110
+pipe the standard output of your app to somewhere else). `Color` has support to
111
+disable colors both globally and for single color definition. For example
112
+suppose you have a CLI app and a `--no-color` bool flag. You can easily disable
113
+the color output with:
114
+
115
+    var flagNoColor = flag.Bool("no-color", false, "Disable color output")
116
+
117
+    if *flagNoColor {
118
+    	color.NoColor = true // disables colorized output
119
+    }
120
+
121
+You can also disable the color by setting the NO_COLOR environment variable to any value.
122
+
123
+It also has support for single color definitions (local). You can
124
+disable/enable color output on the fly:
125
+
126
+     c := color.New(color.FgCyan)
127
+     c.Println("Prints cyan text")
128
+
129
+     c.DisableColor()
130
+     c.Println("This is printed without any color")
131
+
132
+     c.EnableColor()
133
+     c.Println("This prints again cyan...")
134
+*/
135
+package color

+ 8
- 0
src/github.com/fatih/go.mod 查看文件

@@ -0,0 +1,8 @@
1
+module github.com/fatih/color
2
+
3
+go 1.13
4
+
5
+require (
6
+	github.com/mattn/go-colorable v0.1.8
7
+	github.com/mattn/go-isatty v0.0.13
8
+)

+ 8
- 0
src/github.com/fatih/go.sum 查看文件

@@ -0,0 +1,8 @@
1
+github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
2
+github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
3
+github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
4
+github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA=
5
+github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
6
+golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
7
+golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8=
8
+golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

Loading…
取消
儲存