mirror of https://github.com/docker/compose.git
better support NO_COLOR by disabling colors, not ANSI TUI (#10434)
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
parent
90eda35f3d
commit
d762f5f473
|
@ -305,11 +305,13 @@ func RootCommand(streams command.Cli, backend api.Service) *cobra.Command { //no
|
|||
logrus.SetLevel(logrus.TraceLevel)
|
||||
}
|
||||
|
||||
if noColor, ok := os.LookupEnv("NO_COLOR"); ok && noColor != "" && !cmd.Flags().Changed("ansi") {
|
||||
ansi = "never"
|
||||
formatter.SetANSIMode(streams, ansi)
|
||||
|
||||
if noColor, ok := os.LookupEnv("NO_COLOR"); ok && noColor != "" {
|
||||
progress.NoColor()
|
||||
formatter.SetANSIMode(streams, formatter.Never)
|
||||
}
|
||||
|
||||
formatter.SetANSIMode(streams, ansi)
|
||||
switch ansi {
|
||||
case "never":
|
||||
progress.Mode = progress.ModePlain
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
Copyright 2020 Docker Compose CLI authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package progress
|
||||
|
||||
import (
|
||||
"github.com/morikuni/aec"
|
||||
)
|
||||
|
||||
type colorFunc func(string) string
|
||||
|
||||
var (
|
||||
nocolor colorFunc = func(s string) string {
|
||||
return s
|
||||
}
|
||||
|
||||
DoneColor colorFunc = aec.BlueF.Apply
|
||||
TimerColor colorFunc = aec.BlueF.Apply
|
||||
CountColor colorFunc = aec.YellowF.Apply
|
||||
WarningColor colorFunc = aec.YellowF.With(aec.Bold).Apply
|
||||
SuccessColor colorFunc = aec.GreenF.Apply
|
||||
ErrorColor colorFunc = aec.RedF.With(aec.Bold).Apply
|
||||
PrefixColor colorFunc = aec.CyanF.Apply
|
||||
)
|
||||
|
||||
func NoColor() {
|
||||
DoneColor = nocolor
|
||||
TimerColor = nocolor
|
||||
CountColor = nocolor
|
||||
WarningColor = nocolor
|
||||
SuccessColor = nocolor
|
||||
ErrorColor = nocolor
|
||||
PrefixColor = nocolor
|
||||
}
|
|
@ -18,23 +18,21 @@ package progress
|
|||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/morikuni/aec"
|
||||
)
|
||||
|
||||
// EventStatus indicates the status of an action
|
||||
type EventStatus int
|
||||
|
||||
func (s EventStatus) color() aec.ANSI {
|
||||
func (s EventStatus) colorFn() colorFunc {
|
||||
switch s {
|
||||
case Done:
|
||||
return aec.GreenF
|
||||
return SuccessColor
|
||||
case Warning:
|
||||
return aec.YellowF.With(aec.Bold)
|
||||
return WarningColor
|
||||
case Error:
|
||||
return aec.RedF.With(aec.Bold)
|
||||
return ErrorColor
|
||||
default:
|
||||
return aec.DefaultF
|
||||
return nocolor
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,19 +168,19 @@ func (e *Event) stop() {
|
|||
}
|
||||
|
||||
var (
|
||||
spinnerDone = aec.Apply("✔", aec.GreenF)
|
||||
spinnerWarning = aec.Apply("!", aec.YellowF)
|
||||
spinnerError = aec.Apply("✘", aec.RedF)
|
||||
spinnerDone = "✔"
|
||||
spinnerWarning = "!"
|
||||
spinnerError = "✘"
|
||||
)
|
||||
|
||||
func (e *Event) Spinner() any {
|
||||
switch e.Status {
|
||||
case Done:
|
||||
return spinnerDone
|
||||
return SuccessColor(spinnerDone)
|
||||
case Warning:
|
||||
return spinnerWarning
|
||||
return WarningColor(spinnerWarning)
|
||||
case Error:
|
||||
return spinnerError
|
||||
return ErrorColor(spinnerError)
|
||||
default:
|
||||
return e.spinner.String()
|
||||
}
|
||||
|
|
|
@ -151,7 +151,7 @@ func (w *ttyWriter) print() { //nolint:gocyclo
|
|||
|
||||
firstLine := fmt.Sprintf("[+] Running %d/%d", numDone(w.events), w.numLines)
|
||||
if w.numLines != 0 && numDone(w.events) == w.numLines {
|
||||
firstLine = aec.Apply(firstLine, aec.BlueF)
|
||||
firstLine = DoneColor(firstLine)
|
||||
}
|
||||
fmt.Fprintln(w.out, firstLine)
|
||||
|
||||
|
@ -210,7 +210,7 @@ func (w *ttyWriter) lineText(event Event, pad string, terminalWidth, statusPaddi
|
|||
}
|
||||
prefix := ""
|
||||
if dryRun {
|
||||
prefix = aec.Apply(api.DRYRUN_PREFIX, aec.CyanF)
|
||||
prefix = PrefixColor(api.DRYRUN_PREFIX)
|
||||
}
|
||||
|
||||
elapsed := endTime.Sub(event.startTime).Seconds()
|
||||
|
@ -234,8 +234,8 @@ func (w *ttyWriter) lineText(event Event, pad string, terminalWidth, statusPaddi
|
|||
if len(completion) > 0 {
|
||||
txt = fmt.Sprintf("%s %s [%s] %7s/%-7s %s",
|
||||
event.ID,
|
||||
aec.Apply(fmt.Sprintf("%d layers", len(completion)), aec.YellowF),
|
||||
aec.Apply(strings.Join(completion, ""), aec.GreenF, aec.Bold),
|
||||
CountColor(fmt.Sprintf("%d layers", len(completion))),
|
||||
SuccessColor(strings.Join(completion, "")),
|
||||
units.HumanSize(float64(current)), units.HumanSize(float64(total)),
|
||||
event.Text)
|
||||
} else {
|
||||
|
@ -260,10 +260,10 @@ func (w *ttyWriter) lineText(event Event, pad string, terminalWidth, statusPaddi
|
|||
prefix,
|
||||
txt,
|
||||
strings.Repeat(" ", padding),
|
||||
aec.Apply(status, event.Status.color()),
|
||||
event.Status.colorFn()(status),
|
||||
)
|
||||
timer := fmt.Sprintf("%.1fs ", elapsed)
|
||||
o := align(text, aec.Apply(timer, aec.BlueF), terminalWidth)
|
||||
o := align(text, TimerColor(timer), terminalWidth)
|
||||
|
||||
return o
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ func TestLineText(t *testing.T) {
|
|||
lineWidth := len(fmt.Sprintf("%s %s", ev.ID, ev.Text))
|
||||
|
||||
out := tty().lineText(ev, "", 50, lineWidth, false)
|
||||
assert.Equal(t, out, " . id Text \x1b[39mStatus\x1b[0m \x1b[34m0.0s \x1b[0m\n")
|
||||
assert.Equal(t, out, " . id Text Status \x1b[34m0.0s \x1b[0m\n")
|
||||
|
||||
ev.Status = Done
|
||||
out = tty().lineText(ev, "", 50, lineWidth, false)
|
||||
|
@ -50,11 +50,11 @@ func TestLineText(t *testing.T) {
|
|||
|
||||
ev.Status = Error
|
||||
out = tty().lineText(ev, "", 50, lineWidth, false)
|
||||
assert.Equal(t, out, " \x1b[31m✘\x1b[0m id Text \x1b[31m\x1b[1mStatus\x1b[0m \x1b[34m0.0s \x1b[0m\n")
|
||||
assert.Equal(t, out, " \x1b[31m\x1b[1m✘\x1b[0m id Text \x1b[31m\x1b[1mStatus\x1b[0m \x1b[34m0.0s \x1b[0m\n")
|
||||
|
||||
ev.Status = Warning
|
||||
out = tty().lineText(ev, "", 50, lineWidth, false)
|
||||
assert.Equal(t, out, " \x1b[33m!\x1b[0m id Text \x1b[33m\x1b[1mStatus\x1b[0m \x1b[34m0.0s \x1b[0m\n")
|
||||
assert.Equal(t, out, " \x1b[33m\x1b[1m!\x1b[0m id Text \x1b[33m\x1b[1mStatus\x1b[0m \x1b[34m0.0s \x1b[0m\n")
|
||||
}
|
||||
|
||||
func TestLineTextSingleEvent(t *testing.T) {
|
||||
|
|
Loading…
Reference in New Issue