mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
feat: truncate secret value if terminal is too small
This commit is contained in:
@@ -2,8 +2,14 @@ package visualize
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/jedib0t/go-pretty/table"
|
||||
"github.com/mattn/go-isatty"
|
||||
"github.com/muesli/ansi"
|
||||
"github.com/muesli/reflow/truncate"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"golang.org/x/term"
|
||||
)
|
||||
|
||||
type TableOptions struct {
|
||||
@@ -16,8 +22,33 @@ type TableOptions struct {
|
||||
// }
|
||||
// }
|
||||
|
||||
const (
|
||||
// combined width of the table borders and padding
|
||||
borderWidths = 10
|
||||
// char to indicate that a string has been truncated
|
||||
ellipsis = "…"
|
||||
)
|
||||
|
||||
// Given headers and rows, this function will print out a table
|
||||
func Table(headers []string, rows [][]string) {
|
||||
func Table(headers [3]string, rows [][3]string) {
|
||||
// if we're not in a terminal, don't truncate the secret value
|
||||
shouldTruncate := isatty.IsTerminal(os.Stdout.Fd()) || isatty.IsCygwinTerminal(os.Stdout.Fd())
|
||||
|
||||
width, _, err := term.GetSize(int(os.Stdout.Fd()))
|
||||
if err != nil {
|
||||
if shouldTruncate {
|
||||
log.Errorf("error getting terminal size: %s", err)
|
||||
} else {
|
||||
log.Debug(err)
|
||||
}
|
||||
}
|
||||
|
||||
longestSecretName, longestSecretType := getLongestValues(append(rows, headers))
|
||||
availableWidth := width - longestSecretName - longestSecretType - borderWidths
|
||||
if availableWidth < 0 {
|
||||
availableWidth = 0
|
||||
}
|
||||
|
||||
t := table.NewWriter()
|
||||
t.SetOutputMirror(os.Stdout)
|
||||
t.SetStyle(table.StyleLight)
|
||||
@@ -35,7 +66,11 @@ func Table(headers []string, rows [][]string) {
|
||||
t.AppendHeader(tableHeaders)
|
||||
for _, row := range rows {
|
||||
tableRow := table.Row{}
|
||||
for _, val := range row {
|
||||
for i, val := range row {
|
||||
// only truncate the first column (secret value)
|
||||
if i == 1 && stringWidth(val) > availableWidth && shouldTruncate {
|
||||
val = truncate.StringWithTail(val, uint(availableWidth), ellipsis)
|
||||
}
|
||||
tableRow = append(tableRow, val)
|
||||
}
|
||||
t.AppendRow(tableRow)
|
||||
@@ -43,3 +78,28 @@ func Table(headers []string, rows [][]string) {
|
||||
|
||||
t.Render()
|
||||
}
|
||||
|
||||
// getLongestValues returns the length of the longest secret name and type from all rows (including the header).
|
||||
func getLongestValues(rows [][3]string) (longestSecretName, longestSecretType int) {
|
||||
for _, row := range rows {
|
||||
if len(row[0]) > longestSecretName {
|
||||
longestSecretName = stringWidth(row[0])
|
||||
}
|
||||
if len(row[2]) > longestSecretType {
|
||||
longestSecretType = stringWidth(row[2])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// stringWidth returns the width of a string.
|
||||
// ANSI escape sequences are ignored and double-width characters are handled correctly.
|
||||
func stringWidth(str string) (width int) {
|
||||
for _, l := range strings.Split(str, "\n") {
|
||||
w := ansi.PrintableRuneWidth(l)
|
||||
if w > width {
|
||||
width = w
|
||||
}
|
||||
}
|
||||
return width
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user