github.com/chenbh/concourse/v6@v6.4.2/fly/ui/table.go (about) 1 package ui 2 3 import ( 4 "bufio" 5 "fmt" 6 "io" 7 "strings" 8 9 "github.com/fatih/color" 10 ) 11 12 type Table struct { 13 Headers TableRow 14 Data Data 15 } 16 17 type Data []TableRow 18 19 type TableRow []TableCell 20 21 type TableCell struct { 22 Contents string 23 Color *color.Color 24 } 25 26 func (d Data) Len() int { return len(d) } 27 func (d Data) Swap(i int, j int) { d[i], d[j] = d[j], d[i] } 28 29 func (d Data) Less(i int, j int) bool { 30 return d[i][0].Contents < d[j][0].Contents 31 } 32 33 func (table Table) Render(dst io.Writer, isPrintHeader bool) error { 34 dst, isTTY := ForTTY(dst) 35 bdst := bufio.NewWriter(dst) 36 defer bdst.Flush() 37 38 columnWidths := map[int]int{} 39 40 if isPrintHeader || isTTY { 41 for i, column := range table.Headers { 42 columnWidth := len(column.Contents) 43 44 if columnWidth > columnWidths[i] { 45 columnWidths[i] = columnWidth 46 } 47 } 48 } 49 50 for _, row := range table.Data { 51 for i, column := range row { 52 columnWidth := len(column.Contents) 53 54 if columnWidth > columnWidths[i] { 55 columnWidths[i] = columnWidth 56 } 57 } 58 } 59 60 if (isPrintHeader || isTTY) && table.Headers != nil { 61 err := table.renderRow(bdst, table.Headers, columnWidths, isTTY) 62 if err != nil { 63 return err 64 } 65 bdst.Flush() 66 } 67 68 for _, row := range table.Data { 69 err := table.renderRow(bdst, row, columnWidths, isTTY) 70 if err != nil { 71 return err 72 } 73 bdst.Flush() 74 } 75 76 return nil 77 } 78 79 func (table Table) renderRow(dst io.Writer, row TableRow, widths map[int]int, isTTY bool) error { 80 for i, column := range row { 81 if column.Color != nil { 82 if isTTY { 83 column.Color.EnableColor() 84 } else { 85 column.Color.DisableColor() 86 } 87 } 88 89 contents := column.Contents 90 if column.Color != nil { 91 contents = column.Color.SprintFunc()(contents) 92 } 93 94 _, err := fmt.Fprintf(dst, "%s", contents) 95 if err != nil { 96 return err 97 } 98 99 paddingSize := widths[i] - len(column.Contents) 100 _, err = fmt.Fprintf(dst, strings.Repeat(" ", paddingSize)) 101 if err != nil { 102 return err 103 } 104 105 if i+1 < len(widths) { 106 _, err := fmt.Fprintf(dst, " ") 107 if err != nil { 108 return err 109 } 110 } 111 } 112 113 _, err := fmt.Fprintln(dst) 114 if err != nil { 115 return err 116 } 117 118 return nil 119 }