-
Notifications
You must be signed in to change notification settings - Fork 80
/
iostreams.go
129 lines (109 loc) · 2.77 KB
/
iostreams.go
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
package cli
import (
"bytes"
"fmt"
"io"
"os"
"runtime"
surveyCore "github.com/AlecAivazis/survey/v2/core"
"github.com/mattn/go-colorable"
"github.com/mattn/go-isatty"
"github.com/mgutz/ansi"
)
type IOStreams struct {
In io.ReadCloser
Out io.Writer
ErrOut io.Writer
colorEnabled bool
progressIndicatorEnabled bool
stdoutTTYOverride bool
stderrTTYOverride bool
stderrIsTTY bool
stdoutIsTTY bool
is256enabled bool
}
func (s *IOStreams) ColorScheme() *ColorScheme {
return NewColorScheme(s.ColorEnabled(), s.ColorSupport256())
}
func (s *IOStreams) ColorEnabled() bool {
return s.colorEnabled
}
func (s *IOStreams) SetColorEnabled(colorEnabled bool) {
s.colorEnabled = colorEnabled
s.setSurveyColor()
s.progressIndicatorEnabled = colorEnabled
}
func (s *IOStreams) setSurveyColor() {
if !s.colorEnabled {
surveyCore.DisableColor = true
} else {
// override survey's poor choice of color
surveyCore.TemplateFuncsWithColor["color"] = func(style string) string {
switch style {
case "white":
if s.ColorSupport256() {
return fmt.Sprintf("\x1b[%d;5;%dm", 38, 242)
}
return ansi.ColorCode("default")
default:
return ansi.ColorCode(style)
}
}
}
}
func (s *IOStreams) ColorSupport256() bool {
return s.is256enabled
}
func NewIOStreams() *IOStreams {
stdoutIsTTY := isTerminal(os.Stdout)
stderrIsTTY := isTerminal(os.Stderr)
ios := &IOStreams{
In: os.Stdin,
Out: colorable.NewColorable(os.Stdout),
ErrOut: colorable.NewColorable(os.Stderr),
colorEnabled: EnvColorForced() || (!EnvColorDisabled() && stdoutIsTTY),
is256enabled: Is256ColorSupported(),
}
// the colours are not working on windows, let's disable it
if runtime.GOOS == "windows" {
ios.colorEnabled = false
}
if stdoutIsTTY && stderrIsTTY {
ios.progressIndicatorEnabled = true
}
ios.setSurveyColor()
// prevent duplicate isTerminal queries now that we know the answer
ios.SetStdoutTTY(stdoutIsTTY)
ios.SetStderrTTY(stderrIsTTY)
return ios
}
func (s *IOStreams) SetStdoutTTY(isTTY bool) {
s.stdoutTTYOverride = true
s.stdoutIsTTY = isTTY
}
func (s *IOStreams) SetStderrTTY(isTTY bool) {
s.stderrTTYOverride = true
s.stderrIsTTY = isTTY
}
func (s *IOStreams) IsStdoutTTY() bool {
if s.stdoutTTYOverride {
return s.stdoutIsTTY
}
if stdout, ok := s.Out.(*os.File); ok {
return isTerminal(stdout)
}
return false
}
func isTerminal(f *os.File) bool {
return isatty.IsTerminal(f.Fd()) || isatty.IsCygwinTerminal(f.Fd())
}
func IOTest() (*IOStreams, *bytes.Buffer, *bytes.Buffer, *bytes.Buffer) {
in := &bytes.Buffer{}
out := &bytes.Buffer{}
errOut := &bytes.Buffer{}
return &IOStreams{
In: io.NopCloser(in),
Out: out,
ErrOut: errOut,
}, in, out, errOut
}