config

package module
v0.5.1 Latest Latest
Warning

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

Go to latest
Published: Dec 13, 2022 License: MIT Imports: 11 Imported by: 16

README

config

A lightweight and versatile configuration toolkit for Go.

Build Status GoDoc Go Report Card

Overview

config presents configuration from multiple sources as a unified key/value store, providing a single consistent API to access configuration parameters, independent of the underlying configuration storage formats, locations or technologies.

config provides simple access to common configuration sources, including environment variables, command line flags, and configuration files (in JSON, INI, TOML, YAML, INI, and properties formats), and networked stores such as etcd. And you can roll your own Getters if you have unusual requirements.

config provides functions to coax configuration values from the configuration source into the types your code requires, including ints, string, bool, time, duration, and slices.

config is versatile as it allows you to control all aspects of your configuration, including the configuration sources, their location, format, and the order in which they are searched.

Quick Start

A couple of steps are required to setup and use config:

  • Create a Config to provide type conversions for values from the your configuration sources
  • Read and convert configuration Value from the Config

A minimal setup to access configuration from POSIX/GNU style command line flags, might look like:

    c := config.New(pflag.New())

A command line parameter such as

    myapp --config-file=myfile.json

could then be read using:

   cfgFile := c.MustGet("config.file").String()

Or read configuration from a configuration file - in this case a TOML file:

    c := config.New(blob.New(file.New("myconfig.toml"), toml.NewDecoder()))

Multiple configuration sources can be added to the config, for example:

    c := config.New(
        pflag.New(),
        env.New(),
        blob.New(file.New("myconfig.json"), json.NewDecoder()))

which would overlay configuration from POSIX flags over environment variables and over a JSON configuration file. Gets from the configuration will search through the source in the provided order for each key.

Multiple configuration sources can be setup and customised to suit your application requirements. The Example Usage section provides a more extensive example.

Core API

The core API is comprised of three elements:

  • the Getter which retrieves configuration values from an underlying data source
  • the Config which wraps a Getter or collection of Getters
  • the Value corresponding to a particular key which is returned by the Config.

The core API and supplied Getters should be sufficient for common usage.

Config

GoDoc

The Config provides get methods to retrieve configuration parameters, identified by a key string, and return them as a Value.

Getters are added to the Config by passing them to config.New, or by later adding them using Config.Append, which adds a Getter to the end of the list of Getters to he searched, or Config.Insert which inserts a Getter to the front of the list of Getters.

Values can be retrieved using Config.Get, which returns the Value and any error that occured while retrieving it, or Config.MustGet, which returns the Value or panics if there was an error.

Complete objects can be retrieved using Config.Unmarshal, or Config.UnmarshalToMap.

Getter

GoDoc

The Getter retrieves configuration values from an underlying data store.

The source of configuration may be local or remote. Getters for remote configuration typically cache a snapshot of configuration locally, but can be optionally monitored for changes using a Watcher.

A number of Getters for common configuration sources are provided in sub-packages:

Getter Configuration Source
blob files and other sources of formatted configuration in various formats including JSON, YAML, INI, and properties
dict key/value maps
env environment variables
etcd etcd v3 key/value server
flag Go style command line flags
pflag POSIX/GNU style command line flags

If those are insufficient, you can roll your own Getter. Refer to the Getter documentation for a more complete definition of the interface to implement.

The Getter may optionally support the Option interface so that it can be passed into config.New with a collection of other Getters. All the supplied Getters support the Option interface by embedding a GetterAsOption element.

Several helper packages are available should you wish to roll your own Getter:

The keys sub-package provides a number of functions to assist in mapping between namespaces.

The list sub-package provides functions to assist in decoding lists stored as strings in configuration sources.

The tree sub-package provides a Get method to get a value from a map[string]interface{} or map[interface{}]interface{}.

Value

GoDoc

The Value contains the raw value for a field, as returned by the Getter and Config, and provides methods to convert the raw value into particular types.

Supported target types

config provides methods to convert Values to the following types:

  • bool
  • int (specifically int64)
  • uint (specifically uint64)
  • float (specifically float64)
  • string
  • slice (values remain as interface{}, so []interface{})
  • slice of int ([]int64)
  • slice of uint ([]uint64)
  • slice of string ([]string)
  • duration (time.Duration)
  • time (time.Time)

The int and float types return the maximum possible width to prevent loss of information. The returned values can be range checked and assigned to narrower types by the application as required.

The cfgconv sub-package provides the functions config uses to perform the conversions from the interface{} returned by the Getter to the type requested by the application code. The cfgconv package is similar to the standard strconv package, but converts from interface{} instead of string. The conversions performed by cfgconv are as permissive as possible, given the data types involved, to allow for Getters mapping from formats that may not directly support the requested type.

Direct gets of maps and structs are not supported, but the following composite types can be unmarshalled from the configuration, with the configuration keys being drawn from struct field names or map keys:

  • slice of struct (using Unmarshal)
  • map (specifically map[string]interface{} using UnmarshalToMap)
  • struct (using Unmarshal)

Unmarshalling into nested structs is supported, as is overiding struct field names using tags.

Advanced API

The intent is for the core API to handle the majority of use cases, but the advanced sections of the API provide additional functionality for more complicated environments.

Sub-config

A sub-tree of the configuration contained in a Config, such as the configuration specific to a sub-module, can be retreived from a parent Config using Config.GetConfig.

For example the configuration for a Postgress client may be contained in a tree under "db.postgres" in my application configuration. This could be retreived using:

    pgCfg := cfg.GetConfig("db.postgres")
    pg := pgClient.New(pgCfg)

The sub-module, in this case the postgress client, can then be presented with its configuration without any knowledge of the application in which it is contained.

Watchers

Dynamic changes to configuration can be monitored by adding a watcher, either on a particular key, using Config.NewKeyWatcher, or the complete configuration using Config.NewWatcher.

Getters may optionally support the WatchableGetter interface to indicate that it supports monitoring the underlying source for changes. This is typically enabled via a Getter construction option called WithWatcher.

Of the supplied Getters, only file loader and the etcd currently support watchers.

Error Handling Policy

The default error handling behaviour of the core API commands is as follows:

API Method Error Behaviour
Config.Get Get error returned with zero Value.
Config.MustGet Get error causes panic 💥.
Value.X (conversions) Conversion error returns the zero value for target type.

For example the following code will panic if the pin config is not found, but will return 0 if it is found but cannot be converted to the int as expected:

    c := config.New(getter)
    pin := c.MustGet("pin").Int()

These behaviours can be overriden globally to the Config using ConfigOptions, and per Get using ValueOptions.

Option ConfigOption ValueOption Behaviour
WithMust Panic 💥 on error.
WithErrorHandler Install error handler for both Config.Get and Value conversion errors. When applied to a Config, the error handler is propagated to any Values created by the Config.Get unless overridden by ValueOptions in the Get.
WithGetErrorHandler Install handler for Config.Get errors
WithValueErrorHandler Install handler for Value conversion errors. This option is passed to the Config.New and is propagated to any Values created by the Config.Get unless overridden by ValueOptions in the Get.

Error handlers are passed the error, which they process as appropriate, and return an error that replaces the original. This may be nil if the handler wants to absorb the error. This is particularly relevent for Config.MustGet, which wraps Config.Get and converts any error to a panic, as the error returned by the get error handler is the error checked by Config.MustGet.

Overlays

A collection of Getters can be formed into an Overlay. An overlay presents an ordered list of Getters as a new Getter. The overlay searches for the key in each of the Getters in turn and returns the first value found. The Getters contained in the overlay, and their order, is specified by the application and is fixed during construction.

The Overlay can be considered an immutable Stack.

Stacks

A collection of Getters can be formed into a Stack. A stack presents an ordered list of Getters as a new Getter. The stack searches for the key in each of the Getters in turn and returns the first value found. Additional Getters can be safely added to either end of the Stack at runtime.

The Stack can be considered a mutable Overlay.

Decorators

Getters may be wrapped in Decorators, such as the WithAlias or WithFallback, to perform key translations before the key is passed to the Getter, or to manipulate the value before returning it to the Config.

A number of decorators are provided including:

Decorator Purpose
Alias Map a key that does not exist in the configuation to one that does
Fallback Provide a fallback Getter to be used when a key is not found in the decorated Getter
Graft Graft the root of a Getter that only provides a sub-config into the config
KeyReplacer Perform string replacements on keys before they are passed to the decorated Getter
MustGet Panic if the key is not found in the decorated Getter
Prefix Add a prefix to keys be for passing them to the decorated Getter
RegexAlias Map all keys that match a regex to a fixed key
Trace Pass values returned from the Getter to a provided function
UpdateHandler Perform transformations on values returned by a GetterWatcher

Decorators can be added to the Getter before it is provided to the Config. e.g.:

    a := config.NewAlias()
    c := config.New(config.Decorate(g, config.WithAlias(a)))
    a.Append(newKey, oldKey)
Alias

The WithAlias decorator provides aliases that map from a new key to an old key.

When searching for configuration parameters at each Getter, config first fetches the new key, and if that fails then tries any aliases to old keys. Aliases are ignored by the search if the parameter is found with the new key.

Each new key may be aliased to multiple old keys, and old keys may be aliased by multiple new keys.

Aliases have a number of potential uses:

  • Migration

    With aliases from a new layout to an old, the application can support both old and new configuration layouts at once, allowing users to upgrade their configurations at their convenience. Once all users have migrated to the new layout, the aliases can be removed in subsequent releases.

  • DRY

    A configuration parameter may be shared by multiple subsystems. Rather than replicating the value throughout the configuration for each subsystem, an alias from one to the other allows a single parameter value to appear to be located in multiple places.

  • Overridable Defaults

    A configuration parameter can be aliased to a default value, and will take the value from the alias (default) unless the parameter is explicitly set itself.

    This also allows default configuration values to be exposed in the configuration file rather than embedded in the application.

Fallback

The WithFallback decorator provides a fallback Getter to use if the configuration is not found in the decorated Getter.

Graft

The WithGraft decorator relocates the root of the decorated Getter into a node of the configuration tree. This allows a Getter that only provides part of the configuration tree to be grafted into the larger tree.

KeyReplacer

The WithKeyReplacer decorator attaches a replacer which may performs a substitution on the key before it is presented to the Getter.

MustGet

The WithMustGet decorator panics if the key cannot be found by the Getter.

This takes priority over the global error handling performed by the Config, as its checking effectively occurs before the Get returns to the Config.

Prefix

The WithPrefix decorator can be considered is a special case of WithKeyReplacer that prefixes the key with a fixed string. This can be used to move a Getter deeper into the configuration tree, for example if the configuration only requires a sub-config from a larger configuration.

This is the opposite of Graft.

RegexAlias

The WithRegexAlias decorator provides alias mappings similar to Alias, but the matching pattern is a regular expression instead of an exact match.

In addition to the uses of plain aliases, regex aliases can be used for setting default values for fields in array elements. e.g. this alias

    r := config.NewRegexAlias()
    r.Append(`somearray\[\d+\](.*)`, "somearray[0]$1")
    c := config.New(config.Decorate(g, config.WithRegexAlias(r)))

defaults all fields in the array elements to the values of the first element of the same array.

The regex form of alias requires more processing than plain aliases, and so is split out into a separate decorator. If you don't need regexes then use the plain aliases instead.

Trace

The WithTrace decorator attaches a function which is called with the parameters and return values of any call to the Getter. This could be used for logging and diagnostics, such as determining what configuration keys are retrieved by an application.

UpdateHandler

The WithUpdateHandler decorator adds a handler function to a Getter that can process updates from the Getter before they are returned to the watcher. This allows any decoration that would normally be applied to the Get path to be applied to the watcher path.

Background Concepts

Config Tree

The configuration is presented to the application as a key/value store. Conceptually the configuration parameters are located in a tree, where the key defines the path to the parameter from the root of the tree. The key is a list of nodes followed by the name of the leaf. The node and leaf names are joined with a separator, which by default is '.', to form the key. e.g. log.verbosity identifies the verbosity leaf in the log node.

Simple configurations may contain only a root node. More complex configurations may include nodes corresponding to the configuration of contained objects or subsystems.

config does not enforce a particular case on keys, so applications can choose their preferred case. Keys should be considered case sensitive by the application, as config considers keys that differ only by case to be distinct.

Arrays, other than arrays of structs, are considered leaves and can be retrieved whole. Additionally, array elements can be referenced with keys of the form a[i] where a is the key of the whole array and i is the zero-based integer index into the array. The size of the array can be referenced with a key of form a[]. e.g.

    ports := c.MustGet("ports").UintSlice()

    // equivalently....
    size := int(c.MustGet("ports[]").Int())
    for i := 0; i < size; i++ {
        // get each port sequentially...
        ports[i] = c.MustGet(fmt.Sprintf("ports[%d]", i)).Uint()
    }

Examples

The following examples, and examples of more complex usage, can be found in the example directory.

Usage

The following is an example of setting up a configuration using a number of sources (env, flag, JSON file, and a default map) and retrieving configuration parameters of various types. The Getters are added to a Stack so the search order will be:

  • flag
  • env
  • JSON file
  • default map

Note that configuration from initial sources can be used when setting up subsequent sources, e.g. the env.prefix can be overridden by flags (--env-prefix), and the JSON config filename can be specified by either flag (-c or --config-file) or env (MYAPP_CONFIG_FILE).

func main() {
    defaultConfig := dict.New(dict.WithMap(map[string]interface{}{
        "name":          "myapp",
        "env.prefix":    "MYAPP_",
        "config.file":   "myapp.json",
        "sm.pin":        27,
        "sm.period":     "250ms",
        "sm.thresholds": []int8{23, 45, 64},
    }))
    // from flags and defaults...
    cfg := config.New(
        pflag.New(pflag.WithFlags([]pflag.Flag{{Short: 'c', Name: "config-file"}})),
        config.WithDefault(defaultConfig))

    // and from environment...
    prefix := cfg.MustGet("env.prefix").String()
    cfg.Append(env.New(env.WithEnvPrefix(prefix)))

    // and from config file...
    cf := cfg.MustGet("config.file").String()
    cfg.Append(blob.New(file.New(cf), json.NewDecoder(), blob.MustLoad()))

    // read a config field from the root config
    name := cfg.MustGet("name").String()

    // to pass nested config to a sub-module...
    smCfg := cfg.GetConfig("sm")
    pin := smCfg.MustGet("pin").Uint()
    period := smCfg.MustGet("period").Duration()
    thresholds := smCfg.MustGet("thresholds").IntSlice()

    fmt.Println(cf, name, pin, period, thresholds)

    // or using Unmarshal to populate a config struct...
    type SMConfig struct {
        Pin        uint
        Period     time.Duration
        Thresholds []int
    }
    sc := SMConfig{}
    cfg.Unmarshal("sm", &sc)
    fmt.Println(cf, name, sc)
}

In this example, the config file name for myapp, with key config.file, could be set to "myfile.json" with any of these invocations:

# short flag
myapp -c myfile.json

# long flag
myapp --config-file=myfile.json

# environment
MYAPP_CONFIG_FILE="myfile.json" myapp

# environment with overridden prefix
APP_CONFIG_FILE="myfile.json" myapp --env.prefix=APP_
Key Watcher

This example watches a configuration file and prints updates to the configuration key "somevariable" whenever its value is changed.

func main() {
    c := config.New(blob.New(file.New("config.json", file.WithWatcher()), json.NewDecoder()))

    done := make(chan struct{})
    defer close(done)
    // watcher goroutine
    go func() {
        w := c.NewKeyWatcher("somevariable")
        for {
            v, err := w.Watch(done)
            if err != nil {
                log.Println("watch error:", err)
                return
            }
            log.Println("got update:", v.Int())
        }
    }()
    // main thread
    time.Sleep(time.Minute)
    log.Println("finished.")
}

This is a simple example that minimises error handling for brevity. The implementation of the watcher goroutine and its interactions with other goroutines may vary to suit your application.

A watcher for the whole configuration is very similar. An example can be found in the examples directory.

Documentation

Overview

Package config provides tools to retrieve configuration from various sources and present it to the application through a unified API.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrCanceled indicates the Watch has been canceled.
	ErrCanceled = errors.New("config: canceled")
	// ErrClosed indicates the Config has been closed.
	ErrClosed = errors.New("config: closed")
	// ErrInvalidStruct indicates Unmarshal was provided an object to populate
	// which is not a pointer to struct.
	ErrInvalidStruct = errors.New("unmarshal: provided obj is not pointer to struct")
)
View Source
var WithMust = ErrorHandlerOption{func(err error) error {
	panic(err)
}}

WithMust makes an object panic on error. For Config this applies to Get and is propagated to returned Values. For Value this applies to all type conversions.

View Source
var WithMustGet = func(g Getter) Getter {
	return mustDecorator{getterDecorator{g}}
}

WithMustGet provides a Decorator that panics if a key is not found by the decorated Getter.

View Source
var WithZeroDefaults = ErrorHandlerOption{func(err error) error {
	return nil
}}

WithZeroDefaults makes an object ignore errors and instead return zeroed default values. For Config this applies to Get and is propagated to returned Values. For Value this applies to all type conversions.

Functions

This section is empty.

Types

type Alias

type Alias struct {
	// contains filtered or unexported fields
}

Alias provides a mapping from a key to a set of old or alternate keys.

func NewAlias

func NewAlias(options ...aliasOption) *Alias

NewAlias creates an Alias.

func (*Alias) Append

func (a *Alias) Append(new, old string)

Append adds an alias from the new key to the old. If aliases already exist for the new key then this appended to the end of the existing list.

func (*Alias) Get

func (a *Alias) Get(g Getter, key string) (interface{}, bool)

Get calls the Getter, and if that fails tries aliases to other keys.

func (*Alias) Insert

func (a *Alias) Insert(new, old string)

Insert adds an alias from the new key to the old. If aliases already exist for the new key then this inserted to the beginning of the existing list.

func (Alias) NewWatcher

func (g Alias) NewWatcher(done <-chan struct{}) GetterWatcher

NewWatcher implements the WatchableGetter interface.

type Config

type Config struct {
	// contains filtered or unexported fields
}

Config is a wrapper around a Getter that provides a set of conversion functions that return the requested type, if possible, or an error if not.

func New added in v0.2.0

func New(g Getter, options ...Option) *Config

New creates a new Config with minimal initial state.

func (*Config) Append added in v0.2.0

func (c *Config) Append(g Getter)

Append adds a getter to the end of the list of getters searched by the config, but still before a default getter specified by WithDefault. This function is not safe to call from multiple goroutines, and should only be called to set up configuration in a single goroutine before passing the final config to other goroutines.

func (*Config) Close

func (c *Config) Close() error

Close releases any resources allocated to the Config including cancelling any actve watches.

func (*Config) Get

func (c *Config) Get(key string, opts ...ValueOption) (Value, error)

Get gets the raw value corresponding to the key. Returns a zero Value and an error if the value cannot be retrieved.

func (*Config) GetConfig

func (c *Config) GetConfig(node string, options ...Option) *Config

GetConfig gets the Config corresponding to a subtree of the config, where the node identifies the root node of the config returned.

func (*Config) Insert added in v0.2.0

func (c *Config) Insert(g Getter)

Insert adds a getter to the beginning of the list of getters searched by the config. This function is not safe to call from multiple goroutines, and should only be called to set up configuration in a single goroutine before passing the final config to other goroutines.

func (*Config) MustGet

func (c *Config) MustGet(key string, opts ...ValueOption) Value

MustGet gets the value corresponding to the key, or panics if the key is not found. This is a convenience wrapper that allows chaining of calls to value conversions when the application is certain the config field will be present.

func (*Config) NewKeyWatcher

func (c *Config) NewKeyWatcher(key string, opts ...ValueOption) *KeyWatcher

NewKeyWatcher creates a watch on the given key. The key should correspond to a field, not a node.

func (*Config) NewWatcher

func (c *Config) NewWatcher() *Watcher

NewWatcher creates a watch on the whole configuration.

func (*Config) Unmarshal

func (c *Config) Unmarshal(node string, obj interface{}) (rerr error)

Unmarshal a section of the config tree into a struct.

The node identifies the section of the tree to unmarshal. The obj is a pointer to a struct with fields corresponding to config values. The config values will be converted to the type defined in the corresponding struct fields. Overflow checks are performed during conversion to ensure the value returned by the getter can fit within the designated field.

By default the config field names are drawn from the struct field, converted to LowerCamelCase (as per typical JSON naming conventions). This can be overridden using `config:"<name>"` tags.

Struct fields which do not have corresponding config fields are ignored, as are config fields which have no corresponding struct field.

The error identifies the first type conversion error, if any.

func (*Config) UnmarshalToMap

func (c *Config) UnmarshalToMap(node string, objmap map[string]interface{}) (rerr error)

UnmarshalToMap unmarshals a section of the config tree into a map[string]interface{}.

The node identifies the section of the tree to unmarshal. The objmap keys define the fields to be populated from config. If non-nil, the config values will be converted to the type already contained in the map. If nil then the value is set to the raw value returned by the Getter.

Nested objects can be populated by adding them as map[string]interface{}, with keys set corresponding to the nested field names.

Map keys which do not have corresponding config fields are ignored, as are config fields which have no corresponding map key.

The error identifies the first type conversion error, if any.

type Decorator

type Decorator func(Getter) Getter

Decorator is a func that takes one Getter and returns a decorated Getter.

func WithAlias

func WithAlias(a *Alias) Decorator

WithAlias provides a decorator that calls the Getter, and falls back to a set of aliases if the lookup of the key fails.

func WithFallback added in v0.2.0

func WithFallback(d Getter) Decorator

WithFallback provides a Decorator that falls back to a default Getter if the key is not found in the decorated Getter.

func WithGraft

func WithGraft(prefix string) Decorator

WithGraft returns a decorator that attaches the root of the decorated Getter to a node in the config space. The prefix defines where the root node of the getter is located in the config space. The prefix must include any separator prior to the first field.

e.g. with a prefix "a.module.", reading the key "a.module.field" from the WithGraft will return the "field" from the wrapped Getter.

func WithKeyReplacer

func WithKeyReplacer(r keys.Replacer) Decorator

WithKeyReplacer provides a decorator which performs a transformation on the key using the ReplacerFunc before calling the Getter.

func WithPrefix

func WithPrefix(prefix string) Decorator

WithPrefix provides a Decorator that adds a prefix to the key before calling the Getter. This is a common special case of KeyReplacer where the key is prefixed with a fixed string.

func WithRegexAlias

func WithRegexAlias(r *RegexAlias) Decorator

WithRegexAlias provides a decorator that calls the Getter, and falls back to a set of regular expression aliases if the lookup of the key fails.

func WithTrace

func WithTrace(t TraceFunc) Decorator

WithTrace provides a decorator that calls the Getter, and then calls a TraceFunc with the result.

func WithUpdateHandler

func WithUpdateHandler(handler UpdateHandler) Decorator

WithUpdateHandler adds an update processing decorator to a Getter.

type DefaultOption added in v0.2.0

type DefaultOption struct {
	// contains filtered or unexported fields
}

DefaultOption defines default configuration uses as a fall back if a field is not returned by the main getter.

func WithDefault

func WithDefault(d Getter) DefaultOption

WithDefault is an Option that sets the default configuration. If applied multiple times, the earlier defaults are ignored.

type DefaultValueOption added in v0.5.0

type DefaultValueOption struct {
	// contains filtered or unexported fields
}

DefaultValueOption defines a default value used as a fall back if a field is not found in the config.

func WithDefaultValue added in v0.5.0

func WithDefaultValue(defVal interface{}) DefaultValueOption

WithDefaultValue is an Option that sets the default value for an individual field.

type ErrorHandler

type ErrorHandler func(error) error

ErrorHandler handles an error. The passed error is processed and an error, which may be the same or different, is returned. The returned error may be nil to indicate the error has been handled.

type ErrorHandlerOption

type ErrorHandlerOption struct {
	// contains filtered or unexported fields
}

ErrorHandlerOption defines the handler for errors.

func WithErrorHandler

func WithErrorHandler(e ErrorHandler) ErrorHandlerOption

WithErrorHandler is an Option that sets the error handling for a Config or Value. For Config this applies to Get and is propagated to returned Values. For Value this applies to all type conversions.

type GetErrorHandlerOption added in v0.2.0

type GetErrorHandlerOption struct {
	// contains filtered or unexported fields
}

GetErrorHandlerOption defines the handler for errors returned by Gets.

func WithGetErrorHandler added in v0.2.0

func WithGetErrorHandler(e ErrorHandler) GetErrorHandlerOption

WithGetErrorHandler is an Option that sets the error handling for a Config Gets.

type Getter

type Getter interface {
	// Get the value of the named config leaf key.
	// Also returns an ok, similar to a map read, to indicate if the value was
	// found.
	// The type underlying the returned interface{} must be convertable to the
	// expected type by cfgconv.
	//
	// Get does not need to support getting of objects, as returning of complete
	// objects is neither supported nor required.
	//
	// But it does support getting of arrays.
	// For arrays, referenced by the array name say "ax", a []interface{} must
	// be returned.
	// Array elements are referenced using keys of form "ax[idx]", where idx is
	// the zero-based index into the array.
	// The length of the array is returned by a key of form "ax[]".
	// If the getter only contains part of the array then it should return only
	// the elements it contains, not "ax" or "ax[]".
	//
	// For arrays of objects the array must be returned, to be consistent with
	// other arrays, but the elements may be nil.
	//
	// Must be safe to call from multiple goroutines.
	Get(key string) (value interface{}, found bool)
}

Getter specifies the minimal interface for a configuration Getter.

A Getter must be safe for concurrent use by multiple goroutines.

func Decorate

func Decorate(g Getter, dd ...Decorator) Getter

Decorate applies an ordered list of decorators to a Getter. The decorators are applied in reverse order, to create a decorator chain with the first decorator being the first link in the chain. When the returned getter is used, the first decorator is called first, then the second, etc and finally the decorated Getter itself.

func Overlay

func Overlay(gg ...Getter) Getter

Overlay attempts a get using a number of Getters, in the order provided, returning the first result found. This can be considered an immutable form of Stack.

type GetterAsOption added in v0.2.0

type GetterAsOption struct {
}

GetterAsOption allows a Getter to be passed to New as an option.

type GetterUpdate

type GetterUpdate interface {
	Commit()
}

GetterUpdate contains an update from a getter.

type GetterWatcher

type GetterWatcher interface {
	Update() <-chan GetterUpdate
}

GetterWatcher contains channels returning updates and errors from Getter watchers.

type KeyWatcher

type KeyWatcher struct {
	// contains filtered or unexported fields
}

KeyWatcher watches a particular key/value, with the next returning changed values. The KeyWatcher should not be called from multiple goroutines simulataneously. If you need to watch the key in multiple goroutines then create a KeyWatcher per goroutine.

func (*KeyWatcher) Watch

func (w *KeyWatcher) Watch(done <-chan struct{}) (Value, error)

Watch returns the next value of the watched field. On the first call it immediately returns the current value. On subsequent calls it blocks until the value changes or the done is closed. Returns an error if the watch was ended unexpectedly. Watch should only be called once at a time - it does not support being called by multiple goroutines simultaneously.

type NotFoundError

type NotFoundError struct {
	Key string
}

NotFoundError indicates that the Key could not be found in the config tree.

func (NotFoundError) Error

func (e NotFoundError) Error() string

type Notifier

type Notifier struct {
	// contains filtered or unexported fields
}

Notifier provides broadcast signalling of an anonymous event. It provides many to many connectivity - any number of sources may trigger the notification and any number of sinks may wait on it.

func NewNotifier

func NewNotifier() *Notifier

NewNotifier creates and returns a new Signal.

func (*Notifier) Notified

func (s *Notifier) Notified() <-chan struct{}

Notified returns a channel which is closed when the signal is triggered.

func (*Notifier) Notify

func (s *Notifier) Notify()

Notify triggers the signal event.

type Option

type Option interface {
	// contains filtered or unexported methods
}

Option is a construction option for a Config.

type RegexAlias

type RegexAlias struct {
	// contains filtered or unexported fields
}

RegexAlias provides a mapping from a key to an old key. New keys are expected to contain regular expressions.

func NewRegexAlias

func NewRegexAlias() *RegexAlias

NewRegexAlias creates a RegexAlias.

func (*RegexAlias) Append

func (r *RegexAlias) Append(new, old string) error

Append adds an alias from a regular expression matching a new key to the old.

func (*RegexAlias) Get

func (r *RegexAlias) Get(g Getter, key string) (interface{}, bool)

Get calls the Getter, and if that fails tries aliases to other keys.

type SeparatorOption

type SeparatorOption struct {
	// contains filtered or unexported fields
}

SeparatorOption defines the string that separates tiers in keys.

func WithSeparator

func WithSeparator(s string) SeparatorOption

WithSeparator is an Option that sets the config namespace separator. This is an option to ensure it can only set at construction time, as changing it at runtime makes no sense.

type Stack

type Stack struct {
	// contains filtered or unexported fields
}

Stack attempts a get using a list of Getters, in the order provided, returning the first result found. Additional layers may be added to the stack at runtime.

func NewStack

func NewStack(gg ...Getter) *Stack

NewStack creates a Stack.

func (*Stack) Append

func (s *Stack) Append(g Getter)

Append appends a getter to the set of getters for the Stack. This means this getter is only used as a last resort, relative to the existing getters.

func (*Stack) Get

func (s *Stack) Get(key string) (interface{}, bool)

Get gets the raw value corresponding to the key. It iterates through the list of getters, searching for a matching key. Returns the first match found, or an error if none is found.

func (*Stack) Insert

func (s *Stack) Insert(g Getter)

Insert inserts a getter to the set of getters for the Stack. This means this getter is used before the existing getters.

func (*Stack) NewWatcher

func (s *Stack) NewWatcher(done <-chan struct{}) GetterWatcher

NewWatcher implements the WatchableGetter interface.

type TagOption

type TagOption struct {
	// contains filtered or unexported fields
}

TagOption defines the string that identifies field names during unmarshaling.

func WithTag

func WithTag(t string) TagOption

WithTag is an Option that sets the config unmarshalling tag. The default tag is "config".

type TraceFunc

type TraceFunc func(k string, v interface{}, ok bool)

TraceFunc traces the parameters and results of a call to a Getter.

type UnmarshalError

type UnmarshalError struct {
	Key string
	Err error
}

UnmarshalError indicates an error occurred while unmarhalling config into a struct or map. The error indicates the problematic Key and the specific error.

func (UnmarshalError) Error

func (e UnmarshalError) Error() string

type UpdateCommit

type UpdateCommit func()

UpdateCommit is a function that commits an update to a getter. After the call the change becomes visible to Get.

type UpdateHandler

type UpdateHandler func(done <-chan struct{}, in <-chan GetterUpdate, out chan<- GetterUpdate)

UpdateHandler receives an update, performs some transformation on it, and forwards (or not) the transformed update. Must return if either the done or in channels are closed. May close the out chan to indicate that no further updates are possible.

type Value

type Value struct {
	// contains filtered or unexported fields
}

Value contains a value read from the configuration.

func NewValue added in v0.2.0

func NewValue(value interface{}, options ...ValueOption) Value

NewValue creates a Value given a raw value. Values are generally returned by Config.Get or Config.GetMust, so you probably don't want to be calling this function.

func (Value) Bool

func (v Value) Bool() bool

Bool converts the value to a bool. Returns false if conversion is not possible.

func (Value) Duration

func (v Value) Duration() time.Duration

Duration gets the value corresponding to the key and converts it to a time.Duration. Returns 0 if conversion is not possible.

func (Value) Float

func (v Value) Float() float64

Float converts the value to a float64. Returns 0 if conversion is not possible.

func (Value) Int

func (v Value) Int() int

Int converts the value to an int. Returns 0 if conversion is not possible.

func (Value) Int64 added in v0.4.0

func (v Value) Int64() int64

Int64 converts the value to an int64. Returns 0 if conversion is not possible.

func (Value) Int64Slice added in v0.4.0

func (v Value) Int64Slice() []int64

Int64Slice converts the value to a slice of int64s. Returns nil if conversion is not possible.

func (Value) IntSlice

func (v Value) IntSlice() []int

IntSlice converts the value to a slice of ints. Returns nil if conversion is not possible.

func (Value) Slice

func (v Value) Slice() []interface{}

Slice converts the value to a slice of []interface{}. Returns nil if conversion is not possible.

func (Value) String

func (v Value) String() string

String converts the value to a string. Returns an empty string if conversion is not possible.

func (Value) StringSlice

func (v Value) StringSlice() []string

StringSlice converts the value to a slice of string. Returns nil if conversion is not possible.

func (Value) Time

func (v Value) Time() time.Time

Time converts the value to a time.Time. Returns time.Time{} if conversion is not possible.

func (Value) Uint

func (v Value) Uint() uint

Uint converts the value to a uint. Returns 0 if conversion is not possible.

func (Value) Uint64 added in v0.4.0

func (v Value) Uint64() uint64

Uint64 converts the value to a iint64. Returns 0 if conversion is not possible.

func (Value) Uint64Slice added in v0.4.0

func (v Value) Uint64Slice() []uint64

Uint64Slice converts the value to a slice of uint64. Returns nil if conversion is not possible.

func (Value) UintSlice

func (v Value) UintSlice() []uint

UintSlice converts the value to a slice of uint. Returns nil if conversion is not possible.

func (Value) Value

func (v Value) Value() interface{}

Value returns the raw value.

type ValueErrorHandlerOption added in v0.2.0

type ValueErrorHandlerOption struct {
	// contains filtered or unexported fields
}

ValueErrorHandlerOption defines the error handler added to Values returned by Config Gets. These may be overridden by ValueOptions.

func WithValueErrorHandler added in v0.2.0

func WithValueErrorHandler(e ErrorHandler) ValueErrorHandlerOption

WithValueErrorHandler is an Option that sets the error handling for a Config Gets.

type ValueOption

type ValueOption interface {
	// contains filtered or unexported methods
}

ValueOption is a construction option for a Value.

type WatchableGetter

type WatchableGetter interface {
	// Create a watcher on the getter.
	// Watcher will exit if the done chan closes.
	// Watcher will send updates via the update channel.
	// Watcher will send terminal errors via the err channel.
	NewWatcher(done <-chan struct{}) GetterWatcher
}

WatchableGetter is the interface supported by Getters that may support being watched.

type Watcher

type Watcher struct {
	// contains filtered or unexported fields
}

Watcher provides a synchronous watch of the overall configuration state. The Watcher should not be called from multiple goroutines at a time. If you need to watch the config in multiple goroutines then create a Watcher per goroutine.

func (*Watcher) Watch

func (w *Watcher) Watch(done <-chan struct{}) error

Watch returns when the configuration has been changed or the done is closed. Returns an error if the watch was ended unexpectedly. Watch should only be called once at a time. To prevent races, multiple simultaneous calls are serialised. If you need to watch the config in multiple goroutines then create a Watcher per goroutine.

Directories

Path Synopsis
Package blob provides a getter that loads and decodes configuration from a source where the configuration is stored in a known format.
Package blob provides a getter that loads and decodes configuration from a source where the configuration is stored in a known format.
decoder
Package decoder contains decoders that convert blobs of configuration from raw bytes into map[string]interface{}.
Package decoder contains decoders that convert blobs of configuration from raw bytes into map[string]interface{}.
decoder/hcl
Package hcl provides a HCL format decoder for config.
Package hcl provides a HCL format decoder for config.
decoder/ini
Package ini provides an INI format decoder for config.
Package ini provides an INI format decoder for config.
decoder/json
Package json provides a JSON format decoder for config.
Package json provides a JSON format decoder for config.
decoder/properties
Package properties provides a Java properties format decoder for config.
Package properties provides a Java properties format decoder for config.
decoder/toml
Package toml provides a TOML format decoder for config.
Package toml provides a TOML format decoder for config.
decoder/yaml
Package yaml provides a YAML format decoder for config.
Package yaml provides a YAML format decoder for config.
loader
Package loader contains loaders that read blobs of configuration from various sources.
Package loader contains loaders that read blobs of configuration from various sources.
loader/bytes
Package bytes provides a loader from []byte for config.
Package bytes provides a loader from []byte for config.
loader/file
Package file provides a file loader for config.
Package file provides a file loader for config.
Package cfgconv provides type conversions from incoming configuration types to requested internal types.
Package cfgconv provides type conversions from incoming configuration types to requested internal types.
Package dict provides a simple Getter that wraps a key/value map.
Package dict provides a simple Getter that wraps a key/value map.
Package env provides an environment variable Getter for config.
Package env provides an environment variable Getter for config.
example
app
A simple app using a variety of config sources.
A simple app using a variety of config sources.
Package flag provides a command line Getter using Go's flag.
Package flag provides a command line Getter using Go's flag.
Package keys provides utilities to manipulate key strings.
Package keys provides utilities to manipulate key strings.
Package list contains helpers to convert values from strings to lists.
Package list contains helpers to convert values from strings to lists.
Package pflag provides a POSIX/GNU style style command line parser/config Getter.
Package pflag provides a POSIX/GNU style style command line parser/config Getter.
Package tree provides functions to get from common tree structures.
Package tree provides functions to get from common tree structures.

Jump to

Keyboard shortcuts

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