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 }