github.com/unionj-cloud/go-doudou/v2@v2.3.5/toolkit/envconfig/README.md (about) 1 # envconfig 2 3 [](https://travis-ci.org/kelseyhightower/envconfig) 4 5 ```Go 6 import "github.com/kelseyhightower/envconfig" 7 ``` 8 9 ## Documentation 10 11 See [godoc](http://godoc.org/github.com/kelseyhightower/envconfig) 12 13 ## Usage 14 15 Set some environment variables: 16 17 ```Bash 18 export MYAPP_DEBUG=false 19 export MYAPP_PORT=8080 20 export MYAPP_USER=Kelsey 21 export MYAPP_RATE="0.5" 22 export MYAPP_TIMEOUT="3m" 23 export MYAPP_USERS="rob,ken,robert" 24 export MYAPP_COLORCODES="red:1,green:2,blue:3" 25 ``` 26 27 Write some code: 28 29 ```Go 30 package main 31 32 import ( 33 "fmt" 34 "log" 35 "time" 36 37 "github.com/kelseyhightower/envconfig" 38 ) 39 40 type Specification struct { 41 Debug bool 42 Port int 43 User string 44 Users []string 45 Rate float32 46 Timeout time.Duration 47 ColorCodes map[string]int 48 } 49 50 func main() { 51 var s Specification 52 err := envconfig.Process("myapp", &s) 53 if err != nil { 54 log.Fatal(err.Error()) 55 } 56 format := "Debug: %v\nPort: %d\nUser: %s\nRate: %f\nTimeout: %s\n" 57 _, err = fmt.Printf(format, s.Debug, s.Port, s.User, s.Rate, s.Timeout) 58 if err != nil { 59 log.Fatal(err.Error()) 60 } 61 62 fmt.Println("Users:") 63 for _, u := range s.Users { 64 fmt.Printf(" %s\n", u) 65 } 66 67 fmt.Println("Color codes:") 68 for k, v := range s.ColorCodes { 69 fmt.Printf(" %s: %d\n", k, v) 70 } 71 } 72 ``` 73 74 Results: 75 76 ```Bash 77 Debug: false 78 Port: 8080 79 User: Kelsey 80 Rate: 0.500000 81 Timeout: 3m0s 82 Users: 83 rob 84 ken 85 robert 86 Color codes: 87 red: 1 88 green: 2 89 blue: 3 90 ``` 91 92 ## Struct Tag Support 93 94 Envconfig supports the use of struct tags to specify alternate, default, and required 95 environment variables. 96 97 For example, consider the following struct: 98 99 ```Go 100 type Specification struct { 101 ManualOverride1 string `envconfig:"manual_override_1"` 102 DefaultVar string `default:"foobar"` 103 RequiredVar string `required:"true"` 104 IgnoredVar string `ignored:"true"` 105 AutoSplitVar string `split_words:"true"` 106 RequiredAndAutoSplitVar string `required:"true" split_words:"true"` 107 } 108 ``` 109 110 Envconfig has automatic support for CamelCased struct elements when the 111 `split_words:"true"` tag is supplied. Without this tag, `AutoSplitVar` above 112 would look for an environment variable called `MYAPP_AUTOSPLITVAR`. With the 113 setting applied it will look for `MYAPP_AUTO_SPLIT_VAR`. Note that numbers 114 will get globbed into the previous word. If the setting does not do the 115 right thing, you may use a manual override. 116 117 Envconfig will process value for `ManualOverride1` by populating it with the 118 value for `MYAPP_MANUAL_OVERRIDE_1`. Without this struct tag, it would have 119 instead looked up `MYAPP_MANUALOVERRIDE1`. With the `split_words:"true"` tag 120 it would have looked up `MYAPP_MANUAL_OVERRIDE1`. 121 122 ```Bash 123 export MYAPP_MANUAL_OVERRIDE_1="this will be the value" 124 125 # export MYAPP_MANUALOVERRIDE1="and this will not" 126 ``` 127 128 If envconfig can't find an environment variable value for `MYAPP_DEFAULTVAR`, 129 it will populate it with "foobar" as a default value. 130 131 If envconfig can't find an environment variable value for `MYAPP_REQUIREDVAR`, 132 it will return an error when asked to process the struct. If 133 `MYAPP_REQUIREDVAR` is present but empty, envconfig will not return an error. 134 135 If envconfig can't find an environment variable in the form `PREFIX_MYVAR`, and there 136 is a struct tag defined, it will try to populate your variable with an environment 137 variable that directly matches the envconfig tag in your struct definition: 138 139 ```shell 140 export SERVICE_HOST=127.0.0.1 141 export MYAPP_DEBUG=true 142 ``` 143 ```Go 144 type Specification struct { 145 ServiceHost string `envconfig:"SERVICE_HOST"` 146 Debug bool 147 } 148 ``` 149 150 Envconfig won't process a field with the "ignored" tag set to "true", even if a corresponding 151 environment variable is set. 152 153 ## Supported Struct Field Types 154 155 envconfig supports these struct field types: 156 157 * string 158 * int8, int16, int32, int64 159 * bool 160 * float32, float64 161 * slices of any supported type 162 * maps (keys and values of any supported type) 163 * [encoding.TextUnmarshaler](https://golang.org/pkg/encoding/#TextUnmarshaler) 164 * [encoding.BinaryUnmarshaler](https://golang.org/pkg/encoding/#BinaryUnmarshaler) 165 * [time.Duration](https://golang.org/pkg/time/#Duration) 166 167 Embedded structs using these fields are also supported. 168 169 ## Custom Decoders 170 171 Any field whose type (or pointer-to-type) implements `envconfig.Decoder` can 172 control its own deserialization: 173 174 ```Bash 175 export DNS_SERVER=8.8.8.8 176 ``` 177 178 ```Go 179 type IPDecoder net.IP 180 181 func (ipd *IPDecoder) Decode(value string) error { 182 *ipd = IPDecoder(net.ParseIP(value)) 183 return nil 184 } 185 186 type DNSConfig struct { 187 Address IPDecoder `envconfig:"DNS_SERVER"` 188 } 189 ``` 190 191 Example for decoding the environment variables into map[string][]structName type 192 193 ```Bash 194 export SMS_PROVIDER_WITH_WEIGHT= `IND=[{"name":"SMSProvider1","weight":70},{"name":"SMSProvider2","weight":30}];US=[{"name":"SMSProvider1","weight":100}]` 195 ``` 196 197 ```GO 198 type providerDetails struct { 199 Name string 200 Weight int 201 } 202 203 type SMSProviderDecoder map[string][]providerDetails 204 205 func (sd *SMSProviderDecoder) Decode(value string) error { 206 smsProvider := map[string][]providerDetails{} 207 pairs := strings.Split(value, ";") 208 for _, pair := range pairs { 209 providerdata := []providerDetails{} 210 kvpair := strings.Split(pair, "=") 211 if len(kvpair) != 2 { 212 return fmt.Errorf("invalid map item: %q", pair) 213 } 214 err := json.Unmarshal([]byte(kvpair[1]), &providerdata) 215 if err != nil { 216 return fmt.Errorf("invalid map json: %w", err) 217 } 218 smsProvider[kvpair[0]] = providerdata 219 220 } 221 *sd = SMSProviderDecoder(smsProvider) 222 return nil 223 } 224 225 type SMSProviderConfig struct { 226 ProviderWithWeight SMSProviderDecoder `envconfig:"SMS_PROVIDER_WITH_WEIGHT"` 227 } 228 ``` 229 230 Also, envconfig will use a `Set(string) error` method like from the 231 [flag.Value](https://godoc.org/flag#Value) interface if implemented.