github.com/skabbes/up@v0.2.1/internal/util/util.go (about) 1 // Package util haters gonna hate. 2 package util 3 4 import ( 5 "encoding/json" 6 "fmt" 7 "io/ioutil" 8 "net/http" 9 "os" 10 "strings" 11 12 "github.com/apex/up/internal/colors" 13 "github.com/pascaldekloe/name" 14 "github.com/pkg/errors" 15 "github.com/tj/go-progress" 16 ) 17 18 // Fields retained when clearing. 19 var keepFields = map[string]bool{ 20 "X-Powered-By": true, 21 } 22 23 // ClearHeader removes all header fields. 24 func ClearHeader(h http.Header) { 25 for k := range h { 26 if keepFields[k] { 27 continue 28 } 29 30 h.Del(k) 31 } 32 } 33 34 // ManagedByUp appends "Managed by Up". 35 func ManagedByUp(s string) string { 36 if s == "" { 37 return "Managed by Up." 38 } 39 40 return s + " (Managed by Up)." 41 } 42 43 // Exists returns true if the file exists. 44 func Exists(path string) bool { 45 _, err := os.Stat(path) 46 return err == nil 47 } 48 49 // ReadFileJSON reads json from the given path. 50 func ReadFileJSON(path string, v interface{}) error { 51 b, err := ioutil.ReadFile(path) 52 if err != nil { 53 return errors.Wrap(err, "reading") 54 } 55 56 if err := json.Unmarshal(b, &v); err != nil { 57 return errors.Wrap(err, "unmarshaling") 58 } 59 60 return nil 61 } 62 63 // Camelcase string with optional args. 64 func Camelcase(s string, v ...interface{}) string { 65 return name.CamelCase(fmt.Sprintf(s, v...), true) 66 } 67 68 // NewProgressInt with the given total. 69 func NewProgressInt(total int) *progress.Bar { 70 b := progress.NewInt(total) 71 b.Template(`{{.Bar}} {{.Percent | printf "%0.0f"}}% {{.Text}}`) 72 b.Width = 35 73 b.StartDelimiter = colors.Gray("|") 74 b.EndDelimiter = colors.Gray("|") 75 b.Filled = colors.Purple("█") 76 b.Empty = colors.Gray("░") 77 return b 78 } 79 80 // NewInlineProgressInt with the given total. 81 func NewInlineProgressInt(total int) *progress.Bar { 82 b := progress.NewInt(total) 83 b.Template(`{{.Bar}} {{.Percent | printf "%0.0f"}}% {{.Text}}`) 84 b.Width = 20 85 b.StartDelimiter = colors.Gray("|") 86 b.EndDelimiter = colors.Gray("|") 87 b.Filled = colors.Purple("█") 88 b.Empty = colors.Gray(" ") 89 return b 90 } 91 92 // Pad helper. 93 func Pad() func() { 94 println() 95 return func() { 96 println() 97 } 98 } 99 100 // Fatal error. 101 func Fatal(err error) { 102 fmt.Fprintf(os.Stderr, "\n %s %s\n\n", colors.Red("Error:"), err) 103 os.Exit(1) 104 } 105 106 // IsJSON returns true if the msg looks like json. 107 func IsJSON(s string) bool { 108 return len(s) > 1 && s[0] == '{' && s[len(s)-1] == '}' 109 } 110 111 // IsNotFound returns true if err is not nil and represents a missing resource. 112 func IsNotFound(err error) bool { 113 switch { 114 case err == nil: 115 return false 116 case strings.Contains(err.Error(), "does not exist"): 117 return true 118 case strings.Contains(err.Error(), "not found"): 119 return true 120 default: 121 return false 122 } 123 } 124 125 // IsThrottled returns true if err is not nil and represents a throttled request. 126 func IsThrottled(err error) bool { 127 switch { 128 case err == nil: 129 return false 130 case strings.Contains(err.Error(), "Throttling: Rate exceeded"): 131 return true 132 default: 133 return false 134 } 135 } 136 137 // Env returns a slice from environment variable map. 138 func Env(m map[string]string) (env []string) { 139 for k, v := range m { 140 env = append(env, fmt.Sprintf("%s=%s", k, v)) 141 } 142 return 143 }