Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions 17 internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
const (
aliasesKey = "aliases"
browserKey = "browser"
colorLabelsKey = "color_labels"
editorKey = "editor"
gitProtocolKey = "git_protocol"
hostsKey = "hosts"
Expand Down Expand Up @@ -113,6 +114,11 @@ func (c *cfg) Browser(hostname string) gh.ConfigEntry {
return c.GetOrDefault(hostname, browserKey).Unwrap()
}

func (c *cfg) ColorLabels(hostname string) gh.ConfigEntry {
// Intentionally panic if there is no user provided value or default value (which would be a programmer error)
return c.GetOrDefault(hostname, colorLabelsKey).Unwrap()
}

func (c *cfg) Editor(hostname string) gh.ConfigEntry {
// Intentionally panic if there is no user provided value or default value (which would be a programmer error)
return c.GetOrDefault(hostname, editorKey).Unwrap()
Expand Down Expand Up @@ -532,6 +538,8 @@ aliases:
http_unix_socket:
# What web browser gh should use when opening URLs. If blank, will refer to environment.
browser:
# Whether to display labels using their RGB hex color codes in terminals that support truecolor. Supported values: enabled, disabled
color_labels: disabled
`

type ConfigOption struct {
Expand Down Expand Up @@ -602,6 +610,15 @@ var Options = []ConfigOption{
return c.Browser(hostname).Value
},
},
{
Key: colorLabelsKey,
Description: "whether to display labels using their RGB hex color codes in terminals that support truecolor",
DefaultValue: "disabled",
AllowedValues: []string{"enabled", "disabled"},
CurrentValue: func(c gh.Config, hostname string) string {
return c.ColorLabels(hostname).Value
},
},
}

func HomeDirPath(subdir string) (string, error) {
Expand Down
2 changes: 2 additions & 0 deletions 2 internal/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ func TestNewConfigProvidesFallback(t *testing.T) {
requireKeyWithValue(t, spiedCfg, []string{aliasesKey, "co"}, "pr checkout")
requireKeyWithValue(t, spiedCfg, []string{httpUnixSocketKey}, "")
requireKeyWithValue(t, spiedCfg, []string{browserKey}, "")
requireKeyWithValue(t, spiedCfg, []string{colorLabelsKey}, "disabled")
}

func TestGetOrDefaultApplicationDefaults(t *testing.T) {
Expand Down Expand Up @@ -137,6 +138,7 @@ func TestFallbackConfig(t *testing.T) {
requireKeyWithValue(t, cfg, []string{aliasesKey, "co"}, "pr checkout")
requireKeyWithValue(t, cfg, []string{httpUnixSocketKey}, "")
requireKeyWithValue(t, cfg, []string{browserKey}, "")
requireKeyWithValue(t, cfg, []string{colorLabelsKey}, "disabled")
requireNoKey(t, cfg, []string{"unknown"})
}

Expand Down
3 changes: 3 additions & 0 deletions 3 internal/config/stub.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ func NewFromString(cfgStr string) *ghmock.ConfigMock {
mock.BrowserFunc = func(hostname string) gh.ConfigEntry {
return cfg.Browser(hostname)
}
mock.ColorLabelsFunc = func(hostname string) gh.ConfigEntry {
return cfg.ColorLabels(hostname)
}
mock.EditorFunc = func(hostname string) gh.ConfigEntry {
return cfg.Editor(hostname)
}
Expand Down
2 changes: 2 additions & 0 deletions 2 internal/gh/gh.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ type Config interface {

// Browser returns the configured browser, optionally scoped by host.
Browser(hostname string) ConfigEntry
// ColorLabels returns the configured color_label setting, optionally scoped by host.
ColorLabels(hostname string) ConfigEntry
// Editor returns the configured editor, optionally scoped by host.
Editor(hostname string) ConfigEntry
// GitProtocol returns the configured git protocol, optionally scoped by host.
Expand Down
44 changes: 44 additions & 0 deletions 44 internal/gh/mock/config.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion 2 internal/tableprinter/table_printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func NewWithWriter(w io.Writer, isTTY bool, maxWidth int, cs *iostreams.ColorSch
// was not padded. In tests cs.Enabled() is false which allows us to avoid having to fix up
// numerous tests that verify header padding.
var paddingFunc func(int, string) string
if cs.Enabled() {
if cs.Enabled {
paddingFunc = text.PadRight
}

Expand Down
19 changes: 11 additions & 8 deletions 19 pkg/cmd/config/list/list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"testing"

"github.com/MakeNowJust/heredoc"
"github.com/cli/cli/v2/internal/config"
"github.com/cli/cli/v2/internal/gh"
"github.com/cli/cli/v2/pkg/cmdutil"
Expand Down Expand Up @@ -91,14 +92,16 @@ func Test_listRun(t *testing.T) {
return cfg
}(),
input: &ListOptions{Hostname: "HOST"},
stdout: `git_protocol=ssh
editor=/usr/bin/vim
prompt=disabled
prefer_editor_prompt=enabled
pager=less
http_unix_socket=
browser=brave
`,
stdout: heredoc.Doc(`
git_protocol=ssh
editor=/usr/bin/vim
prompt=disabled
prefer_editor_prompt=enabled
pager=less
http_unix_socket=
browser=brave
color_labels=disabled
`),
},
}

Expand Down
11 changes: 11 additions & 0 deletions 11 pkg/cmd/factory/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,17 @@ func ioStreams(f *cmdutil.Factory) *iostreams.IOStreams {
io.SetPager(pager.Value)
}

if ghColorLabels, ghColorLabelsExists := os.LookupEnv("GH_COLOR_LABELS"); ghColorLabelsExists {
switch ghColorLabels {
case "", "0", "false", "no":
io.SetColorLabels(false)
default:
io.SetColorLabels(true)
}
} else if prompt := cfg.ColorLabels(""); prompt.Value == "enabled" {
io.SetColorLabels(true)
}

io.SetAccessibleColorsEnabled(xcolor.IsAccessibleColorsEnabled())

return io
Expand Down
86 changes: 86 additions & 0 deletions 86 pkg/cmd/factory/default_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,84 @@ func Test_ioStreams_prompt(t *testing.T) {
}
}

func Test_ioStreams_colorLabels(t *testing.T) {
tests := []struct {
name string
config gh.Config
colorLabelsEnabled bool
env map[string]string
}{
{
name: "default config",
colorLabelsEnabled: false,
},
{
name: "config with colorLabels enabled",
config: enableColorLabelsConfig(),
colorLabelsEnabled: true,
},
{
name: "config with colorLabels disabled",
config: disableColorLabelsConfig(),
colorLabelsEnabled: false,
},
{
name: "colorLabels enabled via `1` in GH_COLOR_LABELS env var",
env: map[string]string{"GH_COLOR_LABELS": "1"},
colorLabelsEnabled: true,
},
{
name: "colorLabels enabled via `true` in GH_COLOR_LABELS env var",
env: map[string]string{"GH_COLOR_LABELS": "true"},
colorLabelsEnabled: true,
},
{
name: "colorLabels enabled via `yes` in GH_COLOR_LABELS env var",
env: map[string]string{"GH_COLOR_LABELS": "yes"},
colorLabelsEnabled: true,
},
{
name: "colorLabels disable via empty string in GH_COLOR_LABELS env var",
env: map[string]string{"GH_COLOR_LABELS": ""},
colorLabelsEnabled: false,
},
{
name: "colorLabels disabled via `0` in GH_COLOR_LABELS env var",
env: map[string]string{"GH_COLOR_LABELS": "0"},
colorLabelsEnabled: false,
},
{
name: "colorLabels disabled via `false` in GH_COLOR_LABELS env var",
env: map[string]string{"GH_COLOR_LABELS": "false"},
colorLabelsEnabled: false,
},
{
name: "colorLabels disabled via `no` in GH_COLOR_LABELS env var",
env: map[string]string{"GH_COLOR_LABELS": "no"},
colorLabelsEnabled: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.env != nil {
for k, v := range tt.env {
t.Setenv(k, v)
}
}
f := New("1")
f.Config = func() (gh.Config, error) {
if tt.config == nil {
return config.NewBlankConfig(), nil
} else {
return tt.config, nil
}
}
io := ioStreams(f)
assert.Equal(t, tt.colorLabelsEnabled, io.ColorLabels())
})
}
}

func TestSSOURL(t *testing.T) {
tests := []struct {
name string
Expand Down Expand Up @@ -537,3 +615,11 @@ func pagerConfig() gh.Config {
func disablePromptConfig() gh.Config {
return config.NewFromString("prompt: disabled")
}

func disableColorLabelsConfig() gh.Config {
return config.NewFromString("color_labels: disabled")
}

func enableColorLabelsConfig() gh.Config {
return config.NewFromString("color_labels: enabled")
}
27 changes: 17 additions & 10 deletions 27 pkg/cmd/gist/list/list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -654,50 +654,57 @@ func Test_highlightMatch(t *testing.T) {
tests := []struct {
name string
input string
color bool
cs *iostreams.ColorScheme
want string
}{
{
name: "single match",
input: "Octo",
cs: &iostreams.ColorScheme{},
want: "Octo",
},
{
name: "single match (color)",
input: "Octo",
color: true,
want: "\x1b[0;30;43mOcto\x1b[0m",
cs: &iostreams.ColorScheme{
Enabled: true,
},
want: "\x1b[0;30;43mOcto\x1b[0m",
},
{
name: "single match with extra",
input: "Hello, Octocat!",
cs: &iostreams.ColorScheme{},
want: "Hello, Octocat!",
},
{
name: "single match with extra (color)",
input: "Hello, Octocat!",
color: true,
want: "\x1b[0;34mHello, \x1b[0m\x1b[0;30;43mOcto\x1b[0m\x1b[0;34mcat!\x1b[0m",
cs: &iostreams.ColorScheme{
Enabled: true,
},
want: "\x1b[0;34mHello, \x1b[0m\x1b[0;30;43mOcto\x1b[0m\x1b[0;34mcat!\x1b[0m",
},
{
name: "multiple matches",
input: "Octocat/octo",
cs: &iostreams.ColorScheme{},
want: "Octocat/octo",
},
{
name: "multiple matches (color)",
input: "Octocat/octo",
color: true,
want: "\x1b[0;30;43mOcto\x1b[0m\x1b[0;34mcat/\x1b[0m\x1b[0;30;43mocto\x1b[0m",
cs: &iostreams.ColorScheme{
Enabled: true,
},
want: "\x1b[0;30;43mOcto\x1b[0m\x1b[0;34mcat/\x1b[0m\x1b[0;30;43mocto\x1b[0m",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cs := iostreams.NewColorScheme(tt.color, false, false, false, iostreams.NoTheme)

matched := false
got, err := highlightMatch(tt.input, regex, &matched, cs.Blue, cs.Highlight)
got, err := highlightMatch(tt.input, regex, &matched, tt.cs.Blue, tt.cs.Highlight)
assert.NoError(t, err)
assert.True(t, matched)
assert.Equal(t, tt.want, got)
Expand Down
2 changes: 1 addition & 1 deletion 2 pkg/cmd/issue/shared/display.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func issueLabelList(issue *api.Issue, cs *iostreams.ColorScheme, colorize bool)
labelNames := make([]string, 0, len(issue.Labels.Nodes))
for _, label := range issue.Labels.Nodes {
if colorize {
labelNames = append(labelNames, cs.HexToRGB(label.Color, label.Name))
labelNames = append(labelNames, cs.Label(label.Color, label.Name))
} else {
labelNames = append(labelNames, label.Name)
}
Expand Down
Loading
Morty Proxy This is a proxified and sanitized view of the page, visit original site.