cfgenv

package module
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 6, 2024 License: Apache-2.0 Imports: 10 Imported by: 0

README

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

Documentation

Overview

Package cfgenv - Go package for loading config structs from environment vars

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Example

func Example(w io.Writer, cfg any, options ...any) error

Example writes an example of the config

the supplied cfg arg must be a pointer to a struct

Use any options (such as PrefixOption, SeparatorOption, NamingOption or multiple CustomSetterOption) to alter loading behaviour

func ExampleOf

func ExampleOf[T any](w io.Writer, options ...any) error

ExampleOf writes an example of the specified T config

the type of T must be a struct

Use any options (such as PrefixOption, SeparatorOption, NamingOption or multiple CustomSetterOption) to alter loading behaviour

func Load

func Load(cfg any, options ...any) error

Load loads a config struct from environment vars

the supplied cfg arg must be a pointer to a struct

Use any options (such as PrefixOption, SeparatorOption, NamingOption or multiple CustomSetterOption) to alter loading behaviour

func LoadAs

func LoadAs[T any](options ...any) (*T, error)

LoadAs loads the specified T config struct type from environment vars

the type of T must be a struct

Use any options (such as PrefixOption, SeparatorOption, NamingOption or multiple CustomSetterOption) to alter loading behaviour

func Write

func Write(w io.Writer, cfg any, options ...any) error

Write writes the current config

the type of T must be a struct

Use any options (such as PrefixOption, SeparatorOption, NamingOption or multiple CustomSetterOption) to alter loading behaviour

Types

type CustomSetterOption

type CustomSetterOption interface {
	// IsApplicable should return true if the fld type is supported by this custom setter
	IsApplicable(fld reflect.StructField) bool
	// Set sets the field value `v` using the environment var `raw` value
	Set(fld reflect.StructField, v reflect.Value, raw string) error
}

CustomSetterOption is an option that can be passed to Load or LoadAs and provides support for reading additional struct field types

func NewDatetimeSetter

func NewDatetimeSetter(format string) CustomSetterOption

type ExpandOption added in v1.1.0

type ExpandOption interface {
	// Expand expands the env var value s
	Expand(s string) string
}

ExpandOption is an option that can be passed to Load or LoadAs and provides support for expanding environment var values like...

FOO=${BAR}

func Expand added in v1.1.0

func Expand(lookups ...map[string]string) ExpandOption

Expand creates a default ExpandOption (for use in Load / LoadAs)

Any supplied lookup maps are checked first - if a given env var name, e.g. "${FOO}", is not found in lookups then the value is taken from env var

type NamingOption

type NamingOption interface {
	BuildName(prefix string, separator string, fld reflect.StructField, overrideName string) string
}

NamingOption is an option that can be passed to Load or LoadAs and provides a means of overriding how env var names are deduced

type PrefixOption

type PrefixOption interface {
	// GetPrefix returns the prefix for all env var names
	GetPrefix() string
}

PrefixOption is an option that can be passed to Load or LoadAs and provides a prefix for all env var names

func NewPrefix

func NewPrefix(prefix string) PrefixOption

NewPrefix creates a new PrefixOption with the specified prefix

type SeparatorOption

type SeparatorOption interface {
	// GetSeparator returns the separator to be used between prefixes used in env var names
	GetSeparator() string
}

SeparatorOption is an option that can be passed to Load or LoadAs and provides the separator to be used between prefixes used in env var names

func NewSeparator

func NewSeparator(separator string) SeparatorOption

NewSeparator creates a new NewSeparator with the specified separator

Directories

Path Synopsis
_examples
basic command
expand_option command
naming_option command
prefix_option command
readme command
write_example command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL