From bf7e4707109cd187e7a389c5ddf845e209c0a3f1 Mon Sep 17 00:00:00 2001 From: "M. J. Fromberger" Date: Thu, 1 Oct 2026 19:55:09 -0700 Subject: [PATCH] cmd/setec: make the output of "list" nicer for many versions When a secret has a large number of versions, the output of "list" can be hard to read in the default columnar format. To make it nicer, truncate the width to a "reasonable" amount of most-recent versions. To ensure the caller can still get the full output if needed, add a --json flag so that the caller can still get the full, unclipped value. Apply this flag to the "get" and "info" commands too, for symmetry. --- cmd/setec/setec.go | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/cmd/setec/setec.go b/cmd/setec/setec.go index a1fc717..627fc47 100644 --- a/cmd/setec/setec.go +++ b/cmd/setec/setec.go @@ -11,6 +11,7 @@ import ( "bytes" "context" "crypto/sha256" + "encoding/json" "errors" "expvar" "fmt" @@ -192,6 +193,7 @@ var serverArgs struct { var clientArgs struct { Server string `flag:"s,default=$SETEC_SERVER,Server address"` + JSON bool `flag:"json,Write output in JSON format"` } func runServer(env *command.Env) error { @@ -361,6 +363,13 @@ func runList(env *command.Env) error { if err != nil { return fmt.Errorf("failed to list secrets: %v", err) } + if clientArgs.JSON { + enc := json.NewEncoder(os.Stdout) + for _, s := range secrets { + enc.Encode(s) + } + return nil + } tw := newTabWriter(os.Stdout) io.WriteString(tw, "NAME\tACTIVE\tVERSIONS\tLAST ACCESSED\n") @@ -373,11 +382,24 @@ func runList(env *command.Env) error { if !s.LastAccess.IsZero() { lastAccess = s.LastAccess.Format(time.RFC3339) } - fmt.Fprintf(tw, "%s\t%s\t%s\t%s\n", s.Name, s.ActiveVersion, strings.Join(vers, ","), lastAccess) + fmt.Fprintf(tw, "%s\t%s\t%s\t%s\n", s.Name, s.ActiveVersion, formatVersions(vers), lastAccess) } return tw.Flush() } +func formatVersions(vs []string) string { + i, n := len(vs)-1, 0 + for i > 0 && n < 50 { + n += len(vs[i]) + 1 + i-- + } + s := strings.Join(vs[i:], ",") + if i > 0 { + return "...," + s + } + return s +} + func runInfo(env *command.Env, name string) error { c, err := newClient() if err != nil { @@ -388,6 +410,9 @@ func runInfo(env *command.Env, name string) error { if err != nil { return fmt.Errorf("failed to get secret info: %v", err) } + if clientArgs.JSON { + return json.NewEncoder(os.Stdout).Encode(info) + } vers := make([]string, 0, len(info.Versions)) for _, v := range info.Versions { vers = append(vers, v.String()) @@ -425,6 +450,10 @@ func runGet(env *command.Env, name string) error { return fmt.Errorf("failed to get secret: %v", err) } + if clientArgs.JSON { + return json.NewEncoder(os.Stdout).Encode(val) + } + // Print with a newline if a human's going to look at it, // otherwise output just the secret bytes. if term.IsTerminal(int(os.Stdout.Fd())) {