github.com/vchain-us/vcn@v0.9.11-0.20210921212052-a2484d23c0b3/pkg/cmd/internal/cli/lc_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 "reflect" 16 "strings" 17 "text/tabwriter" 18 "time" 19 20 "github.com/dustin/go-humanize" 21 "github.com/fatih/color" 22 "github.com/mattn/go-colorable" 23 "github.com/vchain-us/vcn/pkg/api" 24 "github.com/vchain-us/vcn/pkg/cmd/internal/types" 25 "github.com/vchain-us/vcn/pkg/meta" 26 "gopkg.in/yaml.v2" 27 ) 28 29 func PrintLc(output string, r *types.LcResult) error { 30 switch output { 31 case "": 32 WriteLcResultTo(r, colorable.NewColorableStdout()) 33 case "attachments": 34 WriteLcResultTo(r, colorable.NewColorableStdout()) 35 case "yaml": 36 b, err := yaml.Marshal(r) 37 if err != nil { 38 return err 39 } 40 fmt.Println(string(b)) 41 case "json": 42 b, err := json.MarshalIndent(r, "", " ") 43 if err != nil { 44 return err 45 } 46 fmt.Println(string(b)) 47 default: 48 return outputNotSupportedErr(output) 49 } 50 return nil 51 } 52 53 func WriteLcResultTo(r *types.LcResult, out io.Writer) (n int64, err error) { 54 if r == nil { 55 return 0, nil 56 } 57 58 w := new(tabwriter.Writer) 59 w.Init(out, 0, 8, 0, '\t', 0) 60 61 printf := func(format string, a ...interface{}) error { 62 m, err := fmt.Fprintf(w, format, a...) 63 n += int64(m) 64 return err 65 } 66 67 s := reflect.ValueOf(r).Elem() 68 s = s.FieldByName("LcArtifact") 69 typeOfT := s.Type() 70 71 for i, l := 0, s.NumField(); i < l; i++ { 72 f := s.Field(i) 73 if key, ok := typeOfT.Field(i).Tag.Lookup("vcn"); ok { 74 var value string 75 switch key { 76 case "Size": 77 if size, ok := f.Interface().(uint64); ok && size > 0 { 78 value = humanize.Bytes(size) 79 } 80 case "Metadata": 81 if metadata, ok := f.Interface().(api.Metadata); ok { 82 for k, v := range metadata { 83 if v == "" { 84 continue 85 } 86 if vv, err := json.MarshalIndent(v, "\t", " "); err == nil { 87 value += fmt.Sprintf("\n\t\t%s=%s", k, string(vv)) 88 } 89 } 90 value = strings.TrimPrefix(value, "\n") 91 } 92 case "Apikey revoked": 93 if f.IsZero() { 94 value = color.New(meta.StyleWarning()).Sprintf("not available") 95 } else { 96 if revoked, ok := f.Interface().(*time.Time); ok { 97 if revoked.IsZero() { 98 value = color.New(meta.StyleAffordance()).Sprintf("no") 99 } else { 100 value = color.New(meta.StyleError()).Sprintf(revoked.Format(time.UnixDate)) 101 } 102 } 103 } 104 case "Attachments": 105 if attachments, ok := f.Interface().([]api.Attachment); ok { 106 for _, attach := range attachments { 107 if attach.Filename == "" { 108 continue 109 } 110 v := reflect.ValueOf(attach) 111 112 for i := 0; i < v.NumField(); i++ { 113 sep := "\n\t %s:\t%s" 114 if i == 0 { 115 sep = "\n\t- %s:\t%s" 116 } 117 value += fmt.Sprintf(sep, v.Type().Field(i).Name, v.Field(i).String()) 118 } 119 } 120 } 121 case "Status": 122 err = printf("Status:\t%s\n", meta.StatusNameStyled(r.Status)) 123 if err != nil { 124 return 125 } 126 case "Included in": 127 if included, ok := f.Interface().([]api.PackageDetails); ok { 128 value += formatPackageDetails(included) 129 } 130 case "Dependencies": 131 if deps, ok := f.Interface().([]api.PackageDetails); ok { 132 value += formatPackageDetails(deps) 133 } 134 default: 135 value = fmt.Sprintf("%s", f.Interface()) 136 } 137 if value != "" { 138 err = printf("%s:\t%s\n", key, value) 139 if err != nil { 140 return 141 } 142 } 143 } 144 } 145 146 // here extra data when --verbose flag is provided 147 if r.Verbose != nil { 148 err = printf("\nAdditional details:\n") 149 if err != nil { 150 return 151 } 152 s = reflect.ValueOf(r.Verbose).Elem() 153 typeOfT = s.Type() 154 for i, l := 0, s.NumField(); i < l; i++ { 155 if key, ok := typeOfT.Field(i).Tag.Lookup("vcn"); ok { 156 switch key { 157 case "LedgerName": 158 err = printf("Ledger Name:\t%s\n", r.Verbose.LedgerName) 159 if err != nil { 160 return 161 } 162 case "LocalSID": 163 err = printf("Local SignerID:\t%s\n", r.Verbose.LocalSID) 164 if err != nil { 165 return 166 } 167 case "ApiKey": 168 err = printf("Api-key:\t%s\n", r.Verbose.ApiKey) 169 if err != nil { 170 return 171 } 172 } 173 } 174 } 175 } 176 177 for _, e := range r.Errors { 178 err = printf("Error:\t%s\n", color.New(meta.StyleError()).Sprintf(e.Error())) 179 if err != nil { 180 return 181 } 182 } 183 184 return n, w.Flush() 185 } 186 187 func PrintLcSlice(output string, rs []*types.LcResult) error { 188 switch output { 189 case "": 190 for _, r := range rs { 191 WriteLcResultTo(r, colorable.NewColorableStdout()) 192 fmt.Println() 193 } 194 case "yaml": 195 b, err := yaml.Marshal(rs) 196 if err != nil { 197 return err 198 } 199 fmt.Println(string(b)) 200 case "json": 201 b, err := json.MarshalIndent(rs, "", " ") 202 if err != nil { 203 return err 204 } 205 fmt.Println(string(b)) 206 default: 207 return outputNotSupportedErr(output) 208 } 209 return nil 210 } 211 212 func PrintAttachmentList(attach string, attachmentList []api.Attachment) { 213 if len(attachmentList) == 0 { 214 fmt.Println("no attachments founded") 215 return 216 } 217 color.Set(meta.StyleAffordance()) 218 attachDownloadMessage := "downloading attachments ..." 219 if attach != "" { 220 attachDownloadMessage = "downloading all notarizations attachments associated to the provided label ..." 221 } 222 fmt.Println(attachDownloadMessage) 223 color.Unset() 224 225 fmt.Printf("Download list:\n") 226 for _, a := range attachmentList { 227 fmt.Printf("\t\t- Filename:\t%s\n", a.Filename) 228 fmt.Printf("\t\t Hash:\t\t%s\n", a.Hash) 229 fmt.Printf("\t\t Mime:\t\t%s\n", a.Mime) 230 } 231 fmt.Printf("\n") 232 } 233 234 func formatPackageDetails(packages []api.PackageDetails) string { 235 var ret string 236 maxWidth := 0 237 for _, pkg := range packages { 238 width := len(pkg.Name) + len(pkg.Version) 239 if width > maxWidth { 240 maxWidth = width 241 } 242 } 243 maxWidth++ 244 for i, pkg := range packages { 245 if i != 0 { 246 ret += "\n" 247 } 248 var line string 249 if pkg.Version != "" { 250 line = pkg.Name + "@" + pkg.Version 251 } else { 252 line = pkg.Name 253 } 254 ret += fmt.Sprintf("\t%-*s %s", maxWidth, line, pkg.Hash) 255 } 256 257 return ret 258 }