Skip to content

Commit 2cfd9df

Browse files
authored
Merge pull request #6654 from vvoland/img-list-nocolor
image/tree: Respect NO_COLOR env variable
2 parents 88e3241 + be9e630 commit 2cfd9df

File tree

5 files changed

+46
-15
lines changed

5 files changed

+46
-15
lines changed

cli/command/image/tree.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ func printImageTree(outs command.Streams, view treeView) {
292292
Width: func() int {
293293
maxChipsWidth := 0
294294
for _, chip := range possibleChips {
295-
s := chip.String(isTerm)
295+
s := out.Sprint(chip)
296296
l := tui.Width(s)
297297
maxChipsWidth += l
298298
}
@@ -308,9 +308,9 @@ func printImageTree(outs command.Streams, view treeView) {
308308
var b strings.Builder
309309
for _, chip := range possibleChips {
310310
if chip.check(d) {
311-
b.WriteString(chip.String(isTerm))
311+
b.WriteString(out.Sprint(chip))
312312
} else {
313-
b.WriteString(chipPlaceholder.String(isTerm))
313+
b.WriteString(out.Sprint(chipPlaceholder))
314314
}
315315
}
316316
return b.String()

cli/command/image/tree_test.go

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ func TestPrintImageTreeAnsiTty(t *testing.T) {
1515
stdoutTty bool
1616
stderrTty bool
1717
expectedAnsi bool
18+
noColorEnv bool
1819
}{
1920
{
2021
name: "non-terminal",
@@ -80,6 +81,24 @@ func TestPrintImageTreeAnsiTty(t *testing.T) {
8081

8182
expectedAnsi: false,
8283
},
84+
{
85+
name: "no-color-env",
86+
stdinTty: false,
87+
stdoutTty: false,
88+
stderrTty: false,
89+
90+
noColorEnv: true,
91+
expectedAnsi: false,
92+
},
93+
{
94+
name: "no-color-env-terminal",
95+
stdinTty: true,
96+
stdoutTty: true,
97+
stderrTty: true,
98+
99+
noColorEnv: true,
100+
expectedAnsi: false,
101+
},
83102
}
84103

85104
mockView := treeView{
@@ -115,6 +134,11 @@ func TestPrintImageTreeAnsiTty(t *testing.T) {
115134
cli.In().SetIsTerminal(tc.stdinTty)
116135
cli.Out().SetIsTerminal(tc.stdoutTty)
117136
cli.Err().SetIsTerminal(tc.stderrTty)
137+
if tc.noColorEnv {
138+
t.Setenv("NO_COLOR", "1")
139+
} else {
140+
t.Setenv("NO_COLOR", "")
141+
}
118142

119143
printImageTree(cli, mockView)
120144

@@ -123,9 +147,9 @@ func TestPrintImageTreeAnsiTty(t *testing.T) {
123147

124148
hasAnsi := strings.Contains(out, "\x1b[")
125149
if tc.expectedAnsi {
126-
assert.Check(t, hasAnsi, "Output should contain ANSI escape codes")
150+
assert.Check(t, hasAnsi, "Output should contain ANSI escape codes, output: %s", out)
127151
} else {
128-
assert.Check(t, !hasAnsi, "Output should not contain ANSI escape codes")
152+
assert.Check(t, !hasAnsi, "Output should not contain ANSI escape codes, output: %s", out)
129153
}
130154
})
131155
}

docs/reference/commandline/docker.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ line:
130130
| `DOCKER_TLS` | Enable TLS for connections made by the `docker` CLI (equivalent of the `--tls` command-line option). Set to a non-empty value to enable TLS. Note that TLS is enabled automatically if any of the other TLS options are set. |
131131
| `DOCKER_TLS_VERIFY` | When set Docker uses TLS and verifies the remote. This variable is used both by the `docker` CLI and the [`dockerd` daemon](https://docs.docker.com/reference/cli/dockerd/) |
132132
| `BUILDKIT_PROGRESS` | Set type of progress output (`auto`, `plain`, `tty`, `rawjson`) when [building](https://docs.docker.com/reference/cli/docker/image/build/) with [BuildKit backend](https://docs.docker.com/build/buildkit/). Use plain to show container output (default `auto`). |
133+
| `NO_COLOR` | Disable any ANSI escape codes in the output in accordance with https://no-color.org/
134+
|
133135

134136
Because Docker is developed using Go, you can also use any environment
135137
variables used by the Go runtime. In particular, you may find these useful:

internal/tui/note.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ func withHeader(header Str) noteOptions {
2828
}
2929

3030
func (o Output) printNoteWithOptions(format string, args []any, opts ...noteOptions) {
31-
if o.isTerminal {
31+
if !o.noColor {
3232
// TODO: Handle all flags
3333
format = strings.ReplaceAll(format, "--platform", ColorFlag.Apply("--platform"))
3434
}
@@ -51,7 +51,7 @@ func (o Output) printNoteWithOptions(format string, args []any, opts ...noteOpti
5151
}
5252

5353
l := line
54-
if o.isTerminal {
54+
if !o.noColor {
5555
l = aec.Italic.Apply(l)
5656
}
5757
_, _ = fmt.Fprintln(o, l)

internal/tui/output.go

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,39 +5,44 @@ package tui
55

66
import (
77
"fmt"
8+
"os"
89

910
"github.com/docker/cli/cli/streams"
1011
"github.com/morikuni/aec"
1112
)
1213

1314
type Output struct {
1415
*streams.Out
15-
isTerminal bool
16+
noColor bool
1617
}
1718

1819
type terminalPrintable interface {
1920
String(isTerminal bool) string
2021
}
2122

2223
func NewOutput(out *streams.Out) Output {
24+
noColor := !out.IsTerminal()
25+
if os.Getenv("NO_COLOR") != "" {
26+
noColor = true
27+
}
2328
return Output{
24-
Out: out,
25-
isTerminal: out.IsTerminal(),
29+
Out: out,
30+
noColor: noColor,
2631
}
2732
}
2833

2934
func (o Output) Color(clr aec.ANSI) aec.ANSI {
30-
if o.isTerminal {
31-
return clr
35+
if o.noColor {
36+
return ColorNone
3237
}
33-
return ColorNone
38+
return clr
3439
}
3540

3641
func (o Output) Sprint(all ...any) string {
3742
var out []any
3843
for _, p := range all {
3944
if s, ok := p.(terminalPrintable); ok {
40-
out = append(out, s.String(o.isTerminal))
45+
out = append(out, s.String(!o.noColor))
4146
} else {
4247
out = append(out, p)
4348
}
@@ -47,7 +52,7 @@ func (o Output) Sprint(all ...any) string {
4752

4853
func (o Output) PrintlnWithColor(clr aec.ANSI, args ...any) {
4954
msg := o.Sprint(args...)
50-
if o.isTerminal {
55+
if !o.noColor {
5156
msg = clr.Apply(msg)
5257
}
5358
_, _ = fmt.Fprintln(o.Out, msg)

0 commit comments

Comments
 (0)