Skip to content

Commit

Permalink
bring back error coloring (GoogleContainerTools#5718)
Browse files Browse the repository at this point in the history
* bring back error coloring

* more descriptive error

* treat tput error as not supporting colors

* move string into constants

* address readability feedback

* Update cmd/skaffold/skaffold.go

Co-authored-by: Brian de Alwis <bsd@acm.org>

* log error at debug level

Co-authored-by: Brian de Alwis <bsd@acm.org>
  • Loading branch information
MarlonGamez and briandealwis authored May 4, 2021
1 parent 9a89e8f commit a9a18d8
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 8 deletions.
7 changes: 3 additions & 4 deletions cmd/skaffold/app/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const (
HouseKeepingMessagesAllowedAnnotation = "skaffold_annotation_housekeeping_allowed"
)

func NewSkaffoldCommand(out, err io.Writer) *cobra.Command {
func NewSkaffoldCommand(out, errOut io.Writer) *cobra.Command {
updateMsg := make(chan string, 1)
surveyPrompt := make(chan bool, 1)
metricsPrompt := make(chan bool, 1)
Expand All @@ -75,8 +75,7 @@ func NewSkaffoldCommand(out, err io.Writer) *cobra.Command {

opts.Command = cmd.Use
instrumentation.SetCommand(cmd.Use)

out = color.SetupColors(out, defaultColor, forceColors)
out := color.SetupColors(out, defaultColor, forceColors)
if timestamps {
l := logrus.New()
l.SetOutput(out)
Expand All @@ -88,7 +87,7 @@ func NewSkaffoldCommand(out, err io.Writer) *cobra.Command {
cmd.Root().SetOutput(out)

// Setup logs
if err := setUpLogs(err, v, timestamps); err != nil {
if err := setUpLogs(errOut, v, timestamps); err != nil {
return err
}

Expand Down
6 changes: 5 additions & 1 deletion cmd/skaffold/skaffold.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@ func main() {
if errors.Is(err, context.Canceled) {
logrus.Debugln("ignore error since context is cancelled:", err)
} else {
color.Red.Fprintln(os.Stderr, err)
// As we allow some color setup using CLI flags for the main run, we can't run SetupColors()
// for the entire skaffold run here. It's possible SetupColors() was never called, so call it again
// before we print an error to get the right coloring.
errOut := color.SetupColors(os.Stderr, color.DefaultColorCode, false)
color.Red.Fprintln(errOut, err)
code = exitCode(err)
}
}
Expand Down
8 changes: 7 additions & 1 deletion pkg/skaffold/color/formatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (

colors "github.com/heroku/color"
"github.com/mattn/go-colorable"
"github.com/sirupsen/logrus"

"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util"
)
Expand All @@ -39,7 +40,12 @@ func init() {
// SetupColors conditionally wraps the input `Writer` with a color enabled `Writer`.
func SetupColors(out io.Writer, defaultColor int, forceColors bool) io.Writer {
_, isTerm := util.IsTerminal(out)
useColors := isTerm || forceColors
supportsColor, err := util.SupportsColor()
if err != nil {
logrus.Debugf("error checking for color support: %v", err)
}

useColors := (isTerm && supportsColor) || forceColors
if useColors {
// Use EnableColorsStdout to enable use of color on Windows
useColors = false // value is updated if color-enablement is successful
Expand Down
2 changes: 2 additions & 0 deletions pkg/skaffold/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ const (
LeeroyAppResponse = "leeroooooy app!!\n"

GithubIssueLink = "https://github.com/GoogleContainerTools/skaffold/issues/new"

Windows = "windows"
)

type Phase string
Expand Down
4 changes: 3 additions & 1 deletion pkg/skaffold/util/tar.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import (
"time"

"github.com/sirupsen/logrus"

"github.com/GoogleContainerTools/skaffold/pkg/skaffold/constants"
)

type headerModifier func(*tar.Header)
Expand Down Expand Up @@ -145,7 +147,7 @@ func addFileToTar(root string, src string, dst string, tw *tar.Writer, hm header
}

// Code copied from https://github.com/moby/moby/blob/master/pkg/archive/archive_windows.go
if runtime.GOOS == "windows" {
if runtime.GOOS == constants.Windows {
header.Mode = int64(chmodTarEntry(os.FileMode(header.Mode)))
}
if hm != nil {
Expand Down
3 changes: 2 additions & 1 deletion pkg/skaffold/util/tar_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"testing"
"time"

"github.com/GoogleContainerTools/skaffold/pkg/skaffold/constants"
"github.com/GoogleContainerTools/skaffold/testutil"
)

Expand Down Expand Up @@ -234,7 +235,7 @@ func TestCreateTarWithAbsolutePaths(t *testing.T) {
}

func TestAddFileToTarSymlinks(t *testing.T) {
if runtime.GOOS == "windows" {
if runtime.GOOS == constants.Windows {
t.Skip("creating symlinks requires extra privileges on Windows")
}

Expand Down
26 changes: 26 additions & 0 deletions pkg/skaffold/util/term.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,16 @@ limitations under the License.
package util

import (
"fmt"
"io"
"os/exec"
"runtime"
"strconv"
"strings"

"golang.org/x/term"

"github.com/GoogleContainerTools/skaffold/pkg/skaffold/constants"
)

func IsTerminal(w io.Writer) (uintptr, bool) {
Expand All @@ -35,3 +42,22 @@ func IsTerminal(w io.Writer) (uintptr, bool) {

return 0, false
}

func SupportsColor() (bool, error) {
if runtime.GOOS == constants.Windows {
return true, nil
}

cmd := exec.Command("tput", "colors")
res, err := RunCmdOut(cmd)
if err != nil {
return false, fmt.Errorf("checking terminal colors: %w", err)
}

numColors, err := strconv.Atoi(strings.TrimSpace(string(res)))
if err != nil {
return false, err
}

return numColors > 0, nil
}
51 changes: 51 additions & 0 deletions pkg/skaffold/util/term_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@ package util

import (
"bytes"
"errors"
"runtime"
"testing"

"github.com/GoogleContainerTools/skaffold/pkg/skaffold/constants"
"github.com/GoogleContainerTools/skaffold/testutil"
)

Expand All @@ -31,3 +34,51 @@ func TestIsNotTerminal(t *testing.T) {
testutil.CheckDeepEqual(t, uintptr(0x00), termFd)
testutil.CheckDeepEqual(t, false, isTerm)
}

func TestSupportsColor(t *testing.T) {
tests := []struct {
description string
colorsOutput string
shouldErr bool
expected bool
}{
{
description: "Supports 256 colors",
colorsOutput: "256",
expected: true,
},
{
description: "Supports 0 colors",
colorsOutput: "0",
expected: false,
},
{
description: "tput returns -1",
colorsOutput: "-1",
expected: false,
},
{
description: "cmd run errors",
colorsOutput: "-1",
expected: false,
shouldErr: true,
},
}

for _, test := range tests {
testutil.Run(t, test.description, func(t *testutil.T) {
if test.shouldErr {
t.Override(&DefaultExecCommand, testutil.CmdRunOutErr("tput colors", test.colorsOutput, errors.New("error")))
} else {
t.Override(&DefaultExecCommand, testutil.CmdRunOut("tput colors", test.colorsOutput))
}
if runtime.GOOS == constants.Windows {
test.expected = true
test.shouldErr = false
}

supportsColors, err := SupportsColor()
t.CheckErrorAndDeepEqual(test.shouldErr, err, test.expected, supportsColors)
})
}
}

0 comments on commit a9a18d8

Please sign in to comment.