Skip to content

Commit a1093c2

Browse files
author
Cornelius Weig
authored
Merge pull request #9 from corneliusweig/powershell-colors
Explicitly enable color escape sequences on windows
2 parents 0d17fc1 + 20a7f2c commit a1093c2

File tree

4 files changed

+100
-10
lines changed

4 files changed

+100
-10
lines changed

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ require (
1717
github.com/imdario/mergo v0.3.7 // indirect
1818
github.com/inconshreveable/mousetrap v1.0.0 // indirect
1919
github.com/json-iterator/go v1.1.5 // indirect
20+
github.com/konsorten/go-windows-terminal-sequences v1.0.1
2021
github.com/kr/pretty v0.1.0 // indirect
2122
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
2223
github.com/modern-go/reflect2 v1.0.1 // indirect

pkg/rakkess/util/printer.go

+8-10
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,10 @@ package util
1919
import (
2020
"fmt"
2121
"io"
22-
"os"
2322
"strings"
23+
"sync"
2424

2525
"github.com/corneliusweig/rakkess/pkg/rakkess/client"
26-
"golang.org/x/crypto/ssh/terminal"
2726
)
2827

2928
type color int
@@ -35,7 +34,10 @@ const (
3534
none = color(0)
3635
)
3736

38-
var IsTerminal = isTerminal
37+
var (
38+
IsTerminal = isTerminal
39+
terminit sync.Once
40+
)
3941

4042
type OutputFormat int
4143

@@ -44,10 +46,13 @@ const (
4446
ASCIITable OutputFormat = iota
4547
)
4648

49+
// TODO printing logic should be moved to its own package
4750
func PrintResults(out io.Writer, requestedVerbs []string, outputFormat OutputFormat, results []client.Result) {
4851
w := NewWriter(out, 4, 8, 2, ' ', CollapseEscape^StripEscape)
4952
defer w.Flush()
5053

54+
terminit.Do(func() { initTerminal(out) })
55+
5156
fmt.Fprint(w, "NAME")
5257
for _, v := range requestedVerbs {
5358
fmt.Fprintf(w, "\t%s", strings.ToUpper(v))
@@ -86,13 +91,6 @@ func humanreadableAccessCode(code int) string {
8691
}
8792
}
8893

89-
func isTerminal(w io.Writer) bool {
90-
if f, ok := w.(*os.File); ok {
91-
return terminal.IsTerminal(int(f.Fd()))
92-
}
93-
return false
94-
}
95-
9694
func colorHumanreadableAccessCode(code int) string {
9795
return fmt.Sprintf("\xff\033[%dm\xff%s\xff\033[0m\xff", codeToColor(code), humanreadableAccessCode(code))
9896
}
+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// +build !windows
2+
3+
/*
4+
Copyright 2019 Cornelius Weig
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
*/
18+
19+
// NOTICE: This implementation comes from logrus, unfortunately logrus
20+
// does not expose a public interface we can use to call it.
21+
// https://github.com/sirupsen/logrus/blob/master/terminal_check_notappengine.go
22+
// https://github.com/sirupsen/logrus/blob/master/terminal_windows.go
23+
24+
package util
25+
26+
import (
27+
"io"
28+
"os"
29+
30+
"golang.org/x/crypto/ssh/terminal"
31+
)
32+
33+
// initTerminal enables ANSI color escape sequences. On UNIX, they are always enabled.
34+
func initTerminal(_ io.Writer) {
35+
}
36+
37+
func isTerminal(w io.Writer) bool {
38+
if f, ok := w.(*os.File); ok {
39+
return terminal.IsTerminal(int(f.Fd()))
40+
}
41+
return false
42+
}

pkg/rakkess/util/terminal_windows.go

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// +build windows
2+
3+
/*
4+
Copyright 2019 Cornelius Weig
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
*/
18+
19+
// NOTICE: This implementation comes from logrus, unfortunately logrus
20+
// does not expose a public interface we can use to call it.
21+
// https://github.com/sirupsen/logrus/blob/master/terminal_check_notappengine.go
22+
// https://github.com/sirupsen/logrus/blob/master/terminal_windows.go
23+
24+
package util
25+
26+
import (
27+
"io"
28+
"os"
29+
"syscall"
30+
31+
sequences "github.com/konsorten/go-windows-terminal-sequences"
32+
)
33+
34+
// initTerminal enables ANSI color escape on windows. Usually, this is done by logrus, but
35+
// since we don't log anything before printing, we need to take care of this ourselves.
36+
func initTerminal(w io.Writer) {
37+
if f, ok := w.(*os.File); ok {
38+
sequences.EnableVirtualTerminalProcessing(syscall.Handle(f.Fd()), true)
39+
}
40+
}
41+
42+
func isTerminal(w io.Writer) bool {
43+
if f, ok := w.(*os.File); ok {
44+
var mode uint32
45+
err := syscall.GetConsoleMode(syscall.Handle(f.Fd()), &mode)
46+
return err == nil
47+
}
48+
return false
49+
}

0 commit comments

Comments
 (0)