github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/cli/printer/format.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 "os" 25 "strings" 26 27 "github.com/spf13/cobra" 28 "k8s.io/klog/v2" 29 "k8s.io/kubectl/pkg/cmd/util" 30 ) 31 32 // Format is a type for capturing supported output formats 33 type Format string 34 35 const ( 36 Table Format = "table" 37 JSON Format = "json" 38 YAML Format = "yaml" 39 Wide Format = "wide" 40 ) 41 42 var ErrInvalidFormatType = fmt.Errorf("invalid format type") 43 44 func Formats() []string { 45 return []string{Table.String(), JSON.String(), YAML.String(), Wide.String()} 46 } 47 48 func FormatsWithDesc() map[string]string { 49 return map[string]string{ 50 Table.String(): "Output result in human-readable format", 51 JSON.String(): "Output result in JSON format", 52 YAML.String(): "Output result in YAML format", 53 Wide.String(): "Output result in human-readable format with more information", 54 } 55 } 56 57 func (f Format) String() string { 58 return string(f) 59 } 60 61 func (f Format) IsHumanReadable() bool { 62 return f == Table || f == Wide 63 } 64 65 func ParseFormat(s string) (out Format, err error) { 66 switch s { 67 case Table.String(): 68 out, err = Table, nil 69 case JSON.String(): 70 out, err = JSON, nil 71 case YAML.String(): 72 out, err = YAML, nil 73 case Wide.String(): 74 out, err = Wide, nil 75 default: 76 out, err = "", ErrInvalidFormatType 77 } 78 return 79 } 80 81 func AddOutputFlag(cmd *cobra.Command, varRef *Format) { 82 cmd.Flags().VarP(newOutputValue(Table, varRef), "output", "o", 83 fmt.Sprintf("prints the output in the specified format. Allowed values: %s", strings.Join(Formats(), ", "))) 84 util.CheckErr(cmd.RegisterFlagCompletionFunc("output", 85 func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { 86 var names []string 87 for format, desc := range FormatsWithDesc() { 88 if strings.HasPrefix(format, toComplete) { 89 names = append(names, fmt.Sprintf("%s\t%s", format, desc)) 90 } 91 } 92 return names, cobra.ShellCompDirectiveNoFileComp 93 })) 94 } 95 96 func AddOutputFlagForCreate(cmd *cobra.Command, varRef *Format, persistent bool) { 97 fs := cmd.Flags() 98 if persistent { 99 fs = cmd.PersistentFlags() 100 } 101 fs.VarP(newOutputValue(YAML, varRef), "output", "o", "Prints the output in the specified format. Allowed values: JSON and YAML") 102 } 103 104 type outputValue Format 105 106 func newOutputValue(defaultValue Format, p *Format) *outputValue { 107 *p = defaultValue 108 return (*outputValue)(p) 109 } 110 111 func (o *outputValue) String() string { 112 return string(*o) 113 } 114 115 func (o *outputValue) Type() string { 116 return "format" 117 } 118 119 func (o *outputValue) Set(s string) error { 120 outfmt, err := ParseFormat(s) 121 if err != nil { 122 return err 123 } 124 *o = outputValue(outfmt) 125 return nil 126 } 127 128 // FatalWithRedColor when an error occurs, sets the red color to print it. 129 func FatalWithRedColor(msg string, code int) { 130 if klog.V(99).Enabled() { 131 klog.FatalDepth(2, msg) 132 } 133 if len(msg) > 0 { 134 // add newline if needed 135 if !strings.HasSuffix(msg, "\n") { 136 msg += "\n" 137 } 138 fmt.Fprint(os.Stderr, BoldRed(msg)) 139 } 140 os.Exit(code) 141 }