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"`
}
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
}
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/vrischmann/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/vrischmann/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.