Skip to content

Commit d6eadd8

Browse files
committed
Fix colors for Windows!
1 parent 92eb52d commit d6eadd8

File tree

4 files changed

+71
-5
lines changed

4 files changed

+71
-5
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//go:build !windows
2+
3+
package logger
4+
5+
import (
6+
"io"
7+
"os"
8+
)
9+
10+
func detectColorSupport(w io.Writer) bool {
11+
f, ok := w.(*os.File)
12+
if !ok {
13+
return false
14+
}
15+
16+
info, err := f.Stat()
17+
if err != nil {
18+
return false
19+
}
20+
21+
return (info.Mode() & os.ModeCharDevice) != 0
22+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//go:build windows
2+
3+
package logger
4+
5+
import (
6+
"io"
7+
"os"
8+
9+
"golang.org/x/sys/windows"
10+
)
11+
12+
const enableVirtualTerminalProcessing = 0x0004
13+
14+
func detectColorSupport(w io.Writer) bool {
15+
f, ok := w.(*os.File)
16+
if !ok {
17+
return false
18+
}
19+
20+
handle := windows.Handle(f.Fd())
21+
var mode uint32
22+
if err := windows.GetConsoleMode(handle, &mode); err != nil {
23+
return false
24+
}
25+
26+
if mode&enableVirtualTerminalProcessing != 0 {
27+
return true
28+
}
29+
30+
return windows.SetConsoleMode(handle, mode|enableVirtualTerminalProcessing) == nil
31+
}

internal/logger/logger.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -215,11 +215,7 @@ func shouldUseColor() bool {
215215
if strings.TrimSpace(os.Getenv("FORCE_COLOR")) != "" {
216216
return true
217217
}
218-
info, err := os.Stdout.Stat()
219-
if err != nil {
220-
return false
221-
}
222-
return (info.Mode() & os.ModeCharDevice) != 0
218+
return detectColorSupport(os.Stdout)
223219
}
224220

225221
func renderColorTags(text string) string {

internal/logger/logger_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ package logger
99

1010
import (
1111
"bytes"
12+
"os"
1213
"strings"
1314
"testing"
1415
)
@@ -76,3 +77,19 @@ func TestLoggerSuppressesBelowLevel(t *testing.T) {
7677
t.Fatal("warn message should be logged at WARN level")
7778
}
7879
}
80+
81+
func TestShouldUseColorHonorsNoColor(t *testing.T) {
82+
oldNoColor := os.Getenv("NO_COLOR")
83+
oldForceColor := os.Getenv("FORCE_COLOR")
84+
t.Cleanup(func() {
85+
_ = os.Setenv("NO_COLOR", oldNoColor)
86+
_ = os.Setenv("FORCE_COLOR", oldForceColor)
87+
})
88+
89+
_ = os.Setenv("FORCE_COLOR", "1")
90+
_ = os.Setenv("NO_COLOR", "1")
91+
92+
if shouldUseColor() {
93+
t.Fatal("NO_COLOR should disable colors even when FORCE_COLOR is set")
94+
}
95+
}

0 commit comments

Comments
 (0)