github.com/stefanmcshane/helm@v0.0.0-20221213002717-88a4a2c6e77d/pkg/cli/output/output.go (about) 1 /* 2 Copyright The Helm Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package output 18 19 import ( 20 "encoding/json" 21 "fmt" 22 "io" 23 24 "github.com/gosuri/uitable" 25 "github.com/pkg/errors" 26 "sigs.k8s.io/yaml" 27 ) 28 29 // Format is a type for capturing supported output formats 30 type Format string 31 32 const ( 33 Table Format = "table" 34 JSON Format = "json" 35 YAML Format = "yaml" 36 ) 37 38 // Formats returns a list of the string representation of the supported formats 39 func Formats() []string { 40 return []string{Table.String(), JSON.String(), YAML.String()} 41 } 42 43 // FormatsWithDesc returns a list of the string representation of the supported formats 44 // including a description 45 func FormatsWithDesc() map[string]string { 46 return map[string]string{ 47 Table.String(): "Output result in human-readable format", 48 JSON.String(): "Output result in JSON format", 49 YAML.String(): "Output result in YAML format", 50 } 51 } 52 53 // ErrInvalidFormatType is returned when an unsupported format type is used 54 var ErrInvalidFormatType = fmt.Errorf("invalid format type") 55 56 // String returns the string representation of the Format 57 func (o Format) String() string { 58 return string(o) 59 } 60 61 // Write the output in the given format to the io.Writer. Unsupported formats 62 // will return an error 63 func (o Format) Write(out io.Writer, w Writer) error { 64 switch o { 65 case Table: 66 return w.WriteTable(out) 67 case JSON: 68 return w.WriteJSON(out) 69 case YAML: 70 return w.WriteYAML(out) 71 } 72 return ErrInvalidFormatType 73 } 74 75 // ParseFormat takes a raw string and returns the matching Format. 76 // If the format does not exists, ErrInvalidFormatType is returned 77 func ParseFormat(s string) (out Format, err error) { 78 switch s { 79 case Table.String(): 80 out, err = Table, nil 81 case JSON.String(): 82 out, err = JSON, nil 83 case YAML.String(): 84 out, err = YAML, nil 85 default: 86 out, err = "", ErrInvalidFormatType 87 } 88 return 89 } 90 91 // Writer is an interface that any type can implement to write supported formats 92 type Writer interface { 93 // WriteTable will write tabular output into the given io.Writer, returning 94 // an error if any occur 95 WriteTable(out io.Writer) error 96 // WriteJSON will write JSON formatted output into the given io.Writer, 97 // returning an error if any occur 98 WriteJSON(out io.Writer) error 99 // WriteYAML will write YAML formatted output into the given io.Writer, 100 // returning an error if any occur 101 WriteYAML(out io.Writer) error 102 } 103 104 // EncodeJSON is a helper function to decorate any error message with a bit more 105 // context and avoid writing the same code over and over for printers. 106 func EncodeJSON(out io.Writer, obj interface{}) error { 107 enc := json.NewEncoder(out) 108 err := enc.Encode(obj) 109 if err != nil { 110 return errors.Wrap(err, "unable to write JSON output") 111 } 112 return nil 113 } 114 115 // EncodeYAML is a helper function to decorate any error message with a bit more 116 // context and avoid writing the same code over and over for printers 117 func EncodeYAML(out io.Writer, obj interface{}) error { 118 raw, err := yaml.Marshal(obj) 119 if err != nil { 120 return errors.Wrap(err, "unable to write YAML output") 121 } 122 123 _, err = out.Write(raw) 124 if err != nil { 125 return errors.Wrap(err, "unable to write YAML output") 126 } 127 return nil 128 } 129 130 // EncodeTable is a helper function to decorate any error message with a bit 131 // more context and avoid writing the same code over and over for printers 132 func EncodeTable(out io.Writer, table *uitable.Table) error { 133 raw := table.Bytes() 134 raw = append(raw, []byte("\n")...) 135 _, err := out.Write(raw) 136 if err != nil { 137 return errors.Wrap(err, "unable to write table output") 138 } 139 return nil 140 }