configuration

package module
v3.0.2 Latest Latest
Warning

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

Go to latest
Published: May 23, 2021 License: MIT Imports: 11 Imported by: 0

README

Go Report Card codecov Go GoDoc Mentioned in Awesome Go

Configuration

is a library for injecting values recursively into structs - a convenient way of setting up a configuration object. Available features:

  • setting default values for struct fields - NewDefaultProvider()
  • setting values from environment variables - NewEnvProvider()
  • setting values from command line flags - NewFlagProvider(&cfg)
  • setting values from files (JSON or YAML) - NewFileProvider("./testdata/input.yml")

Supported types:

  • string, *string, []string
  • bool, *bool, []bool
  • int, int8, int16, int32, int64 + slices of these types
  • *int, *int8, *int16, *int32, *int64
  • uint, uint8, uint16, uint32, uint64 + slices of these types
  • *uint, *uint8, *uint16, *uint32, *uint64
  • float32, float64 + slices of these types
  • *float32, *float64
  • time.Duration from strings like 12ms, 2s etc.
  • embedded structs and pointers to structs

Why?

  • your entire configuration can be defined in one model
  • all metadata is in your model (defined with tags)
  • easy to set/change a source of data for your configuration
  • easy to set a priority of sources to fetch data from (e.g., 1.flags, 2.env, 3.default or another order)
  • you can implement your custom provider
  • only 2 external dependencies
  • complies with 12-factor app

Quick start

Import path github.com/BoRuDar/configuration/v3

// define a configuration object
cfg := struct {
    Name     string `flag:"name"`
    LastName string `default:"defaultLastName"`
    Age      byte   `env:"AGE_ENV"`
    BoolPtr  *bool  `default:"false"`

    ObjPtr *struct {
        F32       float32       `default:"32"`
        StrPtr    *string       `default:"str_ptr_test"`
        HundredMS time.Duration `default:"100ms"`
    }

    Obj struct {
        IntPtr   *int16   `default:"123"`
        NameYML  int      `default:"24"`
        StrSlice []string `default:"one;two"`
        IntSlice []int64  `default:"3; 4"`
    }
}{}

fileProvider, err := NewFileProvider("./testdata/input.yml")
if err != nil {
    t.Fatalf("unexpected error: %v", err)
}

configurator, err := New(
    &cfg, // pointer to the object for configuration 
    NewFlagProvider(&cfg),  // 1. flag provider expects pointer to the object to initialize flags
    NewEnvProvider(),       // 2.
    fileProvider,           // 3.
    NewDefaultProvider(),   // 4.
    // providers are executed in order of the declaration from 1 to 4 
)
if err != nil {
    t.Fatalf("unexpected error: %v", err)
}

configurator.InitValues()

Providers

You can specify one or more providers. They will be executed in order of definition:

[]Provider{
    NewFlagProvider(&cfg), // 1
    NewEnvProvider(), // 2
    NewDefaultProvider(), // 3
} 

If provider set value successfully next ones will not be executed (if flag provider from the sample above found a value env and default providers are skipped). The value of first successfully executed provider will be set. If none of providers found value - an application will be terminated. This behavior can be changed with configurator.SetOnFailFn method.

Custom provider

You can define a custom provider which should satisfy next interface:

type Provider interface {
	Provide(field reflect.StructField, v reflect.Value, pathToField ...string) error
}
Default provider

Looks for default tag and set value from it:

    struct {
        // ...
        Name string `default:"defaultName"`
        // ...
    }
Env provider

Looks for env tag and tries to find an ENV variable with the name from the tag (AGE in this example):

    struct {
        // ...
        Age      byte   `env:"AGE"`
        // ...
    }

Name inside tag env:"<name>" must be unique for each field.

Flag provider

Looks for flag tag and tries to set value from the command line flag -first_name

    struct {
        // ...
        Name     string `flag:"first_name|default_value|Description"`
        // ...
    }

Name inside tag flag:"<name>" must be unique for each field. default_value and description sections are optional and can be omitted. NewFlagProvider(&cfg) expects a pointer to the same object for initialization.

Note: if program is executed with -help or -h flag you will see all available flags with description:

Flags: 
	-first_name		"Description (default: default_value)"

And program execution will be terminated.

File provider

Doesn't require any specific tags. JSON and YAML formats of files are supported.

    NewFileProvider("./testdata/input.yml")

Documentation

Overview

Package configuration provides ability to initialize your custom configuration struct from: flags, environment variables, `default` tag, files (toml)

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrEmptyValue = errors.New("empty value")
)

Functions

func New

func New(
	cfgPtr interface{},
	providers ...Provider,
) (configurator, error)

New creates a new instance of the configurator.

func NewDefaultProvider

func NewDefaultProvider() defaultProvider

NewDefaultProvider creates new provider which sets values from `default` tag

func NewEnvProvider

func NewEnvProvider() envProvider

NewEnvProvider creates provider which sets values from ENV variables (gets variable name from `env` tag)

func NewFileProvider

func NewFileProvider(fileName string) (fp fileProvider, err error)

NewFileProvider creates new provider which read values from files (toml)

func NewFlagProvider

func NewFlagProvider(ptrToCfg interface{}) flagProvider

NewFlagProvider creates a new provider to fetch data from flags like: --flag_name some_value

func SetField

func SetField(field reflect.StructField, v reflect.Value, valStr string) error

SetField sets field with `valStr` value (converts to the proper type beforehand)

Types

type Provider

type Provider interface {
	Provide(field reflect.StructField, v reflect.Value, pathToField ...string) error
}

Provider defines interface for existing and future custom providers

Jump to

Keyboard shortcuts

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