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

muesli / termenv / 5943573526

22 Aug 2023 08:11PM UTC coverage: 57.655% (-0.2%) from 57.843%
5943573526

Pull #122

github

aymanbagabas
fix(output): export output writer

Termenv output can be a buffer, ssh session, a file, or anything that
implements the io.Writer interface.

In the case of an ssh session, the std ssh library returns a
io.ReadWriter for ssh sessions and the current Termenv implementation
makes it impossible to read terminal status reports since it expects a
file in return.

In addition, the TTY() function is confusing since it implies that the
returned value is a TTY. Which is not always true until we check that
using the isTTY() function.

Deprecate TTY() in favor of Writer() which simply returns the underlying
writer. The caller then can infer the type of the writer and decide what
to do with it.

This also deprecate parts of commit <a class=hub.com/muesli/termenv/commit/669c9abfb65169a7a146968e38702d3d80327a42">669c9abfb https://github.com/muesli/termenv/commit/669c9abfb65169a7a146968e38702d3d80327a42
Pull Request #122: fix(output): export output writer

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

531 of 921 relevant lines covered (57.65%)

8.83 hits per line

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

78.26
/termenv.go
1
package termenv
2

3
import (
4
        "errors"
5
        "os"
6

7
        "github.com/mattn/go-isatty"
8
)
9

10
var (
11
        // ErrStatusReport gets returned when the terminal can't be queried.
12
        ErrStatusReport = errors.New("unable to retrieve status report")
13
)
14

15
const (
16
        // Escape character
17
        ESC = '\x1b'
18
        // Bell
19
        BEL = '\a'
20
        // Control Sequence Introducer
21
        CSI = string(ESC) + "["
22
        // Operating System Command
23
        OSC = string(ESC) + "]"
24
        // String Terminator
25
        ST = string(ESC) + `\`
26
)
27

28
func (o *Output) isTTY() bool {
26✔
29
        if o.assumeTTY || o.unsafe {
28✔
30
                return true
2✔
31
        }
2✔
32
        if len(o.environ.Getenv("CI")) > 0 {
48✔
33
                return false
24✔
34
        }
24✔
35
        if f, ok := o.Writer().(*os.File); ok {
×
36
                return isatty.IsTerminal(f.Fd())
×
37
        }
×
38

39
        return false
×
40
}
41

42
// ColorProfile returns the supported color profile:
43
// Ascii, ANSI, ANSI256, or TrueColor.
44
func ColorProfile() Profile {
1✔
45
        return output.ColorProfile()
1✔
46
}
1✔
47

48
// ForegroundColor returns the terminal's default foreground color.
49
func ForegroundColor() Color {
1✔
50
        return output.ForegroundColor()
1✔
51
}
1✔
52

53
// BackgroundColor returns the terminal's default background color.
54
func BackgroundColor() Color {
1✔
55
        return output.BackgroundColor()
1✔
56
}
1✔
57

58
// HasDarkBackground returns whether terminal uses a dark-ish background.
59
func HasDarkBackground() bool {
2✔
60
        return output.HasDarkBackground()
2✔
61
}
2✔
62

63
// EnvNoColor returns true if the environment variables explicitly disable color output
64
// by setting NO_COLOR (https://no-color.org/)
65
// or CLICOLOR/CLICOLOR_FORCE (https://bixense.com/clicolors/)
66
// If NO_COLOR is set, this will return true, ignoring CLICOLOR/CLICOLOR_FORCE
67
// If CLICOLOR=="0", it will be true only if CLICOLOR_FORCE is also "0" or is unset.
68
func (o *Output) EnvNoColor() bool {
30✔
69
        return o.environ.Getenv("NO_COLOR") != "" || (o.environ.Getenv("CLICOLOR") == "0" && !o.cliColorForced())
30✔
70
}
30✔
71

72
// EnvNoColor returns true if the environment variables explicitly disable color output
73
// by setting NO_COLOR (https://no-color.org/)
74
// or CLICOLOR/CLICOLOR_FORCE (https://bixense.com/clicolors/)
75
// If NO_COLOR is set, this will return true, ignoring CLICOLOR/CLICOLOR_FORCE
76
// If CLICOLOR=="0", it will be true only if CLICOLOR_FORCE is also "0" or is unset.
77
func EnvNoColor() bool {
×
78
        return output.EnvNoColor()
×
79
}
×
80

81
// EnvColorProfile returns the color profile based on environment variables set
82
// Supports NO_COLOR (https://no-color.org/)
83
// and CLICOLOR/CLICOLOR_FORCE (https://bixense.com/clicolors/)
84
// If none of these environment variables are set, this behaves the same as ColorProfile()
85
// It will return the Ascii color profile if EnvNoColor() returns true
86
// If the terminal does not support any colors, but CLICOLOR_FORCE is set and not "0"
87
// then the ANSI color profile will be returned.
88
func EnvColorProfile() Profile {
×
89
        return output.EnvColorProfile()
×
90
}
×
91

92
// EnvColorProfile returns the color profile based on environment variables set
93
// Supports NO_COLOR (https://no-color.org/)
94
// and CLICOLOR/CLICOLOR_FORCE (https://bixense.com/clicolors/)
95
// If none of these environment variables are set, this behaves the same as ColorProfile()
96
// It will return the Ascii color profile if EnvNoColor() returns true
97
// If the terminal does not support any colors, but CLICOLOR_FORCE is set and not "0"
98
// then the ANSI color profile will be returned.
99
func (o *Output) EnvColorProfile() Profile {
18✔
100
        if o.EnvNoColor() {
23✔
101
                return Ascii
5✔
102
        }
5✔
103
        p := o.ColorProfile()
13✔
104
        if o.cliColorForced() && p == Ascii {
16✔
105
                return ANSI
3✔
106
        }
3✔
107
        return p
10✔
108
}
109

110
func (o *Output) cliColorForced() bool {
19✔
111
        if forced := o.environ.Getenv("CLICOLOR_FORCE"); forced != "" {
28✔
112
                return forced != "0"
9✔
113
        }
9✔
114
        return false
10✔
115
}
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