Tag-based configuration parser which loads values from different providers into typesafe struct.
This package needs go version 1.15+
go get -u github.com/miladabc/gonfig
package main
import (
"fmt"
"net/url"
"time"
"github.com/miladabc/gonfig"
)
// Unexported struct fields are ignored
type Config struct {
Host string
Log bool
Expiry int
Port uint
Pi float64
Com complex128
Byte byte
Rune rune
Duration time.Duration
Time time.Time
url url.URL
Redis struct {
Hosts []string
Ports []int
}
}
func main() {
var c Config
// Input argument must be a pointer to struct
err := gonfig.Load().FromEnv().Into(&c)
if err != nil {
fmt.Println(err)
}
}
All the tags are optional.
config
tag is used to change default key for fetching the value of field.
type Config struct {
HostName string `config:"HOST"`
}
func main() {
var c Config
os.Setenv("HOST", "golang.org")
gonfig.Load().FromEnv().Into(&c)
}
json
, yaml
and toml
tags are used to change default key for fetching the value from file.
type Config struct {
HostName string `json:"host" yaml:"host" toml:"host"`
}
func main() {
var c Config
gonfig.Load().FromFile("config.json").Into(&c)
}
default
tag is used to declare a default value in case of missing value.
type Config struct {
Host url.URL `default:"golang.org"`
}
required
tag is used to make sure a value is present for corresponding field.
Fields are optional by default.
type Config struct {
Host url.URL `required:"true"`
}
ignore
tag is used to skip populating a field.
Ignore is false
by default.
type Config struct {
Ignored int `ignore:"true"`
AlsoIgnored int `config:"-"`
}
expand
tag is used to expand value from OS environment variables.
Expand is false
by default.
type Config struct {
Expanded int `expand:"true" default:"${ENV_VALUE}"`
}
func main() {
var c Config
os.Setenv("ENV_VALUE", "123")
gonfig.Load().FromEnv().Into(&c)
fmt.Println(c.Expanded) // 123
}
separator
tag is used to separate slice/array items.
Default separator is a single space.
type Config struct {
List []int `separator:"," default:"1, 2, 3"`
}
format
tag is used for parsing time strings.
Default format is time.RFC3339
.
type Config struct {
Time time.Time `format:"2006-01-02T15:04:05.999999999Z07:00"`
}
Providers can be chained together and they are applied in the specified order.
If multiple values are provided for a field, last one will get applied.
- Environment variables
- files
- .json
- .yaml (.yml)
- .toml
- .env
func main() {
var c Config
gonfig.
Load().
FromEnv().
FromFile("config.json").
FromFile("config.yaml").
FromFile("config.toml").
FromFile(".env").
AddProvider(CustomProvider).
Into(&c)
}
Env provider will populate struct fields based on the hierarchy of struct.
type Config struct {
PrettyLog bool
Redis struct {
Host string
Port int
}
}
func main() {
var c Config
gonfig.
Load().
FromEnv().
Into(&c)
}
It will check for following keys:
PRETTY_LOG
REDIS_HOST
REDIS_PORT
To change default settings, make an EnvProvider
and add it to the providers list manually:
type Config struct {
PrettyLog bool
Redis struct {
Host string
Port int
}
}
func main() {
var c Config
ep := gonfig.EnvProvider{
Prefix: "APP_", // Default to ""
SnakeCase: false, // Defaults to true
UpperCase: false, // Defaults to true
FieldSeparator: "__", // Defaults to "_"
Source: ".env", // Defaults to OS env vars
Required: true, // Defaults to false
}
gonfig.
Load().
AddProvider(&ep).
Into(&c)
}
It will check for following keys in .env
file:
APP_PrettyLog
APP_Redis__Host
APP_Redis__Port
File provider uses third party parsers for parsing files, read their documentation for more info.
You can use your own provider by implementing Provider
interface and one or both Unmarshaler
and Filler
interfaces.
type CustomProvider struct{}
func (cp *CustomProvider) Name() string {
return "custom provider"
}
func (cp *CustomProvider) UnmarshalStruct(i interface{}) error {
// UnmarshalStruct receives a struct pointer and unmarshalls values into it.
return nil
}
func (cp *CustomProvider) Fill(in *gonfig.Input) error {
// Fill receives struct fields and set their values.
return nil
}
func main() {
var c Config
gonfig.
Load().
AddProvider(new(CustomProvider)).
Into(&c)
}
Any other type except the followings, results an error
string
bool
int
,int8
,int16
,int32
,int64
uint
,uint8
,uint16
,uint32
,uint64
float32
,float64
complex64
,complex128
byte
rune
- time.Duration
- time.Time
- url.URL
pointer
,slice
andarray
of above typesnested
andembedded
structs
Any contribution is appreciated :)
- Add support for map data type
- Add support for map slice
- Add support for slice of structs
- Add support for encoding.TextUnmarshaler and encoding.BinaryUnmarshaler
- Add support for other providers
- command line flags
- etcd
- Consul
- Vault
- Amazon SSM
Take a look at docs for more information.
The library is released under the MIT license.
Checkout LICENSE file.