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  }