From 3fe5026d39f1cb4dacec3793ef45bbe2f416c987 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Mon, 17 Oct 2022 15:15:39 +0200 Subject: [PATCH] Migrate to tableprinter from go-gh (#6346) --- internal/tableprinter/table_printer.go | 52 ++++++ pkg/cmd/alias/list/list.go | 1 + pkg/cmd/codespace/list.go | 1 + pkg/cmd/codespace/ports.go | 1 + pkg/cmd/extension/command.go | 1 + pkg/cmd/gist/list/list.go | 1 + pkg/cmd/gpg-key/list/list.go | 1 + pkg/cmd/issue/shared/display.go | 1 + pkg/cmd/label/list.go | 1 + pkg/cmd/pr/checks/output.go | 1 + pkg/cmd/pr/list/list.go | 1 + pkg/cmd/release/list/list.go | 22 +-- pkg/cmd/release/list/list_test.go | 9 +- pkg/cmd/release/view/view.go | 1 + pkg/cmd/repo/deploy-key/list/list.go | 1 + pkg/cmd/repo/list/list.go | 1 + pkg/cmd/run/list/list.go | 1 + pkg/cmd/search/repos/repos.go | 1 + pkg/cmd/search/shared/shared.go | 1 + pkg/cmd/secret/list/list.go | 1 + pkg/cmd/ssh-key/list/list.go | 1 + pkg/cmd/status/status.go | 1 + pkg/cmd/workflow/list/list.go | 1 + pkg/cmd/workflow/view/view.go | 1 + utils/table_printer.go | 218 ++++--------------------- utils/table_printer_test.go | 31 ---- 26 files changed, 115 insertions(+), 238 deletions(-) create mode 100644 internal/tableprinter/table_printer.go delete mode 100644 utils/table_printer_test.go diff --git a/internal/tableprinter/table_printer.go b/internal/tableprinter/table_printer.go new file mode 100644 index 000000000..2e8d398eb --- /dev/null +++ b/internal/tableprinter/table_printer.go @@ -0,0 +1,52 @@ +package tableprinter + +import ( + "strings" + "time" + + "github.com/cli/cli/v2/internal/text" + "github.com/cli/cli/v2/pkg/iostreams" + "github.com/cli/go-gh/pkg/tableprinter" +) + +type TablePrinter struct { + tableprinter.TablePrinter + isTTY bool +} + +func (t *TablePrinter) HeaderRow(columns ...string) { + if !t.isTTY { + return + } + for _, col := range columns { + t.AddField(strings.ToUpper(col)) + } + t.EndRow() +} + +func (tp *TablePrinter) AddTimeField(t time.Time, c func(string) string) { + tf := t.Format(time.RFC3339) + if tp.isTTY { + // TODO: use a static time.Now + tf = text.FuzzyAgo(time.Now(), t) + } + tp.AddField(tf, tableprinter.WithColor(c)) +} + +var ( + WithTruncate = tableprinter.WithTruncate + WithColor = tableprinter.WithColor +) + +func New(ios *iostreams.IOStreams) *TablePrinter { + maxWidth := 80 + isTTY := ios.IsStdoutTTY() + if isTTY { + maxWidth = ios.TerminalWidth() + } + tp := tableprinter.New(ios.Out, isTTY, maxWidth) + return &TablePrinter{ + TablePrinter: tp, + isTTY: isTTY, + } +} diff --git a/pkg/cmd/alias/list/list.go b/pkg/cmd/alias/list/list.go index a7ea40ac4..1039759e3 100644 --- a/pkg/cmd/alias/list/list.go +++ b/pkg/cmd/alias/list/list.go @@ -54,6 +54,7 @@ func listRun(opts *ListOptions) error { return cmdutil.NewNoResultsError("no aliases configured") } + //nolint:staticcheck // SA1019: utils.NewTablePrinter is deprecated: use internal/tableprinter tp := utils.NewTablePrinter(opts.IO) keys := []string{} for alias := range aliasMap { diff --git a/pkg/cmd/codespace/list.go b/pkg/cmd/codespace/list.go index 310f1c658..71a869d77 100644 --- a/pkg/cmd/codespace/list.go +++ b/pkg/cmd/codespace/list.go @@ -86,6 +86,7 @@ func (a *App) List(ctx context.Context, opts *listOptions, exporter cmdutil.Expo return cmdutil.NewNoResultsError("no codespaces found") } + //nolint:staticcheck // SA1019: utils.NewTablePrinter is deprecated: use internal/tableprinter tp := utils.NewTablePrinter(a.io) if tp.IsTTY() { tp.AddField("NAME", nil, nil) diff --git a/pkg/cmd/codespace/ports.go b/pkg/cmd/codespace/ports.go index 35d79e8b3..5b55f0c5d 100644 --- a/pkg/cmd/codespace/ports.go +++ b/pkg/cmd/codespace/ports.go @@ -103,6 +103,7 @@ func (a *App) ListPorts(ctx context.Context, codespaceName string, exporter cmdu } cs := a.io.ColorScheme() + //nolint:staticcheck // SA1019: utils.NewTablePrinter is deprecated: use internal/tableprinter tp := utils.NewTablePrinter(a.io) if tp.IsTTY() { diff --git a/pkg/cmd/extension/command.go b/pkg/cmd/extension/command.go index 50112b717..995e4bfd4 100644 --- a/pkg/cmd/extension/command.go +++ b/pkg/cmd/extension/command.go @@ -50,6 +50,7 @@ func NewCmdExtension(f *cmdutil.Factory) *cobra.Command { return cmdutil.NewNoResultsError("no installed extensions found") } cs := io.ColorScheme() + //nolint:staticcheck // SA1019: utils.NewTablePrinter is deprecated: use internal/tableprinter t := utils.NewTablePrinter(io) for _, c := range cmds { var repo string diff --git a/pkg/cmd/gist/list/list.go b/pkg/cmd/gist/list/list.go index bdf936d23..733b0d8f5 100644 --- a/pkg/cmd/gist/list/list.go +++ b/pkg/cmd/gist/list/list.go @@ -95,6 +95,7 @@ func listRun(opts *ListOptions) error { cs := opts.IO.ColorScheme() + //nolint:staticcheck // SA1019: utils.NewTablePrinter is deprecated: use internal/tableprinter tp := utils.NewTablePrinter(opts.IO) for _, gist := range gists { diff --git a/pkg/cmd/gpg-key/list/list.go b/pkg/cmd/gpg-key/list/list.go index 28dfd570e..3a52c64fe 100644 --- a/pkg/cmd/gpg-key/list/list.go +++ b/pkg/cmd/gpg-key/list/list.go @@ -71,6 +71,7 @@ func listRun(opts *ListOptions) error { return cmdutil.NewNoResultsError("no GPG keys present in the GitHub account") } + //nolint:staticcheck // SA1019: utils.NewTablePrinter is deprecated: use internal/tableprinter t := utils.NewTablePrinter(opts.IO) cs := opts.IO.ColorScheme() now := time.Now() diff --git a/pkg/cmd/issue/shared/display.go b/pkg/cmd/issue/shared/display.go index 84b26633a..efb8398ce 100644 --- a/pkg/cmd/issue/shared/display.go +++ b/pkg/cmd/issue/shared/display.go @@ -15,6 +15,7 @@ import ( func PrintIssues(io *iostreams.IOStreams, now time.Time, prefix string, totalCount int, issues []api.Issue) { cs := io.ColorScheme() + //nolint:staticcheck // SA1019: utils.NewTablePrinter is deprecated: use internal/tableprinter table := utils.NewTablePrinter(io) for _, issue := range issues { issueNum := strconv.Itoa(issue.Number) diff --git a/pkg/cmd/label/list.go b/pkg/cmd/label/list.go index 4efec440f..5ad056115 100644 --- a/pkg/cmd/label/list.go +++ b/pkg/cmd/label/list.go @@ -134,6 +134,7 @@ func listRun(opts *listOptions) error { func printLabels(io *iostreams.IOStreams, labels []label) error { cs := io.ColorScheme() + //nolint:staticcheck // SA1019: utils.NewTablePrinter is deprecated: use internal/tableprinter table := utils.NewTablePrinter(io) for _, label := range labels { diff --git a/pkg/cmd/pr/checks/output.go b/pkg/cmd/pr/checks/output.go index d1adb7c54..bf5ecc839 100644 --- a/pkg/cmd/pr/checks/output.go +++ b/pkg/cmd/pr/checks/output.go @@ -76,6 +76,7 @@ func printSummary(io *iostreams.IOStreams, counts checkCounts) { } func printTable(io *iostreams.IOStreams, checks []check) error { + //nolint:staticcheck // SA1019: utils.NewTablePrinter is deprecated: use internal/tableprinter tp := utils.NewTablePrinter(io) sort.Slice(checks, func(i, j int) bool { diff --git a/pkg/cmd/pr/list/list.go b/pkg/cmd/pr/list/list.go index ecf1c4454..a56ac0e5d 100644 --- a/pkg/cmd/pr/list/list.go +++ b/pkg/cmd/pr/list/list.go @@ -198,6 +198,7 @@ func listRun(opts *ListOptions) error { } cs := opts.IO.ColorScheme() + //nolint:staticcheck // SA1019: utils.NewTablePrinter is deprecated: use internal/tableprinter table := utils.NewTablePrinter(opts.IO) for _, pr := range listResult.PullRequests { prNum := strconv.Itoa(pr.Number) diff --git a/pkg/cmd/release/list/list.go b/pkg/cmd/release/list/list.go index ef9f65f94..6d18c80c0 100644 --- a/pkg/cmd/release/list/list.go +++ b/pkg/cmd/release/list/list.go @@ -3,13 +3,12 @@ package list import ( "fmt" "net/http" - "time" "github.com/cli/cli/v2/internal/ghrepo" + "github.com/cli/cli/v2/internal/tableprinter" "github.com/cli/cli/v2/internal/text" "github.com/cli/cli/v2/pkg/cmdutil" "github.com/cli/cli/v2/pkg/iostreams" - "github.com/cli/cli/v2/utils" "github.com/spf13/cobra" ) @@ -76,14 +75,15 @@ func listRun(opts *ListOptions) error { fmt.Fprintf(opts.IO.ErrOut, "failed to start pager: %v\n", err) } - table := utils.NewTablePrinter(opts.IO) + table := tableprinter.New(opts.IO) iofmt := opts.IO.ColorScheme() + table.HeaderRow("Title", "Type", "Tag name", "Published") for _, rel := range releases { title := text.RemoveExcessiveWhitespace(rel.Name) if title == "" { title = rel.TagName } - table.AddField(title, nil, nil) + table.AddField(title) badge := "" var badgeColor func(string) string @@ -97,23 +97,15 @@ func listRun(opts *ListOptions) error { badge = "Pre-release" badgeColor = iofmt.Yellow } - table.AddField(badge, nil, badgeColor) + table.AddField(badge, tableprinter.WithColor(badgeColor)) - tagName := rel.TagName - if table.IsTTY() { - tagName = fmt.Sprintf("(%s)", tagName) - } - table.AddField(tagName, nil, nil) + table.AddField(rel.TagName, tableprinter.WithTruncate(nil)) pubDate := rel.PublishedAt if rel.PublishedAt.IsZero() { pubDate = rel.CreatedAt } - publishedAt := pubDate.Format(time.RFC3339) - if table.IsTTY() { - publishedAt = text.FuzzyAgo(time.Now(), pubDate) - } - table.AddField(publishedAt, nil, iofmt.Gray) + table.AddTimeField(pubDate, iofmt.Gray) table.EndRow() } err = table.Render() diff --git a/pkg/cmd/release/list/list_test.go b/pkg/cmd/release/list/list_test.go index c88185aad..4c4c0868e 100644 --- a/pkg/cmd/release/list/list_test.go +++ b/pkg/cmd/release/list/list_test.go @@ -103,10 +103,11 @@ func Test_listRun(t *testing.T) { LimitResults: 30, }, wantStdout: heredoc.Doc(` - v1.1.0 Draft (v1.1.0) about 1 day ago - The big 1.0 Latest (v1.0.0) about 1 day ago - 1.0 release candidate Pre-release (v1.0.0-pre.2) about 1 day ago - New features (v0.9.2) about 1 day ago + TITLE TYPE TAG NAME PUBLISHED + v1.1.0 Draft v1.1.0 about 1 day ago + The big 1.0 Latest v1.0.0 about 1 day ago + 1.0 release candidate Pre-release v1.0.0-pre.2 about 1 day ago + New features v0.9.2 about 1 day ago `), wantStderr: ``, }, diff --git a/pkg/cmd/release/view/view.go b/pkg/cmd/release/view/view.go index 38cdc6523..b0f130edb 100644 --- a/pkg/cmd/release/view/view.go +++ b/pkg/cmd/release/view/view.go @@ -152,6 +152,7 @@ func renderReleaseTTY(io *iostreams.IOStreams, release *shared.Release) error { if len(release.Assets) > 0 { fmt.Fprintf(w, "%s\n", iofmt.Bold("Assets")) + //nolint:staticcheck // SA1019: utils.NewTablePrinter is deprecated: use internal/tableprinter table := utils.NewTablePrinter(io) for _, a := range release.Assets { table.AddField(a.Name, nil, nil) diff --git a/pkg/cmd/repo/deploy-key/list/list.go b/pkg/cmd/repo/deploy-key/list/list.go index f682582ee..9504b3725 100644 --- a/pkg/cmd/repo/deploy-key/list/list.go +++ b/pkg/cmd/repo/deploy-key/list/list.go @@ -64,6 +64,7 @@ func listRun(opts *ListOptions) error { return cmdutil.NewNoResultsError(fmt.Sprintf("no deploy keys found in %s", ghrepo.FullName(repo))) } + //nolint:staticcheck // SA1019: utils.NewTablePrinter is deprecated: use internal/tableprinter t := utils.NewTablePrinter(opts.IO) cs := opts.IO.ColorScheme() now := time.Now() diff --git a/pkg/cmd/repo/list/list.go b/pkg/cmd/repo/list/list.go index 5a85485b1..a7e21e0ee 100644 --- a/pkg/cmd/repo/list/list.go +++ b/pkg/cmd/repo/list/list.go @@ -164,6 +164,7 @@ func listRun(opts *ListOptions) error { } cs := opts.IO.ColorScheme() + //nolint:staticcheck // SA1019: utils.NewTablePrinter is deprecated: use internal/tableprinter tp := utils.NewTablePrinter(opts.IO) for _, repo := range listResult.Repositories { diff --git a/pkg/cmd/run/list/list.go b/pkg/cmd/run/list/list.go index c68245662..0fe685110 100644 --- a/pkg/cmd/run/list/list.go +++ b/pkg/cmd/run/list/list.go @@ -119,6 +119,7 @@ func listRun(opts *ListOptions) error { return opts.Exporter.Write(opts.IO, runs) } + //nolint:staticcheck // SA1019: utils.NewTablePrinter is deprecated: use internal/tableprinter tp := utils.NewTablePrinter(opts.IO) cs := opts.IO.ColorScheme() diff --git a/pkg/cmd/search/repos/repos.go b/pkg/cmd/search/repos/repos.go index 8cfacf8fa..25c796c37 100644 --- a/pkg/cmd/search/repos/repos.go +++ b/pkg/cmd/search/repos/repos.go @@ -158,6 +158,7 @@ func displayResults(io *iostreams.IOStreams, now time.Time, results search.Repos now = time.Now() } cs := io.ColorScheme() + //nolint:staticcheck // SA1019: utils.NewTablePrinter is deprecated: use internal/tableprinter tp := utils.NewTablePrinter(io) for _, repo := range results.Items { tags := []string{visibilityLabel(repo)} diff --git a/pkg/cmd/search/shared/shared.go b/pkg/cmd/search/shared/shared.go index be163482b..a5cdfe8dc 100644 --- a/pkg/cmd/search/shared/shared.go +++ b/pkg/cmd/search/shared/shared.go @@ -96,6 +96,7 @@ func displayIssueResults(io *iostreams.IOStreams, now time.Time, et EntityType, now = time.Now() } cs := io.ColorScheme() + //nolint:staticcheck // SA1019: utils.NewTablePrinter is deprecated: use internal/tableprinter tp := utils.NewTablePrinter(io) for _, issue := range results.Items { if et == Both { diff --git a/pkg/cmd/secret/list/list.go b/pkg/cmd/secret/list/list.go index a7336570c..4c1a1d01d 100644 --- a/pkg/cmd/secret/list/list.go +++ b/pkg/cmd/secret/list/list.go @@ -146,6 +146,7 @@ func listRun(opts *ListOptions) error { fmt.Fprintf(opts.IO.ErrOut, "failed to start pager: %v\n", err) } + //nolint:staticcheck // SA1019: utils.NewTablePrinter is deprecated: use internal/tableprinter tp := utils.NewTablePrinter(opts.IO) for _, secret := range secrets { tp.AddField(secret.Name, nil, nil) diff --git a/pkg/cmd/ssh-key/list/list.go b/pkg/cmd/ssh-key/list/list.go index 5bde29b9e..376404d42 100644 --- a/pkg/cmd/ssh-key/list/list.go +++ b/pkg/cmd/ssh-key/list/list.go @@ -64,6 +64,7 @@ func listRun(opts *ListOptions) error { return cmdutil.NewNoResultsError("no SSH keys present in the GitHub account") } + //nolint:staticcheck // SA1019: utils.NewTablePrinter is deprecated: use internal/tableprinter t := utils.NewTablePrinter(opts.IO) cs := opts.IO.ColorScheme() now := time.Now() diff --git a/pkg/cmd/status/status.go b/pkg/cmd/status/status.go index 69a53686e..c73db711a 100644 --- a/pkg/cmd/status/status.go +++ b/pkg/cmd/status/status.go @@ -664,6 +664,7 @@ func statusRun(opts *StatusOptions) error { section := func(header string, items []StatusItem, width, rowLimit int) (string, error) { tableOut := &bytes.Buffer{} fmt.Fprintln(tableOut, cs.Bold(header)) + //nolint:staticcheck // SA1019: utils.NewTablePrinterWithOptions is deprecated: use internal/tableprinter tp := utils.NewTablePrinterWithOptions(opts.IO, utils.TablePrinterOptions{ IsTTY: opts.IO.IsStdoutTTY(), MaxWidth: width, diff --git a/pkg/cmd/workflow/list/list.go b/pkg/cmd/workflow/list/list.go index e2c897ab8..a18ebd065 100644 --- a/pkg/cmd/workflow/list/list.go +++ b/pkg/cmd/workflow/list/list.go @@ -92,6 +92,7 @@ func listRun(opts *ListOptions) error { fmt.Fprintf(opts.IO.ErrOut, "failed to start pager: %v\n", err) } + //nolint:staticcheck // SA1019: utils.NewTablePrinter is deprecated: use internal/tableprinter tp := utils.NewTablePrinter(opts.IO) cs := opts.IO.ColorScheme() diff --git a/pkg/cmd/workflow/view/view.go b/pkg/cmd/workflow/view/view.go index 7d087c989..4dc4e7658 100644 --- a/pkg/cmd/workflow/view/view.go +++ b/pkg/cmd/workflow/view/view.go @@ -205,6 +205,7 @@ func viewWorkflowInfo(opts *ViewOptions, client *api.Client, repo ghrepo.Interfa out := opts.IO.Out cs := opts.IO.ColorScheme() + //nolint:staticcheck // SA1019: utils.NewTablePrinter is deprecated: use internal/tableprinter tp := utils.NewTablePrinter(opts.IO) // Header diff --git a/utils/table_printer.go b/utils/table_printer.go index 2ccef943c..e4db98bdc 100644 --- a/utils/table_printer.go +++ b/utils/table_printer.go @@ -1,13 +1,11 @@ package utils import ( - "fmt" "io" - "sort" "strings" - "github.com/cli/cli/v2/internal/text" "github.com/cli/cli/v2/pkg/iostreams" + "github.com/cli/go-gh/pkg/tableprinter" ) type TablePrinter interface { @@ -23,12 +21,14 @@ type TablePrinterOptions struct { Out io.Writer } +// Deprecated: use internal/tableprinter func NewTablePrinter(io *iostreams.IOStreams) TablePrinter { return NewTablePrinterWithOptions(io, TablePrinterOptions{ IsTTY: io.IsStdoutTTY(), }) } +// Deprecated: use internal/tableprinter func NewTablePrinterWithOptions(ios *iostreams.IOStreams, opts TablePrinterOptions) TablePrinter { var out io.Writer if opts.Out != nil { @@ -36,8 +36,8 @@ func NewTablePrinterWithOptions(ios *iostreams.IOStreams, opts TablePrinterOptio } else { out = ios.Out } + var maxWidth int if opts.IsTTY { - var maxWidth int if opts.MaxWidth > 0 { maxWidth = opts.MaxWidth } else if ios.IsStdoutTTY() { @@ -45,205 +45,47 @@ func NewTablePrinterWithOptions(ios *iostreams.IOStreams, opts TablePrinterOptio } else { maxWidth = ios.ProcessTerminalWidth() } - return &ttyTablePrinter{ - out: out, - maxWidth: maxWidth, - } } - return &tsvTablePrinter{ - out: out, + tp := tableprinter.New(out, opts.IsTTY, maxWidth) + return &printer{ + tp: tp, + isTTY: opts.IsTTY, } } -type tableField struct { - Text string - TruncateFunc func(int, string) string - ColorFunc func(string) string +type printer struct { + tp tableprinter.TablePrinter + colIndex int + isTTY bool } -func (f *tableField) DisplayWidth() int { - return text.DisplayWidth(f.Text) +func (p printer) IsTTY() bool { + return p.isTTY } -type ttyTablePrinter struct { - out io.Writer - maxWidth int - rows [][]tableField -} - -func (t ttyTablePrinter) IsTTY() bool { - return true -} - -func (t *ttyTablePrinter) AddField(s string, truncateFunc func(int, string) string, colorFunc func(string) string) { +func (p *printer) AddField(s string, truncateFunc func(int, string) string, colorFunc func(string) string) { if truncateFunc == nil { - truncateFunc = text.Truncate - } - if t.rows == nil { - t.rows = make([][]tableField, 1) - } - rowI := len(t.rows) - 1 - field := tableField{ - Text: s, - TruncateFunc: truncateFunc, - ColorFunc: colorFunc, - } - t.rows[rowI] = append(t.rows[rowI], field) -} - -func (t *ttyTablePrinter) EndRow() { - t.rows = append(t.rows, []tableField{}) -} - -func (t *ttyTablePrinter) Render() error { - if len(t.rows) == 0 { - return nil - } - - delim := " " - numCols := len(t.rows[0]) - colWidths := t.calculateColumnWidths(len(delim)) - - for _, row := range t.rows { - for col, field := range row { - if col > 0 { - _, err := fmt.Fprint(t.out, delim) - if err != nil { - return err - } - } - truncVal := field.TruncateFunc(colWidths[col], field.Text) - if col < numCols-1 { - // pad value with spaces on the right - if padWidth := colWidths[col] - field.DisplayWidth(); padWidth > 0 { - truncVal += strings.Repeat(" ", padWidth) - } - } - if field.ColorFunc != nil { - truncVal = field.ColorFunc(truncVal) - } - _, err := fmt.Fprint(t.out, truncVal) - if err != nil { - return err - } - } - if len(row) > 0 { - _, err := fmt.Fprint(t.out, "\n") - if err != nil { - return err - } + // Disallow ever truncating the 1st colum or any URL value + if p.colIndex == 0 || isURL(s) { + p.tp.AddField(s, tableprinter.WithTruncate(nil), tableprinter.WithColor(colorFunc)) + } else { + p.tp.AddField(s, tableprinter.WithColor(colorFunc)) } + } else { + p.tp.AddField(s, tableprinter.WithTruncate(truncateFunc), tableprinter.WithColor(colorFunc)) } - return nil + p.colIndex++ } -func (t *ttyTablePrinter) calculateColumnWidths(delimSize int) []int { - numCols := len(t.rows[0]) - allColWidths := make([][]int, numCols) - for _, row := range t.rows { - for col, field := range row { - allColWidths[col] = append(allColWidths[col], field.DisplayWidth()) - } - } - - // calculate max & median content width per column - maxColWidths := make([]int, numCols) - // medianColWidth := make([]int, numCols) - for col := 0; col < numCols; col++ { - widths := allColWidths[col] - sort.Ints(widths) - maxColWidths[col] = widths[len(widths)-1] - // medianColWidth[col] = widths[(len(widths)+1)/2] - } - - colWidths := make([]int, numCols) - // never truncate the first column - colWidths[0] = maxColWidths[0] - // never truncate the last column if it contains URLs - if strings.HasPrefix(t.rows[0][numCols-1].Text, "https://") { - colWidths[numCols-1] = maxColWidths[numCols-1] - } - - availWidth := func() int { - setWidths := 0 - for col := 0; col < numCols; col++ { - setWidths += colWidths[col] - } - return t.maxWidth - delimSize*(numCols-1) - setWidths - } - numFixedCols := func() int { - fixedCols := 0 - for col := 0; col < numCols; col++ { - if colWidths[col] > 0 { - fixedCols++ - } - } - return fixedCols - } - - // set the widths of short columns - if w := availWidth(); w > 0 { - if numFlexColumns := numCols - numFixedCols(); numFlexColumns > 0 { - perColumn := w / numFlexColumns - for col := 0; col < numCols; col++ { - if max := maxColWidths[col]; max < perColumn { - colWidths[col] = max - } - } - } - } - - firstFlexCol := -1 - // truncate long columns to the remaining available width - if numFlexColumns := numCols - numFixedCols(); numFlexColumns > 0 { - perColumn := availWidth() / numFlexColumns - for col := 0; col < numCols; col++ { - if colWidths[col] == 0 { - if firstFlexCol == -1 { - firstFlexCol = col - } - if max := maxColWidths[col]; max < perColumn { - colWidths[col] = max - } else if perColumn > 0 { - colWidths[col] = perColumn - } - } - } - } - - // add remainder to the first flex column - if w := availWidth(); w > 0 && firstFlexCol > -1 { - colWidths[firstFlexCol] += w - if max := maxColWidths[firstFlexCol]; max < colWidths[firstFlexCol] { - colWidths[firstFlexCol] = max - } - } - - return colWidths +func (p *printer) EndRow() { + p.tp.EndRow() + p.colIndex = 0 } -type tsvTablePrinter struct { - out io.Writer - currentCol int +func (p *printer) Render() error { + return p.tp.Render() } -func (t tsvTablePrinter) IsTTY() bool { - return false -} - -func (t *tsvTablePrinter) AddField(text string, _ func(int, string) string, _ func(string) string) { - if t.currentCol > 0 { - fmt.Fprint(t.out, "\t") - } - fmt.Fprint(t.out, text) - t.currentCol++ -} - -func (t *tsvTablePrinter) EndRow() { - fmt.Fprint(t.out, "\n") - t.currentCol = 0 -} - -func (t *tsvTablePrinter) Render() error { - return nil +func isURL(s string) bool { + return strings.HasPrefix(s, "https://") || strings.HasPrefix(s, "http://") } diff --git a/utils/table_printer_test.go b/utils/table_printer_test.go deleted file mode 100644 index 2e3e4e803..000000000 --- a/utils/table_printer_test.go +++ /dev/null @@ -1,31 +0,0 @@ -package utils - -import ( - "bytes" - "testing" -) - -func Test_ttyTablePrinter_truncate(t *testing.T) { - buf := bytes.Buffer{} - tp := &ttyTablePrinter{ - out: &buf, - maxWidth: 5, - } - - tp.AddField("1", nil, nil) - tp.AddField("hello", nil, nil) - tp.EndRow() - tp.AddField("2", nil, nil) - tp.AddField("world", nil, nil) - tp.EndRow() - - err := tp.Render() - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - expected := "1 he\n2 wo\n" - if buf.String() != expected { - t.Errorf("expected: %q, got: %q", expected, buf.String()) - } -}