github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/cli/printer/printer.go (about)

     1  /*
     2  Copyright (C) 2022-2023 ApeCloud Co., Ltd
     3  
     4  This file is part of KubeBlocks project
     5  
     6  This program is free software: you can redistribute it and/or modify
     7  it under the terms of the GNU Affero General Public License as published by
     8  the Free Software Foundation, either version 3 of the License, or
     9  (at your option) any later version.
    10  
    11  This program is distributed in the hope that it will be useful
    12  but WITHOUT ANY WARRANTY; without even the implied warranty of
    13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14  GNU Affero General Public License for more details.
    15  
    16  You should have received a copy of the GNU Affero General Public License
    17  along with this program.  If not, see <http://www.gnu.org/licenses/>.
    18  */
    19  
    20  package printer
    21  
    22  import (
    23  	"fmt"
    24  	"io"
    25  	"os"
    26  
    27  	"github.com/jedib0t/go-pretty/v6/table"
    28  )
    29  
    30  var (
    31  	// KubeCtlStyle renders a Table like kubectl
    32  	KubeCtlStyle table.Style
    33  
    34  	// TerminalStyle renders a Table like below:
    35  	//  +-----+------------+-----------+--------+-----------------------------+
    36  	//  |   # | FIRST NAME | LAST NAME | SALARY |                             |
    37  	//  +-----+------------+-----------+--------+-----------------------------+
    38  	//  |   1 | Arya       | Stark     |   3000 |                             |
    39  	//  |  20 | Jon        | Snow      |   2000 | You know nothing, Jon Snow! |
    40  	//  | 300 | Tyrion     | Lannister |   5000 |                             |
    41  	//  +-----+------------+-----------+--------+-----------------------------+
    42  	//  |     |            | TOTAL     |  10000 |                             |
    43  	//  +-----+------------+-----------+--------+-----------------------------+
    44  	TerminalStyle = table.Style{
    45  		Name:    "TerminalStyle",
    46  		Box:     table.StyleBoxDefault,
    47  		Color:   table.ColorOptionsDefault,
    48  		Format:  table.FormatOptionsDefault,
    49  		HTML:    table.DefaultHTMLOptions,
    50  		Options: table.OptionsDefault,
    51  		Title:   table.TitleOptionsDefault,
    52  	}
    53  )
    54  
    55  type TablePrinter struct {
    56  	Tbl table.Writer
    57  }
    58  
    59  func init() {
    60  	boxStyle := table.StyleBoxDefault
    61  	boxStyle.PaddingLeft = ""
    62  	boxStyle.PaddingRight = "   "
    63  	KubeCtlStyle = table.Style{
    64  		Name:    "StyleKubeCtl",
    65  		Box:     boxStyle,
    66  		Color:   table.ColorOptionsDefault,
    67  		Format:  table.FormatOptionsDefault,
    68  		HTML:    table.DefaultHTMLOptions,
    69  		Options: table.OptionsNoBordersAndSeparators,
    70  		Title:   table.TitleOptionsDefault,
    71  	}
    72  }
    73  
    74  // PrintTable high level wrapper function.
    75  func PrintTable(out io.Writer, customSettings func(*TablePrinter), rowFeeder func(*TablePrinter) error, header ...interface{}) error {
    76  	t := NewTablePrinter(out)
    77  	t.SetHeader(header...)
    78  	if customSettings != nil {
    79  		customSettings(t)
    80  	}
    81  	if rowFeeder != nil {
    82  		if err := rowFeeder(t); err != nil {
    83  			return err
    84  		}
    85  	}
    86  	t.Print()
    87  	return nil
    88  }
    89  
    90  func NewTablePrinter(out io.Writer) *TablePrinter {
    91  	t := table.NewWriter()
    92  	t.SetStyle(KubeCtlStyle)
    93  	t.SetOutputMirror(out)
    94  	return &TablePrinter{Tbl: t}
    95  }
    96  
    97  func (t *TablePrinter) SetStyle(style table.Style) {
    98  	t.Tbl.SetStyle(style)
    99  }
   100  
   101  func (t *TablePrinter) SetHeader(header ...interface{}) {
   102  	t.Tbl.AppendHeader(header)
   103  }
   104  
   105  func (t *TablePrinter) AddRow(row ...interface{}) {
   106  	rowObj := table.Row{}
   107  	for _, col := range row {
   108  		rowObj = append(rowObj, col)
   109  	}
   110  	t.Tbl.AppendRow(rowObj)
   111  }
   112  
   113  func (t *TablePrinter) Print() {
   114  	if t == nil || t.Tbl == nil {
   115  		return
   116  	}
   117  	t.Tbl.Render()
   118  }
   119  
   120  // SortBy sorts the table alphabetically by the column you specify, it will be sorted by the first table column in default.
   121  // The columnNumber index starts from 1
   122  func (t *TablePrinter) SortBy(columnNumber ...int) {
   123  	if len(columnNumber) == 0 {
   124  		t.Tbl.SortBy([]table.SortBy{
   125  			{
   126  				Number: 1,
   127  			},
   128  		})
   129  		return
   130  	}
   131  	res := make([]table.SortBy, len(columnNumber))
   132  	for i := range columnNumber {
   133  		res[i].Number = columnNumber[i]
   134  	}
   135  	t.Tbl.SortBy(res)
   136  }
   137  
   138  // PrintPairStringToLine prints pair string for a line , the format is as follows "<space>*<key>:\t<value>".
   139  // spaceCount is the space character count which is placed in the offset of field string.
   140  // the default values of tabCount is 2.
   141  func PrintPairStringToLine(name, value string, spaceCount ...int) {
   142  	scn := 2
   143  	// only the first variable of tabCount is effective.
   144  	if len(spaceCount) > 0 {
   145  		scn = spaceCount[0]
   146  	}
   147  	var (
   148  		spaceString string
   149  		i           int
   150  	)
   151  	for i = 0; i < scn; i++ {
   152  		spaceString += " "
   153  	}
   154  	line := fmt.Sprintf("%s%-20s%s", spaceString, name+":", value)
   155  	fmt.Println(line)
   156  }
   157  
   158  type Pair string
   159  
   160  func NewPair(key, value string) Pair {
   161  	return Pair(fmt.Sprintf("%s: %s", key, value))
   162  }
   163  
   164  func PrintLineWithTabSeparator(ps ...Pair) {
   165  	var line string
   166  	for _, v := range ps {
   167  		line += string(v) + "\t"
   168  	}
   169  	fmt.Println(line)
   170  }
   171  
   172  func PrintTitle(title string) {
   173  	titleTpl := fmt.Sprintf("\n%s:", title)
   174  	fmt.Println(titleTpl)
   175  }
   176  
   177  func PrintLine(line string) {
   178  	fmt.Println(line)
   179  }
   180  
   181  // PrintBlankLine prints a blank line
   182  func PrintBlankLine(out io.Writer) {
   183  	if out == nil {
   184  		out = os.Stdout
   185  	}
   186  	fmt.Fprintln(out)
   187  }