Skip to content

Commit

Permalink
Define AddHeaders instead of WithOptions pattern
Browse files Browse the repository at this point in the history
Resolves PR feedback
  • Loading branch information
heaths committed Oct 18, 2023
1 parent a0e8288 commit 2427edb
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 24 deletions.
43 changes: 19 additions & 24 deletions pkg/tableprinter/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,15 @@ import (
"github.com/cli/go-gh/v2/pkg/text"
)

type tableOption func(TablePrinter)

type fieldOption func(*tableField)

type TablePrinter interface {
AddHeaders([]string, ...fieldOption)
AddField(string, ...fieldOption)
EndRow()
Render() error
}

func WithHeaders(colorFunc func(string) string, headers ...string) tableOption {
return func(t TablePrinter) {
if tp, ok := t.(*ttyTablePrinter); ok {
tp.hasHeaders = true
for _, header := range headers {
tp.AddField(header, WithColor(colorFunc))
}
tp.EndRow()
}
}
}

// WithTruncate overrides the truncation function for the field. The function should transform a string
// argument into a string that fits within the given display width. The default behavior is to truncate the
// value by adding "..." in the end. Pass nil to disable truncation for this value.
Expand All @@ -54,23 +41,17 @@ func WithColor(fn func(string) string) fieldOption {
// New initializes a table printer with terminal mode and terminal width. When terminal mode is enabled, the
// output will be human-readable, column-formatted to fit available width, and rendered with color support.
// In non-terminal mode, the output is tab-separated and all truncation of values is disabled.
func New(w io.Writer, isTTY bool, maxWidth int, opts ...tableOption) TablePrinter {
var tp TablePrinter
func New(w io.Writer, isTTY bool, maxWidth int) TablePrinter {
if isTTY {
tp = &ttyTablePrinter{
return &ttyTablePrinter{
out: w,
maxWidth: maxWidth,
}
} else {
tp = &tsvTablePrinter{
out: w,
}
}

for _, opt := range opts {
opt(tp)
return &tsvTablePrinter{
out: w,
}
return tp
}

type tableField struct {
Expand All @@ -86,6 +67,18 @@ type ttyTablePrinter struct {
rows [][]tableField
}

func (t *ttyTablePrinter) AddHeaders(headers []string, opts ...fieldOption) {
if t.hasHeaders {
return
}

t.hasHeaders = true
for _, header := range headers {
t.AddField(header, opts...)
}
t.EndRow()
}

func (t *ttyTablePrinter) AddField(s string, opts ...fieldOption) {
if t.rows == nil {
t.rows = make([][]tableField, 1)
Expand Down Expand Up @@ -235,6 +228,8 @@ type tsvTablePrinter struct {
currentCol int
}

func (t *tsvTablePrinter) AddHeaders(_ []string, _ ...fieldOption) {}

func (t *tsvTablePrinter) AddField(text string, opts ...fieldOption) {
if t.currentCol > 0 {
fmt.Fprint(t.out, "\t")
Expand Down
32 changes: 32 additions & 0 deletions pkg/tableprinter/table_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ package tableprinter

import (
"bytes"
"fmt"
"log"
"os"
"testing"

"github.com/MakeNowJust/heredoc"
)

func ExampleTablePrinter() {
Expand Down Expand Up @@ -74,6 +77,35 @@ func Test_ttyTablePrinter_WithTruncate(t *testing.T) {
}
}

func Test_ttyTablePrinter_AddHeaders(t *testing.T) {
buf := bytes.Buffer{}
tp := New(&buf, true, 80)

tp.AddHeaders([]string{"ONE", "TWO", "THREE"}, WithColor(func(s string) string {
return fmt.Sprintf("\x1b[4m%s\x1b[m", s)
}))
tp.AddHeaders([]string{"SHOULD", "NOT", "EXIST"})

tp.AddField("hello")
tp.AddField("beautiful")
tp.AddField("people")
tp.EndRow()

err := tp.Render()
if err != nil {
t.Fatalf("unexpected error: %v", err)
}

// Assert the last column header is padded to support underlines, background styles, etc.
expected := heredoc.Docf(`
%[1]s[4mONE %[1]s[m %[1]s[4mTWO %[1]s[m %[1]s[4mTHREE %[1]s[m
hello beautiful people
`, "\x1b")
if buf.String() != expected {
t.Errorf("expected: %q, got: %q", expected, buf.String())
}
}

func Test_tsvTablePrinter(t *testing.T) {
buf := bytes.Buffer{}
tp := New(&buf, false, 0)
Expand Down

0 comments on commit 2427edb

Please sign in to comment.