github.com/unionj-cloud/go-doudou/v2@v2.3.5/toolkit/envconfig/README.md (about)

     1  # envconfig
     2  
     3  [![Build Status](https://travis-ci.org/kelseyhightower/envconfig.svg)](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.