• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

muesli / termenv / 4378269639

09 Mar 2023 07:57PM UTC coverage: 57.484%. First build
4378269639

push

github

Ayman Bagabas
fix(output): status report ignored when assumeTTY or unsafe is true

27 of 27 new or added lines in 3 files covered. (100.0%)

530 of 922 relevant lines covered (57.48%)

8.82 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

75.0
/output.go
1
package termenv
2

3
import (
4
        "io"
5
        "os"
6
        "sync"
7
)
8

9
var (
10
        // output is the default global output.
11
        output = NewOutput(os.Stdout)
12
)
13

14
// File represents a file descriptor.
15
type File interface {
16
        io.ReadWriter
17
        Fd() uintptr
18
}
19

20
// OutputOption sets an option on Output.
21
type OutputOption = func(*Output)
22

23
// Output is a terminal output.
24
type Output struct {
25
        Profile
26
        tty     io.Writer
27
        environ Environ
28

29
        assumeTTY bool
30
        unsafe    bool
31
        cache     bool
32
        fgSync    *sync.Once
33
        fgColor   Color
34
        bgSync    *sync.Once
35
        bgColor   Color
36
}
37

38
// Environ is an interface for getting environment variables.
39
type Environ interface {
40
        Environ() []string
41
        Getenv(string) string
42
}
43

44
type osEnviron struct{}
45

46
func (oe *osEnviron) Environ() []string {
×
47
        return os.Environ()
×
48
}
×
49

50
func (oe *osEnviron) Getenv(key string) string {
99✔
51
        return os.Getenv(key)
99✔
52
}
99✔
53

54
// DefaultOutput returns the default global output.
55
func DefaultOutput() *Output {
×
56
        return output
×
57
}
×
58

59
// SetDefaultOutput sets the default global output.
60
func SetDefaultOutput(o *Output) {
×
61
        output = o
×
62
}
×
63

64
// NewOutput returns a new Output for the given file descriptor.
65
func NewOutput(tty io.Writer, opts ...OutputOption) *Output {
64✔
66
        o := &Output{
64✔
67
                tty:     tty,
64✔
68
                environ: &osEnviron{},
64✔
69
                Profile: -1,
64✔
70
                fgSync:  &sync.Once{},
64✔
71
                fgColor: NoColor{},
64✔
72
                bgSync:  &sync.Once{},
64✔
73
                bgColor: NoColor{},
64✔
74
        }
64✔
75

64✔
76
        if o.tty == nil {
64✔
77
                o.tty = os.Stdout
×
78
        }
×
79
        for _, opt := range opts {
158✔
80
                opt(o)
94✔
81
        }
94✔
82
        if o.Profile < 0 {
82✔
83
                o.Profile = o.EnvColorProfile()
18✔
84
        }
18✔
85

86
        return o
64✔
87
}
88

89
// WithEnvironment returns a new OutputOption for the given environment.
90
func WithEnvironment(environ Environ) OutputOption {
45✔
91
        return func(o *Output) {
90✔
92
                o.environ = environ
45✔
93
        }
45✔
94
}
95

96
// WithProfile returns a new OutputOption for the given profile.
97
func WithProfile(profile Profile) OutputOption {
46✔
98
        return func(o *Output) {
92✔
99
                o.Profile = profile
46✔
100
        }
46✔
101
}
102

103
// WithColorCache returns a new OutputOption with fore- and background color values
104
// pre-fetched and cached.
105
func WithColorCache(v bool) OutputOption {
1✔
106
        return func(o *Output) {
2✔
107
                o.cache = v
1✔
108

1✔
109
                // cache the values now
1✔
110
                _ = o.ForegroundColor()
1✔
111
                _ = o.BackgroundColor()
1✔
112
        }
1✔
113
}
114

115
// WithTTY returns a new OutputOption to assume whether or not the output is a TTY.
116
// This is useful when mocking console output.
117
func WithTTY(v bool) OutputOption {
2✔
118
        return func(o *Output) {
4✔
119
                o.assumeTTY = v
2✔
120
        }
2✔
121
}
122

123
// WithUnsafe returns a new OutputOption with unsafe mode enabled. Unsafe mode doesn't
124
// check whether or not the terminal is a TTY.
125
//
126
// This option supersedes WithTTY.
127
//
128
// This is useful when mocking console output and enforcing ANSI escape output
129
// e.g. on SSH sessions.
130
func WithUnsafe() OutputOption {
×
131
        return func(o *Output) {
×
132
                o.unsafe = true
×
133
        }
×
134
}
135

136
// ForegroundColor returns the terminal's default foreground color.
137
func (o *Output) ForegroundColor() Color {
4✔
138
        f := func() {
8✔
139
                if !o.isTTY() {
8✔
140
                        return
4✔
141
                }
4✔
142

143
                o.fgColor = o.foregroundColor()
×
144
        }
145

146
        if o.cache {
5✔
147
                o.fgSync.Do(f)
1✔
148
        } else {
4✔
149
                f()
3✔
150
        }
3✔
151

152
        return o.fgColor
4✔
153
}
154

155
// BackgroundColor returns the terminal's default background color.
156
func (o *Output) BackgroundColor() Color {
6✔
157
        f := func() {
12✔
158
                if !o.isTTY() {
12✔
159
                        return
6✔
160
                }
6✔
161

162
                o.bgColor = o.backgroundColor()
×
163
        }
164

165
        if o.cache {
7✔
166
                o.bgSync.Do(f)
1✔
167
        } else {
6✔
168
                f()
5✔
169
        }
5✔
170

171
        return o.bgColor
6✔
172
}
173

174
// HasDarkBackground returns whether terminal uses a dark-ish background.
175
func (o *Output) HasDarkBackground() bool {
2✔
176
        c := ConvertToRGB(o.BackgroundColor())
2✔
177
        _, _, l := c.Hsl()
2✔
178
        return l < 0.5
2✔
179
}
2✔
180

181
// TTY returns the underlying terminal output. This may be nil if the output is
182
// not a terminal.
183
func (o Output) TTY() io.Writer {
×
184
        if o.assumeTTY || o.unsafe {
×
185
                return o.tty
×
186
        }
×
187
        if f, ok := o.tty.(File); ok {
×
188
                return f
×
189
        }
×
190
        return nil
×
191
}
192

193
func (o Output) Write(p []byte) (int, error) {
4✔
194
        return o.tty.Write(p)
4✔
195
}
4✔
196

197
// WriteString writes the given string to the output.
198
func (o Output) WriteString(s string) (int, error) {
1✔
199
        return o.Write([]byte(s))
1✔
200
}
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc