Documentation ¶
Overview ¶
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"` Age int `envconfig:"-"` }
The two syntax are equivalent.
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 }
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrUnexportedField is the error returned by the Init* functions when a field of the config struct is not exported and the option AllowUnexported is not used. ErrUnexportedField = errors.New("envconfig: unexported field") // ErrNotAPointer is the error returned by the Init* functions when the configuration object is not a pointer. ErrNotAPointer = errors.New("envconfig: value is not a pointer") // ErrInvalidValueKind is the error returned by the Init* functions when the configuration object is not a struct. ErrInvalidValueKind = errors.New("envconfig: invalid value kind, only works on structs") )
Functions ¶
func Init ¶
func Init(conf interface{}) error
Init reads the configuration from environment variables and populates the conf object. conf must be a pointer
Example ¶
package main import ( "fmt" "os" "time" "github.com/HiFX/envconfig" ) func main() { var conf struct { MySQL struct { Host string Port int Database struct { User string Password string Name string } Params struct { Charset string `envconfig:"-"` } } Log struct { Path string `envconfig:"default=/var/log/mylog.log"` Rotate bool `envconfig:"logRotate"` } NbWorkers int Timeout time.Duration Cassandra struct { SSLCert string SSLKey string } } os.Setenv("MYSQL_HOST", "localhost") os.Setenv("MYSQL_PORT", "3306") os.Setenv("MYSQL_DATABASE_USER", "root") os.Setenv("MYSQL_DATABASE_PASSWORD", "foobar") os.Setenv("MYSQL_DATABASE_NAME", "default") os.Setenv("logRotate", "true") os.Setenv("NBWORKERS", "10") os.Setenv("TIMEOUT", "120s") os.Setenv("CASSANDRA_SSL_CERT", "/etc/cassandra/ssl.crt") os.Setenv("CASSANDRA_SSL_KEY", "/etc/cassandra/ssl.key") if err := envconfig.Init(&conf); err != nil { fmt.Printf("err=%s\n", err) } fmt.Println(conf.MySQL.Database.User) fmt.Println(conf.Log.Rotate) fmt.Println(conf.Timeout) fmt.Println(conf.Log.Path) fmt.Println(conf.Cassandra.SSLCert) fmt.Println(conf.Cassandra.SSLKey) }
Output: root true 2m0s /var/log/mylog.log /etc/cassandra/ssl.crt /etc/cassandra/ssl.key
func InitWithOptions ¶
InitWithOptions reads the configuration from environment variables and populates the conf object. conf must be a pointer.
func InitWithPrefix ¶
InitWithPrefix reads the configuration from environment variables and populates the conf object. conf must be a pointer. Each key read will be prefixed with the prefix string.
Example ¶
package main import ( "fmt" "os" "github.com/HiFX/envconfig" ) func main() { var conf struct { Name string } os.Setenv("NAME", "") os.Setenv("FOO_NAME", "") os.Setenv("NAME", "foobar") err := envconfig.InitWithPrefix(&conf, "FOO") fmt.Println(err) os.Setenv("FOO_NAME", "foobar") err = envconfig.InitWithPrefix(&conf, "FOO") fmt.Println(err) fmt.Println(conf.Name) }
Output: envconfig: keys FOO_NAME, foo_name not found <nil> foobar
Types ¶
type Options ¶
type Options struct { // Prefix allows specifying a prefix for each key. Prefix string // AllOptional determines whether to not throw errors by default for any key // that is not found. AllOptional=true means errors will not be thrown. AllOptional bool // LeaveNil specifies whether to not create new pointers for any pointer fields // found within the passed config. Rather, it behaves such that if and only if // there is a) a non-empty field in the value or b) a non-empty value that // the pointer is pointing to will a new pointer be created. By default, // LeaveNil=false will create all pointers in all structs if they are nil. // // var X struct { // A *struct{ // B string // } // } // envconfig.InitWithOptions(&X, Options{LeaveNil: true}) // // $ ./program // // X.A == nil // // $ A_B="string" ./program // // X.A.B="string" // A will not be nil LeaveNil bool // AllowUnexported allows unexported fields to be present in the passed config. AllowUnexported bool }
Options is used to customize the behavior of envconfig. Use it with InitWithOptions.
type Unmarshaler ¶
Unmarshaler is the interface implemented by objects that can unmarshal a environment variable string of themselves.