53 lines
1.7 KiB
Go
53 lines
1.7 KiB
Go
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package main
|
|
|
|
import "strings"
|
|
|
|
const (
|
|
ansiBlue = "\x1b[34m"
|
|
ansiRed = "\x1b[31m"
|
|
ansiReset = "\x1b[0m"
|
|
)
|
|
|
|
// colorEnabled is set by the -color flag in main.
|
|
var colorEnabled bool
|
|
|
|
// label wraps s in dark-blue ANSI when color output is enabled.
|
|
//
|
|
// Tabwriter caveat: tabwriter.Writer counts *bytes* per cell, not
|
|
// rendered columns. ANSI escape codes (`\x1b[34m…\x1b[0m`, 11 bytes)
|
|
// inflate a cell's apparent width without affecting what the terminal
|
|
// draws. Two things follow:
|
|
//
|
|
// 1. Key-value layouts where column 1 is *always* labelled and
|
|
// column 2 is *always* plain (e.g. `show vpp info`) stay aligned,
|
|
// because every row adds the same 11 bytes to column 1.
|
|
// 2. Multi-column tables where only the *header* row is labelled
|
|
// drift: the header cells each carry 11 extra bytes that the data
|
|
// rows don't, so data cells get over-padded. In those tables,
|
|
// leave the header plain (see runShowVPPLBCounters) and only use
|
|
// label() for labels that appear uniformly column-wise.
|
|
func label(s string) string {
|
|
if !colorEnabled {
|
|
return s
|
|
}
|
|
return ansiBlue + s + ansiReset
|
|
}
|
|
|
|
// formatError returns a user-friendly error string. gRPC status errors are
|
|
// unwrapped to show only the server's message (no "rpc error: code = ..."
|
|
// boilerplate). The result is wrapped in red ANSI when color is enabled.
|
|
func formatError(err error) string {
|
|
msg := err.Error()
|
|
// google.golang.org/grpc/status errors format as:
|
|
// rpc error: code = <Code> desc = <message>
|
|
if i := strings.Index(msg, " desc = "); i >= 0 {
|
|
msg = msg[i+len(" desc = "):]
|
|
}
|
|
if colorEnabled {
|
|
return ansiRed + msg + ansiReset
|
|
}
|
|
return msg
|
|
}
|