Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
205 lines (140 sloc) 5.29 KB
/*
Package envconfig implements a configuration reader which reads each value from an environment variable.
The basic idea is that you define a configuration struct, like this:
var conf struct {
Addr string
Port int
Auth struct {
Key string
Endpoint string
}
Partitions []int
Shards []struct {
Name string
Id int
}
}
Once you have that, you need to initialize the configuration:
if err := envconfig.Init(&conf); err != nil {
log.Fatalln(err)
}
Then it's just a matter of setting the environment variables when calling your binary:
ADDR=localhost PORT=6379 AUTH_KEY=foobar ./mybinary
Layout of the conf struct
Your conf struct must follow the following rules:
- no unexported fields by default (can turn off with Options.AllowUnexported)
- only supported types (no map fields for example)
Naming of the keys
By default, envconfig generates all possible keys based on the field chain according to a flexible naming scheme.
The field chain is how you access your field in the configuration struct. For example:
var conf struct {
Shard struct {
Name string
}
}
With that struct, you access the name field via the chain *Shard.Name*
The default naming scheme takes that and transforms it into the following:
- SHARD_NAME
- shard_name
It can handles more complicated cases, with multiple words in one field name. It needs to be in the correct case though, for example:
var conf struct {
Cassandra struct {
SSLCert string
SslKey string
}
}
With that struct, you access the name field via the chain *Cassandra.SSLCert* or *Cassandra.SslKey*
The default naming scheme takes that and transforms it into the following:
- CASSANDRA_SSL_CERT, cassandra_ssl_cert, CASSANDRA_SSLCERT, cassandra_sslcert
- CASSANDRA_SSL_KEY, cassandra_ssl_key, CASSANDRA_SSLKEY, cassandra_sslkey
And, if that is not good enough for you, you always have the option to use a custom key:
var conf struct {
Cassandra struct {
Name string `envconfig:"cassandraMyName"`
}
}
Now envconfig will only ever checks the environment variable _cassandraMyName_.
Content of the variables
There are three types of content for a single variable:
- for simple types, a single string representing the value, and parseable into the type.
- for slices or arrays, a comma-separated list of strings. Each string must be parseable into the element type of the slice or array.
- for structs, a comma-separated list of specially formatted strings representing structs.
Example of a valid slice value:
foo,bar,baz
The format for a struct is as follow:
- prefixed with {
- suffixed with }
- contains a comma-separated list of field values, in the order in which they are defined in the struct
Example of a valid struct value:
type MyStruct struct {
Name string
Id int
Timeout time.Duration
}
{foobar,10,120s}
Example of a valid slice of struct values:
{foobar,10,120s},{barbaz,20,50s}
Special case for bytes slices
For bytes slices, you generally don't want to type out a comma-separated list of byte values.
For this use case, we support base64 encoded values.
Here's an example:
var conf struct {
Data []byte
}
os.Setenv("DATA", "Rk9PQkFS")
This will decode DATA to FOOBAR and put that into conf.Data.
Optional values
Sometimes you don't absolutely need a value. Here's how we tell envconfig a value is optional:
var conf struct {
Name string `envconfig:"optional"`
}
Skipped fields
Sometimes you want a field to be skipped entirely.
var conf struct {
Internal string `envconfig:"-"`
}
Default values
Often times you have configuration keys which almost never changes, but you still want to be able to change them.
In such cases, you might want to provide a default value.
Here's to do this with envconfig:
var conf struct {
Timeout time.Duration `envconfig:"default=1m"`
}
Combining options
You can of course combine multiple options. The syntax is simple enough, separate each option with a comma.
For example:
var conf struct {
Timeout time.Duration `envconfig:"default=1m,myTimeout"`
}
This would give you the default timeout of 1 minute, and lookup the myTimeout environment variable.
Supported types
envconfig supports the following list of types:
- bool
- string
- intX
- uintX
- floatX
- time.Duration
- pointers to all of the above types
Notably, we don't (yet) support complex types simply because I had no use for it yet.
Custom unmarshaler
When the standard types are not enough, you will want to use a custom unmarshaler for your types.
You do this by implementing Unmarshaler on your type. Here's an example:
type connectionType uint
const (
tlsConnection connectionType = iota
insecureConnection
)
func (t *connectionType) Unmarshal(s string) error {
switch s {
case "tls":
*t = tlsConnection
case "insecure":
*t = insecureConnection
default:
return fmt.Errorf("unable to unmarshal %s to a connection type", s)
}
return nil
}
*/
package envconfig
You can’t perform that action at this time.