github.com/vchain-us/vcn@v0.9.11-0.20210921212052-a2484d23c0b3/pkg/cmd/internal/cli/output.go (about) 1 /* 2 * Copyright (c) 2018-2020 vChain, Inc. All Rights Reserved. 3 * This software is released under GPL3. 4 * The full license information can be found under: 5 * https://www.gnu.org/licenses/gpl-3.0.en.html 6 * 7 */ 8 9 package cli 10 11 import ( 12 "encoding/json" 13 "fmt" 14 "io" 15 "os" 16 "reflect" 17 "strings" 18 "text/tabwriter" 19 20 "github.com/fatih/color" 21 "github.com/mattn/go-colorable" 22 23 "gopkg.in/yaml.v2" 24 25 "github.com/dustin/go-humanize" 26 "github.com/vchain-us/vcn/pkg/api" 27 "github.com/vchain-us/vcn/pkg/cmd/internal/types" 28 "github.com/vchain-us/vcn/pkg/meta" 29 ) 30 31 func WriteResultTo(r *types.Result, out io.Writer) (n int64, err error) { 32 if r == nil { 33 return 0, nil 34 } 35 36 w := new(tabwriter.Writer) 37 w.Init(out, 0, 8, 0, '\t', 0) 38 39 printf := func(format string, a ...interface{}) error { 40 m, err := fmt.Fprintf(w, format, a...) 41 n += int64(m) 42 return err 43 } 44 45 s := reflect.ValueOf(r).Elem() 46 s = s.FieldByName("ArtifactResponse") 47 typeOfT := s.Type() 48 49 for i, l := 0, s.NumField(); i < l; i++ { 50 f := s.Field(i) 51 if key, ok := typeOfT.Field(i).Tag.Lookup("vcn"); ok { 52 var value string 53 switch key { 54 case "Size": 55 if size, ok := f.Interface().(uint64); ok && size > 0 { 56 value = humanize.Bytes(size) 57 } 58 case "Metadata": 59 if metadata, ok := f.Interface().(api.Metadata); ok { 60 for k, v := range metadata { 61 if v == "" { 62 continue 63 } 64 if vv, err := json.MarshalIndent(v, "\t", " "); err == nil { 65 value += fmt.Sprintf("\n\t\t%s=%s", k, string(vv)) 66 } 67 } 68 value = strings.TrimPrefix(value, "\n") 69 } 70 case "Signer": 71 // todo(leogr): this will not happen anymore with the new platform APIs. 72 // Still retained to accommodate future improvements. 73 if f.Interface() != r.Verification.SignerID() { 74 value = fmt.Sprintf("%s", f.Interface()) 75 } 76 default: 77 value = fmt.Sprintf("%s", f.Interface()) 78 } 79 if value != "" { 80 err = printf("%s:\t%s\n", key, value) 81 if err != nil { 82 return 83 } 84 } 85 } 86 } 87 88 if bv := r.Verification; bv != nil { 89 if key := bv.SignerID(); key != "" { 90 err = printf("SignerID:\t%s\n", bv.SignerID()) 91 if err != nil { 92 return 93 } 94 } 95 if bv.Level != 0 { 96 err = printf("Level:\t%s\n", bv.Level.String()) 97 if err != nil { 98 return 99 } 100 } 101 if date := bv.Date(); date != "" { 102 err = printf("Date:\t%s\n", date) 103 if err != nil { 104 return 105 } 106 } 107 err = printf("Status:\t%s\n", meta.StatusNameStyled(r.Verification.Status)) 108 if err != nil { 109 return 110 } 111 } 112 113 for _, e := range r.Errors { 114 err = printf("Error:\t%s\n", color.New(meta.StyleError()).Sprintf(e.Error())) 115 if err != nil { 116 return 117 } 118 } 119 120 return n, w.Flush() 121 } 122 123 func Print(output string, r *types.Result) error { 124 switch output { 125 case "", "attachments": 126 WriteResultTo(r, colorable.NewColorableStdout()) 127 case "yaml": 128 b, err := yaml.Marshal(r) 129 if err != nil { 130 return err 131 } 132 fmt.Println(string(b)) 133 case "json": 134 b, err := json.MarshalIndent(r, "", " ") 135 if err != nil { 136 return err 137 } 138 fmt.Println(string(b)) 139 default: 140 return outputNotSupportedErr(output) 141 } 142 return nil 143 } 144 145 func PrintSlice(output string, rs []types.Result) error { 146 switch output { 147 case "", "attachments": 148 for _, r := range rs { 149 WriteResultTo(&r, colorable.NewColorableStdout()) 150 fmt.Println() 151 } 152 case "yaml": 153 b, err := yaml.Marshal(rs) 154 if err != nil { 155 return err 156 } 157 fmt.Println(string(b)) 158 case "json": 159 b, err := json.MarshalIndent(rs, "", " ") 160 if err != nil { 161 return err 162 } 163 fmt.Println(string(b)) 164 default: 165 return outputNotSupportedErr(output) 166 } 167 return nil 168 } 169 170 func PrintList(output string, artifacts []api.ArtifactResponse) error { 171 switch output { 172 case "", "attachments": 173 for _, a := range artifacts { 174 fmt.Print(a) 175 } 176 case "yaml": 177 b, err := yaml.Marshal(artifacts) 178 if err != nil { 179 return err 180 } 181 fmt.Println(string(b)) 182 case "json": 183 b, err := json.MarshalIndent(artifacts, "", " ") 184 if err != nil { 185 return err 186 } 187 fmt.Println(string(b)) 188 default: 189 return outputNotSupportedErr(output) 190 } 191 return nil 192 } 193 194 func PrintError(output string, err *types.Error) error { 195 if err == nil { 196 return nil 197 } 198 switch output { 199 case "", "attachments": 200 fmt.Fprintf(os.Stderr, "\nError: %s\n", err) 201 case "yaml": 202 b, err := yaml.Marshal(err) 203 if err != nil { 204 return err 205 } 206 fmt.Println(string(b)) 207 case "json": 208 b, err := json.MarshalIndent(err, "", " ") 209 if err != nil { 210 return err 211 } 212 fmt.Println(string(b)) 213 default: 214 return outputNotSupportedErr(output) 215 } 216 return nil 217 } 218 219 func PrintWarning(output string, message string) error { 220 switch output { 221 case "", "attachments": 222 fallthrough 223 case "yaml": 224 fallthrough 225 case "json": 226 fmt.Fprintf(os.Stderr, "\nWarning: %s\n", message) 227 default: 228 return outputNotSupportedErr(output) 229 } 230 return nil 231 } 232 233 func outputNotSupportedErr(output string) error { 234 return fmt.Errorf("output format not supported: %s", output) 235 } 236 237 func PrintObjects(output string, out interface{}) error { 238 switch output { 239 case "", "attachments": 240 fallthrough 241 case "yaml": 242 b, err := yaml.Marshal(out) 243 if err != nil { 244 return err 245 } 246 fmt.Println(string(b)) 247 case "json": 248 b, err := json.MarshalIndent(out, "", " ") 249 if err != nil { 250 return err 251 } 252 fmt.Println(string(b)) 253 default: 254 return outputNotSupportedErr(output) 255 } 256 return nil 257 }