multiconfig

package module
v0.0.0-...-9740d03 Latest Latest
Warning

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

Go to latest
Published: Jul 17, 2015 License: MIT Imports: 15 Imported by: 0

README

Multiconfig GoDoc Build Status

Load configuration from multiple sources. Multiconfig makes loading/parsing from different configuration sources an easy task. The problem with any app is that with time there are many options how to populate a set of configs. Multiconfig makes it easy by dynamically creating all necessary options. Checkout the example below to see it in action.

Features

Multiconfig is able to read configuration automatically based on the given struct's field names from the following sources:

  • Struct tags
  • TOML file
  • JSON file
  • Environment variables
  • Flags

Install

go get github.com/koding/multiconfig

Usage and Examples

Lets define and struct that defines our configuration

type Server struct {
	Name    string `required:"true"`
	Port    int    `default:6060`
	Enabled bool
	Users   []string
}

Load the configuration into multiconfig:

// Create a new DefaultLoader without or with an initial config file
m := multiconfig.New()
m := multiconfig.NewWithPath("config.toml") // supports TOML and JSON

// Get an empty struct for your configuration
serverConf := new(Server)

// Populated the serverConf struct
err := m.Load(serverConf) // Check for error
m.MustLoad(serverConf)    // Panic's if there is any error

// Access now populated fields
serverConf.Port // by default 6060
serverConf.Name // "koding"

Run your app:

# Sets default values first which are defined in each field tag value. 
# Starts to load from config.toml
$ app

# Override any config easily with environment variables, environment variables
# are automatically generated in the form of STRUCTNAME_FIELDNAME
$ SERVER_PORT=4000 SERVER_NAME="koding" app

# Or pass via flag. Flags are also automatically generated based on the field
# name
$ app -port 4000 -users "gopher,koding"

# Print dynamically generated flags and environment variables:
$ app -help
Usage of app:
  -enabled=true: Change value of Enabled.
  -name=Koding: Change value of Name.
  -port=6060: Change value of Port.
  -users=[ankara istanbul]: Change value of Users.

Generated environment variables:
   SERVER_NAME
   SERVER_PORT
   SERVER_ENABLED
   SERVER_USERS

License

The MIT License (MIT) - see LICENSE.md for more details

Documentation

Overview

Package multiconfig provides a way to load and read configurations from multiple sources. You can read from TOML file, JSON file, Environment Variables and flag You can set the order of reader with MultiLoader. Package is extensible, you can add your custom Loader by implementing Load interface

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrSourceNotSet states that neither the path or the reader is set on the loader
	ErrSourceNotSet = errors.New("config path or reader is not set")

	// ErrFileNotFound states that given file is not exists
	ErrFileNotFound = errors.New("config file not found")
)

Functions

func MustLoad

func MustLoad(conf interface{})

MustLoad loads with the DefaultLoader settings. It exits if the config cannot be parsed.

func MustLoadWithPath

func MustLoadWithPath(path string, conf interface{})

MustLoadWithPath loads with the DefaultLoader settings and from the given Path. It exits if the config cannot be parsed.

Types

type DefaultLoader

type DefaultLoader struct {
	Loader
	Validator
}

DefaultLoader implements the Loader interface. It initializes the given pointer of struct s with configuration from the default sources. The order of load is TagLoader, FileLoader, EnvLoader and lastly FlagLoader. An error in any step stops the loading process. Each step overrides the previous step's config (i.e: defining a flag will override previous environment or file config). To customize the order use the individual load functions.

Example
// Our struct which is used for configuration
type ServerConfig struct {
	Name    string `default:"gopher"`
	Port    int    `default:"6060"`
	Enabled bool
	Users   []string
}

// Instantiate a default loader.
d := NewWithPath("testdata/config.toml")

s := &ServerConfig{}

// It first sets the default values for each field with tag values defined
// with "default", next it reads from config.toml, from environment
// variables and finally from command line flags. It panic's if loading fails.
d.MustLoad(s)

fmt.Println("Host-->", s.Name)
fmt.Println("Port-->", s.Port)
Output:

Host--> koding
Port--> 6060

func New

func New() *DefaultLoader

New returns a new instance of DefaultLoader without any file loaders.

func NewWithPath

func NewWithPath(path string) *DefaultLoader

NewWithPath returns a new instance of Loader to read from the given configuration file.

func (*DefaultLoader) MustLoad

func (d *DefaultLoader) MustLoad(conf interface{})

MustLoad is like Load but panics if the config cannot be parsed.

func (*DefaultLoader) MustValidate

func (d *DefaultLoader) MustValidate(conf interface{})

MustValidate validates the struct. It exits with status 1 if it can't validate.

type EnvironmentLoader

type EnvironmentLoader struct {
	// Prefix prepends given string to every environment variable
	// {STRUCTNAME}_FIELDNAME will be {PREFIX}_FIELDNAME
	Prefix string

	// CamelCase adds a seperator for field names in camelcase form. A
	// fieldname of "AccessKey" would generate a environment name of
	// "STRUCTNAME_ACCESSKEY". If CamelCase is enabled, the environment name
	// will be generated in the form of "STRUCTNAME_ACCESS_KEY"
	CamelCase bool
}

EnvironmentLoader satisifies the loader interface. It loads the configuration from the environment variables in the form of STRUCTNAME_FIELDNAME.

Example
// Our struct which is used for configuration
type ServerConfig struct {
	Name     string
	Port     int
	Enabled  bool
	Users    []string
	Postgres Postgres
}

// Assume those values defined before running the Loader
os.Setenv("SERVERCONFIG_NAME", "koding")
os.Setenv("SERVERCONFIG_PORT", "6060")

// Instantiate loader
l := &EnvironmentLoader{}

s := &ServerConfig{}
err := l.Load(s)
if err != nil {
	panic(err)
}

fmt.Println("Host-->", s.Name)
fmt.Println("Port-->", s.Port)
Output:

Host--> koding
Port--> 6060

func (*EnvironmentLoader) Load

func (e *EnvironmentLoader) Load(s interface{}) error

Load loads the source into the config defined by struct s

func (*EnvironmentLoader) PrintEnvs

func (e *EnvironmentLoader) PrintEnvs(s interface{})

PrintEnvs prints the generated environment variables to the std out.

type FlagLoader

type FlagLoader struct {
	// Prefix prepends the prefix to each flag name i.e:
	// --foo is converted to --prefix-foo.
	// --foo-bar is converted to --prefix-foo-bar.
	Prefix string

	// Flatten doesn't add prefixes for nested structs. So previously if we had
	// a nested struct `type T struct{Name struct{ ...}}`, this would generate
	// --name-foo, --name-bar, etc. When Flatten is enabled, the flags will be
	// flattend to the form: --foo, --bar, etc.. Panics if the nested structs
	// has a duplicate field name in the root level of the struct (outer
	// struct). Use this option only if you know what you do.
	Flatten bool

	// CamelCase adds a seperator for field names in camelcase form. A
	// fieldname of "AccessKey" would generate a flag name "--accesskey". If
	// CamelCase is enabled, the flag name will be generated in the form of
	// "--access-key"
	CamelCase bool

	// EnvPrefix is just a placeholder to print the correct usages when an
	// EnvLoader is used
	EnvPrefix string

	// Args defines a custom argument list. If nil, os.Args[1:] is used.
	Args []string
}

FlagLoader satisfies the loader interface. It creates on the fly flags based on the field names and parses them to load into the given pointer of struct s.

func (*FlagLoader) Load

func (f *FlagLoader) Load(s interface{}) error

Load loads the source into the config defined by struct s

type JSONLoader

type JSONLoader struct {
	Path   string
	Reader io.Reader
}

JSONLoader satisifies the loader interface. It loads the configuration from the given json file or Reader

Example
// Our struct which is used for configuration
type ServerConfig struct {
	Name     string
	Port     int
	Enabled  bool
	Users    []string
	Postgres Postgres
}

// Instantiate loader
l := &JSONLoader{Path: testJSON}

s := &ServerConfig{}
err := l.Load(s)
if err != nil {
	panic(err)
}

fmt.Println("Host-->", s.Name)
fmt.Println("Users-->", s.Users)
Output:

Host--> koding
Users--> [ankara istanbul]

func (*JSONLoader) Load

func (j *JSONLoader) Load(s interface{}) error

Load loads the source into the config defined by struct s Defaults to using the Reader if provided, otherwise tries to read from the file

type Loader

type Loader interface {
	// Load loads the source into the config defined by struct s
	Load(s interface{}) error
}

Loader loads the configuration from a source. The implementer of Loader is responsible of setting the default values of the struct.

func MultiLoader

func MultiLoader(loader ...Loader) Loader

MultiLoader creates a loader that executes the loaders one by one in order and returns on the first error.

Example
// Our struct which is used for configuration
type ServerConfig struct {
	Name     string
	Port     int
	Enabled  bool
	Users    []string
	Postgres Postgres
}

os.Setenv("SERVERCONFIG_NAME", "koding")
os.Setenv("SERVERCONFIG_PORT", "6060")

// Create a custom multi loader intance based on your needs.
f := &FlagLoader{}
e := &EnvironmentLoader{}

l := MultiLoader(f, e)

// Load configs into our s variable from the sources above
s := &ServerConfig{}
err := l.Load(s)
if err != nil {
	panic(err)
}

fmt.Println("Host-->", s.Name)
fmt.Println("Port-->", s.Port)
Output:

Host--> koding
Port--> 6060

type RequiredValidator

type RequiredValidator struct {
	//  TagName holds the validator tag name. The default is "required"
	TagName string

	// TagValue holds the expected value of the validator. The default is "true"
	TagValue string
}

RequiredValidator validates the struct against zero values

func (*RequiredValidator) Validate

func (e *RequiredValidator) Validate(s interface{}) error

Validate validates the given struct agaist field's zero values. If intentionaly, the value of a field is `zero-valued`(e.g false, 0, "") required tag should not be set for that field.

type TOMLLoader

type TOMLLoader struct {
	Path   string
	Reader io.Reader
}

TOMLLoader satisifies the loader interface. It loads the configuration from the given toml file or Reader

Example
// Our struct which is used for configuration
type ServerConfig struct {
	Name     string
	Port     int
	Enabled  bool
	Users    []string
	Postgres Postgres
}

// Instantiate loader
l := &TOMLLoader{Path: testTOML}

s := &ServerConfig{}
err := l.Load(s)
if err != nil {
	panic(err)
}

fmt.Println("Host-->", s.Name)
fmt.Println("Users-->", s.Users)
Output:

Host--> koding
Users--> [ankara istanbul]

func (*TOMLLoader) Load

func (t *TOMLLoader) Load(s interface{}) error

Load loads the source into the config defined by struct s Defaults to using the Reader if provided, otherwise tries to read from the file

type TagLoader

type TagLoader struct {
	// DefaultTagName is the default tag name for struct fields to define
	// default values for a field. Example:
	//
	//   // Field's default value is "koding".
	//   Name string `default:"koding"`
	//
	// The default value is "default" if it's not set explicitly.
	DefaultTagName string
}

TagLoader satisfies the loader interface. It parses a struct's field tags and populated the each field with that given tag.

func (*TagLoader) Load

func (t *TagLoader) Load(s interface{}) error

type Validator

type Validator interface {
	// Validate validates the config struct
	Validate(s interface{}) error
}

Validator validates the config against any predefined rules, those predefined rules should be given to this package. The implementer will be responsible about the logic

func MultiValidator

func MultiValidator(validators ...Validator) Validator

MultiValidator accepts variadic validators and satisfies Validator interface.

type YAMLLoader

type YAMLLoader struct {
	Path   string
	Reader io.Reader
}

YAMLLoader satisifies the loader interface. It loads the configuration from the given json file or Reader

func (*YAMLLoader) Load

func (j *YAMLLoader) Load(s interface{}) error

Load loads the source into the config defined by struct s Defaults to using the Reader if provided, otherwise tries to read from the file

Jump to

Keyboard shortcuts

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