go-andiamo / cfgenv

Go package for loading config structs from environment vars

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

CFGENV

GoDoc Latest Version Go Report Card

Cfgenv loads config structs from environment vars.

Struct field types supported:

  • native type - string, bool, int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, time.Duration
  • pointer native type - *string, *bool, *int, *int8, *int16, *int32, *int64, *uint, *uint8, *uint16, *uint32, *uint64, *float32, *float64, *time.Duration - environment var is optional and value is not set if the env var is missing
  • []V (slice) where V is native type or pointer native type
  • map[K]V where K is native type and V is native type or pointer native type
  • embedded structs
  • other types can be handled by providing a cfgenv.CustomerSetterOption

Example:

package main

import (
    "fmt"
    "github.com/go-andiamo/cfgenv"
)

type DbConfig struct {
    Host     string `env:"optional,default=localhost"`
    Port     uint   `env:"optional,default=3601"`
    Username string
    Password string
}

type Config struct {
    ServiceName string
    Database    DbConfig `env:"prefix=DB"`
}

func main() {
    cfg := &Config{}
    err := cfgenv.Load(cfg)
    if err != nil {
        panic(err)
    } else {
        fmt.Printf("%+v\n", cfg)
    }
}

would effectively load from environment...

SERVICE_NAME=foo
DB_HOST=localhost
DB_PORT=33601
DB_USERNAME=root
DB_PASSWORD=root

Installation

To install cfgenv, use go get:

go get github.com/go-andiamo/cfgenv

To update cfgenv to the latest version, run:

go get -u github.com/go-andiamo/cfgenv

Tags

Fields in config structs can use the env tag to override cfgenv loading behaviour

Tag Purpose
env:"MY" overrides the environment var name to read with MY
env:"optional" denotes the environment var is optional
env:"default=foo" denotes the default value if the environment var is missing
env:"prefix=SUB" (on a struct field) denotes all fields on the embedded struct will load from env var names prefixed with SUB_
env:"prefix=SUB_" (on a map[string]string field) denotes the map will read all env vars whose name starts with SUB_
env:"delimiter=;"
env:"delim=;"
(on slice and map fields) denotes the character used to delimit items
(the default is ,)
env:"separator=:"
env:"sep=:"
(on map fields) denotes the character used to separate key and value
(the default is :)

Options

When loading config from environment vars, several option interfaces can be passed to cfgenv.Load() function to alter the names of expected environment vars or provide support for extra field types.

cfgenv.PrefixOption

cfgenv.PrefixOption

Alters the prefix for all environment vars

(Implement interface or use cfgenv.NewPrefix(prefix string)

Example:

package main

import (
    "fmt"
    "github.com/go-andiamo/cfgenv"
)

type Config struct {
    ServiceName string
}

func main() {
    cfg := &Config{}
    err := cfgenv.Load(cfg, cfgenv.NewPrefix("MYAPP"))
    if err != nil {
        panic(err)
    } else {
        fmt.Printf("%+v\n", cfg)
    }
}

to load from environment variables...

MYAPP_SERVICE_NAME=foo

cfgenv.SeparatorOption

cfgenv.SeparatorOption

Alters the separators used between prefixes and field names for environment vars

(Implement interface or use cfgenv.NewSeparator(separator string)

Example:

package main

import (
    "fmt"
    "github.com/go-andiamo/cfgenv"
)

type DbConfig struct {
    Host     string `env:"optional,default=localhost"`
    Port     uint   `env:"optional,default=3601"`
    Username string
    Password string
}

type Config struct {
    ServiceName string
    Database    DbConfig `env:"prefix=DB"`
}

func main() {
    cfg := &Config{}
    err := cfgenv.Load(cfg, cfgenv.NewPrefix("MYAPP"), cfgenv.NewSeparator("."))
    if err != nil {
        panic(err)
    } else {
        fmt.Printf("%+v\n", cfg)
    }
}

to load from environment variables...

MYAPP.SERVICE_NAME=foo
MYAPP.DB.HOST=localhost
MYAPP.DB.PORT=33601
MYAPP.DB.USERNAME=root
MYAPP.DB.PASSWORD=root

cfgenv.NamingOption

cfgenv.NamingOption

Overrides how environment variable names are deduced from field names

Example:

package main

import (
    "fmt"
    "github.com/go-andiamo/cfgenv"
    "reflect"
    "strings"
)

type DbConfig struct {
    Host     string `env:"optional,default=localhost"`
    Port     uint   `env:"optional,default=3601"`
    Username string
    Password string
}

type Config struct {
    ServiceName string
    Database    DbConfig `env:"prefix=DB"`
}

func main() {
    cfg := &Config{}
    err := cfgenv.Load(cfg, &LowercaseFieldNames{}, cfgenv.NewSeparator("."))
    if err != nil {
        panic(err)
    } else {
        fmt.Printf("%+v\n", cfg)
    }
}

type LowercaseFieldNames struct{}

func (l *LowercaseFieldNames) BuildName(prefix string, separator string, fld reflect.StructField, overrideName string) string {
    name := overrideName
    if name == "" {
        name = strings.ToLower(fld.Name)
    }
    if prefix != "" {
        name = prefix + separator + name
    }
    return name
}

to load from environment variables...

servicename=foo
DB.host=localhost
DB.port=33601
DB.username=root
DB.password=root

cfgenv.ExpandOption

cfgenv.ExpandOption

Providing an cfgenv.ExpandOption to the cfgenv.Load() function allows support for resolving substitute environment variables - e.g. EXAMPLE=${FOO}-{$BAR}

Use the Expand() function - or implement your own ExpandOption

Example - see expand_option


cfgenv.CustomSetterOption

cfgenv.CustomSetterOption

Provides support for custom struct field types

Example - see custom_setter_option

Write Example

Cfgenv can also write examples and current config using the cfgenv.Example() or cfgenv.Write() functions.

Example - see write_example

About

Go package for loading config structs from environment vars

License:Apache License 2.0


Languages

Language:Go 100.0%