github.com/mook-as/cf-cli@v7.0.0-beta.28.0.20200120190804-b91c115fae48+incompatible/util/ui/ui_for_push.go (about) 1 package ui 2 3 import ( 4 "errors" 5 "fmt" 6 "reflect" 7 "sort" 8 "strings" 9 10 "code.cloudfoundry.org/cli/types" 11 12 "github.com/fatih/color" 13 ) 14 15 var ErrValueMissmatch = errors.New("values provided were of different types") 16 17 type Change struct { 18 Header string 19 CurrentValue interface{} 20 NewValue interface{} 21 HiddenValue bool 22 } 23 24 // DisplayChangeForPush will display the header and old/new value with the 25 // appropriately red/green minuses and pluses. 26 func (ui *UI) DisplayChangeForPush(header string, stringTypePadding int, hiddenValue bool, originalValue interface{}, newValue interface{}) error { 27 ui.terminalLock.Lock() 28 defer ui.terminalLock.Unlock() 29 30 originalType := reflect.ValueOf(originalValue).Type() 31 newType := reflect.ValueOf(newValue).Type() 32 if originalType != newType { 33 return ErrValueMissmatch 34 } 35 36 offset := strings.Repeat(" ", stringTypePadding) 37 38 switch oVal := originalValue.(type) { 39 case int: 40 nVal := newValue.(int) 41 ui.displayDiffForInt(offset, header, oVal, nVal) 42 case types.NullInt: 43 nVal := newValue.(types.NullInt) 44 ui.displayDiffForNullInt(offset, header, oVal, nVal) 45 case uint64: 46 nVal := newValue.(uint64) 47 ui.displayDiffForUint64(offset, header, oVal, nVal) 48 case string: 49 nVal := newValue.(string) 50 ui.displayDiffForString(offset, header, hiddenValue, oVal, nVal) 51 case []string: 52 nVal := newValue.([]string) 53 if len(oVal) == 0 && len(nVal) == 0 { 54 return nil 55 } 56 57 ui.displayDiffForStrings(offset, header, oVal, nVal) 58 case map[string]string: 59 nVal := newValue.(map[string]string) 60 if len(oVal) == 0 && len(nVal) == 0 { 61 return nil 62 } 63 64 ui.displayDiffForMapStringString(offset, header, oVal, nVal) 65 default: 66 panic(fmt.Sprintf("diff display does not have case for '%s'", header)) 67 } 68 return nil 69 } 70 71 // DisplayChangesForPush will display the set of changes via 72 // DisplayChangeForPush in the order given. 73 func (ui *UI) DisplayChangesForPush(changeSet []Change) error { 74 if len(changeSet) == 0 { 75 return nil 76 } 77 78 var columnWidth int 79 for _, change := range changeSet { 80 if width := wordSize(ui.TranslateText(change.Header)); width > columnWidth { 81 columnWidth = width 82 } 83 } 84 85 for _, change := range changeSet { 86 padding := columnWidth - wordSize(ui.TranslateText(change.Header)) + 3 87 err := ui.DisplayChangeForPush(change.Header, padding, change.HiddenValue, change.CurrentValue, change.NewValue) 88 if err != nil { 89 return err 90 } 91 } 92 93 return nil 94 } 95 96 func (ui UI) displayDiffForInt(offset string, header string, oldValue int, newValue int) { 97 if oldValue != newValue { 98 formattedOld := fmt.Sprintf("- %s%s%d", ui.TranslateText(header), offset, oldValue) 99 formattedNew := fmt.Sprintf("+ %s%s%d", ui.TranslateText(header), offset, newValue) 100 101 if oldValue != 0 { 102 fmt.Fprintln(ui.Out, ui.modifyColor(formattedOld, color.New(color.FgRed))) 103 } 104 fmt.Fprintln(ui.Out, ui.modifyColor(formattedNew, color.New(color.FgGreen))) 105 } else { 106 fmt.Fprintf(ui.Out, " %s%s%d\n", ui.TranslateText(header), offset, oldValue) 107 } 108 } 109 110 func (ui UI) displayDiffForMapStringString(offset string, header string, oldMap map[string]string, newMap map[string]string) { 111 var oldKeys []string 112 for key := range oldMap { 113 oldKeys = append(oldKeys, key) 114 } 115 116 var newKeys []string 117 for key := range newMap { 118 newKeys = append(newKeys, key) 119 } 120 121 sortedKeys := sortedUniqueArray(oldKeys, newKeys) 122 123 fmt.Fprintf(ui.Out, " %s\n", ui.TranslateText(header)) 124 for _, key := range sortedKeys { 125 newVal, ok := newMap[key] 126 if !ok { 127 formattedOld := fmt.Sprintf("- %s", key) 128 fmt.Fprintln(ui.Out, ui.modifyColor(formattedOld, color.New(color.FgRed))) 129 continue 130 } 131 oldVal, ok := oldMap[key] 132 if !ok { 133 formattedNew := fmt.Sprintf("+ %s", key) 134 fmt.Fprintln(ui.Out, ui.modifyColor(formattedNew, color.New(color.FgGreen))) 135 continue 136 } 137 138 if oldVal == newVal { 139 fmt.Fprintf(ui.Out, " %s\n", key) 140 } else { 141 formattedOld := fmt.Sprintf("- %s", key) 142 fmt.Fprintln(ui.Out, ui.modifyColor(formattedOld, color.New(color.FgRed))) 143 formattedNew := fmt.Sprintf("+ %s", key) 144 fmt.Fprintln(ui.Out, ui.modifyColor(formattedNew, color.New(color.FgGreen))) 145 } 146 } 147 } 148 149 func (ui UI) displayDiffForNullInt(offset string, header string, oldValue types.NullInt, newValue types.NullInt) { 150 if oldValue != newValue { 151 formattedOld := fmt.Sprintf("- %s%s%d", ui.TranslateText(header), offset, oldValue.Value) 152 formattedNew := fmt.Sprintf("+ %s%s%d", ui.TranslateText(header), offset, newValue.Value) 153 154 if oldValue.IsSet { 155 fmt.Fprintln(ui.Out, ui.modifyColor(formattedOld, color.New(color.FgRed))) 156 } 157 fmt.Fprintln(ui.Out, ui.modifyColor(formattedNew, color.New(color.FgGreen))) 158 } else { 159 fmt.Fprintf(ui.Out, " %s%s%d\n", ui.TranslateText(header), offset, oldValue.Value) 160 } 161 } 162 163 func (ui UI) displayDiffForString(offset string, header string, hiddenValue bool, oVal string, nVal string) { 164 if oVal != nVal { 165 var formattedOld, formattedNew string 166 if hiddenValue { 167 formattedOld = fmt.Sprintf("- %s%s%s", ui.TranslateText(header), offset, RedactedValue) 168 formattedNew = fmt.Sprintf("+ %s%s%s", ui.TranslateText(header), offset, RedactedValue) 169 } else { 170 formattedOld = fmt.Sprintf("- %s%s%s", ui.TranslateText(header), offset, oVal) 171 formattedNew = fmt.Sprintf("+ %s%s%s", ui.TranslateText(header), offset, nVal) 172 } 173 174 if oVal != "" { 175 fmt.Fprintln(ui.Out, ui.modifyColor(formattedOld, color.New(color.FgRed))) 176 } 177 if nVal != "" { 178 fmt.Fprintln(ui.Out, ui.modifyColor(formattedNew, color.New(color.FgGreen))) 179 } 180 } else { 181 if hiddenValue { 182 fmt.Fprintf(ui.Out, " %s%s%s\n", ui.TranslateText(header), offset, RedactedValue) 183 } else { 184 fmt.Fprintf(ui.Out, " %s%s%s\n", ui.TranslateText(header), offset, oVal) 185 } 186 } 187 } 188 189 func (ui UI) displayDiffForStrings(offset string, header string, oldList []string, newList []string) { 190 fmt.Fprintf(ui.Out, " %s\n", ui.TranslateText(header)) 191 192 fullList := sortedUniqueArray(oldList, newList) 193 for _, item := range fullList { 194 inOld := existsIn(item, oldList) 195 inNew := existsIn(item, newList) 196 197 switch { 198 case inOld && inNew: 199 fmt.Fprintf(ui.Out, " %s\n", item) 200 case inOld: 201 formattedOld := fmt.Sprintf("- %s", item) 202 fmt.Fprintln(ui.Out, ui.modifyColor(formattedOld, color.New(color.FgRed))) 203 default: 204 formattedNew := fmt.Sprintf("+ %s", item) 205 fmt.Fprintln(ui.Out, ui.modifyColor(formattedNew, color.New(color.FgGreen))) 206 } 207 } 208 } 209 210 func (ui UI) displayDiffForUint64(offset string, header string, oldValue uint64, newValue uint64) { 211 if oldValue != newValue { 212 formattedOld := fmt.Sprintf("- %s%s%d", ui.TranslateText(header), offset, oldValue) 213 formattedNew := fmt.Sprintf("+ %s%s%d", ui.TranslateText(header), offset, newValue) 214 215 if oldValue != 0 { 216 fmt.Fprintln(ui.Out, ui.modifyColor(formattedOld, color.New(color.FgRed))) 217 } 218 fmt.Fprintln(ui.Out, ui.modifyColor(formattedNew, color.New(color.FgGreen))) 219 } else { 220 fmt.Fprintf(ui.Out, " %s%s%d\n", ui.TranslateText(header), offset, oldValue) 221 } 222 } 223 224 func existsIn(str string, ary []string) bool { 225 for _, val := range ary { 226 if val == str { 227 return true 228 } 229 } 230 return false 231 } 232 233 func sortedUniqueArray(ary1 []string, ary2 []string) []string { 234 uniq := append([]string{}, ary1...) 235 236 for _, str := range ary2 { 237 if !existsIn(str, uniq) { 238 uniq = append(uniq, str) 239 } 240 } 241 242 sort.Strings(uniq) 243 return uniq 244 }