Skip to content

Commit

Permalink
Support $FORCE_COLOR
Browse files Browse the repository at this point in the history
  • Loading branch information
FollowTheProcess committed Aug 26, 2024
1 parent 281df7e commit 34ff4fd
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 15 deletions.
33 changes: 23 additions & 10 deletions internal/colour/colour.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,36 @@ const (
//
// If $NO_COLOR is set, text will be returned unmodified.
func Title(text string) string {
if noColour() {
return text
}
return CodeTitle + text + CodeReset
return sprint(CodeTitle, text)
}

// Bold returns the given text in bold white.
//
// If $NO_COLOR is set, text will be returned unmodified.
func Bold(text string) string {
if noColour() {
return sprint(CodeBold, text)
}

// sprint returns a string with a given colour and the reset code.
//
// It handles checking for NO_COLOR and FORCE_COLOR.
func sprint(code, text string) string {
// TODO(@FollowTheProcess): I don't like checking *every* time but doing it
// via e.g. sync.Once means that tests are annoying unless we ensure env vars are
// set at the process level
noColor := os.Getenv("NO_COLOR") != ""
forceColor := os.Getenv("FORCE_COLOR") != ""

// $FORCE_COLOR overrides $NO_COLOR
if forceColor {
return code + text + CodeReset
}

// $NO_COLOR is next
if noColor {
return text
}
return CodeBold + text + CodeReset
}

// noColour returns whether the $NO_COLOR env var was set.
func noColour() bool {
return os.Getenv("NO_COLOR") != ""
// Normal
return code + text + CodeReset
}
44 changes: 39 additions & 5 deletions internal/colour/colour_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ import (

func TestColour(t *testing.T) {
tests := []struct {
name string // Name of the test case
text string // Text to colour
fn func(text string) string // Printer function to return the coloured version of text
want string // Expected result containing ANSI escape codes
noColor bool // Whether to set the $NO_COLOR env var
name string // Name of the test case
text string // Text to colour
fn func(text string) string // Printer function to return the coloured version of text
want string // Expected result containing ANSI escape codes
noColor bool // Whether to set the $NO_COLOR env var
forceColor bool // Whether to set the $FORCE_COLOR env var
}{
{
name: "bold",
Expand All @@ -28,6 +29,21 @@ func TestColour(t *testing.T) {
noColor: true,
want: "hello bold",
},
{
name: "bold force color",
text: "hello bold",
fn: colour.Bold,
want: colour.CodeBold + "hello bold" + colour.CodeReset,
forceColor: true,
},
{
name: "bold force color and no color",
text: "hello bold",
fn: colour.Bold,
want: colour.CodeBold + "hello bold" + colour.CodeReset,
forceColor: true, // force should override no
noColor: true,
},
{
name: "title",
text: "Section",
Expand All @@ -41,13 +57,31 @@ func TestColour(t *testing.T) {
noColor: true,
want: "Section",
},
{
name: "title force color",
text: "Section",
fn: colour.Title,
want: colour.CodeTitle + "Section" + colour.CodeReset,
forceColor: true,
},
{
name: "title force color and no color",
text: "Section",
fn: colour.Title,
want: colour.CodeTitle + "Section" + colour.CodeReset,
forceColor: true, // force should override no
noColor: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.noColor {
t.Setenv("NO_COLOR", "true")
}
if tt.forceColor {
t.Setenv("FORCE_COLOR", "true")
}
got := tt.fn(tt.text)
test.Equal(t, got, tt.want)
})
Expand Down

0 comments on commit 34ff4fd

Please sign in to comment.