github.com/govau/cf-common@v0.0.7/env/env.go (about) 1 package env 2 3 import ( 4 "encoding/hex" 5 "fmt" 6 "strconv" 7 ) 8 9 // Lookup must return the value for the environment variable with the given name 10 // and whether or not it was found. 11 type Lookup func(name string) (string, bool) 12 13 // NoopLookup always returns false for the environment variable with the 14 // given name. Useful as a fallback to return for an env lookup that may 15 // not always be applicable, e.g. if not running in CloudFoundry, a user 16 // provided service lookup won't be applicable. 17 func NoopLookup(name string) (string, bool) { 18 return "", false 19 } 20 21 // VarSet provides methods to access environment variables from a list of Lookup 22 // sources. 23 type VarSet struct { 24 // sources are searched sequentially for a given environment variable. 25 sources []Lookup 26 } 27 28 // NewVarSet makes a new VarSet from opts. 29 func NewVarSet(opts ...VarSetOpt) *VarSet { 30 v := &VarSet{sources: make([]Lookup, 0)} 31 for _, opt := range opts { 32 opt(v) 33 } 34 return v 35 } 36 37 // AppendSource adds s as another lookup source after all existing sources. 38 func (v *VarSet) AppendSource(s Lookup) *VarSet { 39 v.sources = append(v.sources, s) 40 return v 41 } 42 43 // String gets the string environment variable with the given name, if set. 44 // If not found, returns defaultVal. 45 func (v *VarSet) String(name, defaultVal string) string { 46 rv, ok := v.Lookup(name) 47 if !ok { 48 return defaultVal 49 } 50 return rv 51 } 52 53 // MustString gets the string environment variable with the given name, if set. 54 // It will panic with an error if it is not set. 55 // If desired, callers can use IsVarNotFound when recovering from the panic in 56 // order to check type of the error. 57 func (v *VarSet) MustString(name string) string { 58 rv, ok := v.Lookup(name) 59 if !ok { 60 panic(&varNotFoundError{name: name}) 61 } 62 return rv 63 } 64 65 // Bool gets the boolean environment variable with the given name, if set. 66 // If not found, returns false. 67 // If found and cannot parse, returns an error. 68 func (v *VarSet) Bool(name string) (bool, error) { 69 val, ok := v.Lookup(name) 70 if !ok { 71 return false, nil 72 } 73 rv, err := strconv.ParseBool(val) 74 if err != nil { 75 return false, &varNotParsableError{name: name} 76 } 77 return rv, nil 78 } 79 80 // MustBool gets the boolean environment variable with the given name, if set. 81 // If not set, false is returned. This matches behavior one would often see with 82 // command line boolean arguments: if you don't set it, it defaults to false. 83 // It will panic with an error if it is not a valid boolean. 84 // If desired, callers can use IsVarNotParsable when recovering from the panic 85 // in order to check type of the error. 86 func (v *VarSet) MustBool(name string) bool { 87 val, ok := v.Lookup(name) 88 if !ok { 89 return false 90 } 91 rv, err := strconv.ParseBool(val) 92 if err != nil { 93 panic(&varNotParsableError{name: name}) 94 } 95 return rv 96 } 97 98 // MustHexEncodedByteArray gets the hex-encoded environment variable with the 99 // given name, if set. 100 // It will panic with an error if it is not set if it is not a valid hex-encoded 101 // string or if its length does not match decodedByteLength. 102 // If desired, callers can use IsVarNotFound and IsVarNotParsable when 103 // recovering from the panic in order to check type of the error. 104 func (v *VarSet) MustHexEncodedByteArray(name string, decodedByteLength int) []byte { 105 rv, ok := v.Lookup(name) 106 if !ok { 107 panic(&varNotFoundError{name: name}) 108 } 109 byteRv, err := hex.DecodeString(rv) 110 if err != nil { 111 panic(&varNotParsableError{name: name}) 112 } 113 if len(byteRv) != decodedByteLength { 114 panic(&varNotParsableError{name: name}) 115 } 116 return byteRv 117 } 118 119 // Lookup looks for a given name within all lookup sources in order. 120 // If no variable is found, an empty string and false is returned. 121 func (v *VarSet) Lookup(name string) (string, bool) { 122 for _, lookup := range v.sources { 123 rv, ok := lookup(name) 124 if ok { 125 return rv, true 126 } 127 } 128 return "", false 129 } 130 131 // IsSet looks for a given name within all lookup sources in order. 132 // If found, true is returned, else false. 133 func (v *VarSet) IsSet(name string) bool { 134 _, ok := v.Lookup(name) 135 return ok 136 } 137 138 // IsVarNotFound returns a boolean indicating whether the error is known to 139 // report that an environment variable is not found. 140 func IsVarNotFound(err error) bool { 141 _, ok := err.(*varNotFoundError) 142 return ok 143 } 144 145 // NewVarNotFoundErr makes a new error that indicates that an environment 146 // variable is not found. 147 func NewVarNotFoundErr(name string) error { 148 return &varNotFoundError{name: name} 149 } 150 151 // varNotFoundError is returned when a required environment variable cannot be 152 // found. 153 type varNotFoundError struct { 154 // name of the environment variable that was not found. 155 name string 156 } 157 158 // Error implements error. 159 func (err *varNotFoundError) Error() string { 160 return fmt.Sprintf("environment variable with name %q not found", err.name) 161 } 162 163 // IsVarNotParsable returns a boolean indicating whether the error is known to 164 // report that an environment variable is not parsable. 165 func IsVarNotParsable(err error) bool { 166 _, ok := err.(*varNotParsableError) 167 return ok 168 } 169 170 // NewVarNotParsableErr makes a new error that indicates that an environment 171 // variable is not parsable. 172 func NewVarNotParsableErr(name string) error { 173 return &varNotParsableError{name: name} 174 } 175 176 // varNotParsableError is returned when a required environment variable cannot 177 // be parsed. 178 type varNotParsableError struct { 179 // name of the environment variable that was not parsable. 180 name string 181 } 182 183 // Error implements error. 184 func (err *varNotParsableError) Error() string { 185 return fmt.Sprintf("environment variable with name %q could not be parsed", err.name) 186 }