README

ozzo-config

GoDoc Build Status Coverage Status Go Report

Other languages

Description

ozzo-config is a Go package for handling configurations in Go applications. It supports

  • reading JSON (with comments), YAML, and TOML configuration files
  • merging multiple configurations
  • accessing any part of the configuration
  • configuring an object using a part of the configuration
  • adding new configuration file formats

Requirements

Go 1.2 or above.

Installation

Run the following command to install the package:

go get github.com/go-ozzo/ozzo-config

Getting Started

The following code snippet shows how you can use this package.

package main

import (
    "fmt"
    "github.com/go-ozzo/ozzo-config"
)

func main() {
    // create a Config object
    c := config.New()

    // load configuration from a JSON string
    c.LoadJSON([]byte(`{
        "Version": "2.0",
        "Author": {
            "Name": "Foo",
            "Email": "bar@example.com"
        }
    }`))

    // get the "Version" value, return "1.0" if it doesn't exist in the config
    version := c.GetString("Version", "1.0")

    var author struct {
        Name, Email string
    }
    // populate the author object from the "Author" configuration
    c.Configure(&author, "Author")

    fmt.Println(version)
    fmt.Println(author.Name)
    fmt.Println(author.Email)
    // Output:
    // 2.0
    // Foo
    // bar@example.com
}

Loading Configuration

You can load configuration in three ways:

c := config.New()

// load from one or multiple JSON, YAML, or TOML files.
// file formats are determined by their extensions: .json, .yaml, .yml, .toml
c.Load("app.json", "app.dev.json")

// load from one or multiple JSON strings
c.LoadJSON([]byte(`{"Name": "abc"}`), []byte(`{"Age": 30}`))

// load from one or multiple variables
data1 := struct {
    Name string
} { "abc" }
data2 := struct {
    Age int
} { 30 }
c.SetData(data1, data2)

When loading from multiple sources, the configuration will be obtained by merging them one after another recursively.

Accessing Configuration

You can access any part of the configuration using one of the Get methods, such as Get(), GetString(), GetInt(). These methods require a path parameter which is in the format of X.Y.Z and references the configuration value located at config["X"]["Y"]["Z"]. If a path does not correspond to a configuration value, a zero value or an explicitly specified default value will be returned by the method. For example,

// Retrieves "Author.Email". The default value "bar@example.com"
// should be returned if "Author.Email" is not found in the configuration.
email := c.GetString("Author.Email", "bar@example.com")

Changing Configuration

You can change any part of the configuration using the Set method. For example, the following code changes the configuration value config["Author"]["Email"]:

c.Set("Author.Email", "bar@example.com")

Configuring Objects

You can use a configuration to configure the properties of an object. For example, the configuration corresponding to the JSON structure {"Name": "Foo", "Email": "bar@example.com"} can be used to configure the Name and Email fields of a struct.

When configuring a nil interface, you have to specify the concrete type in the configuration via a type element in the configuration map. The type should also be registered first by calling Register() so that it knows how to create a concrete instance.

New Configuration File Formats

ozzo-config supports three configuration file formats out-of-box: JSON (can contain comments), YAML, and TOML. To support reading new file formats, you should modify the config.UnmarshalFuncMap variable by mapping a new file extension to the corresponding unmarshal function.

Documentation

Overview

    Package config provides configuration handling for applications.

    Example
    Output:
    
    

    Index

    Examples

    Constants

    This section is empty.

    Variables

    View Source
    var UnmarshalFuncMap = map[string]UnmarshalFunc{
    	".yaml": yaml.Unmarshal,
    	".yml":  yaml.Unmarshal,
    	".json": func(bytes []byte, data interface{}) (err error) {
    		if bytes, err = stripJSONComments(bytes); err != nil {
    			return
    		}
    		if err = json.Unmarshal(bytes, data); err != nil {
    			return
    		}
    		return nil
    	},
    	".toml": func(bytes []byte, data interface{}) error {
    		_, err := toml.Decode(string(bytes), data)
    		return err
    	},
    }

      UnmarshalFuncMap maps configuration file extensions to the corresponding unmarshal functions.

      Functions

      This section is empty.

      Types

      type Config

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

        Config represents a configuration that can be accessed or used to configure objects.

        A configuration is a hierarchy of maps and arrays. You may use a path in the dot format to access a particular configuration value in the hierarchy. For example, the path "Path.To.Xyz" corresponds to the value config["Path"]["To"]["Xyz"].

        You can also configure an object with a particular configuration value by calling the Configure() method, which sets the object fields with the corresponding configuration value.

        Config can be loaded from one or multiple JSON, YAML, or TOML files. Files loaded latter will be merged with the earlier ones. You may also directly populate Config with the data in memory.

        func New

        func New() *Config

          New creates a new Config object.

          func (*Config) Configure

          func (c *Config) Configure(v interface{}, path ...string) (err error)

            Configure configures the specified value.

            You may configured the value with the whole configuration data or a part of it by specifying the path to that part.

            To configure a struct, the configuration should be a map. A struct field will be assigned with a map value whose key is the same as the field name. If a field is also struct, it will be recursively configured with the corresponding map configuration.

            When configuring an interface, the configuration should be a map with a special "type" key. The "type" element specifies the type name registered by Register(). It allows the method to create a correct object given a type name.

            Note that the value to be configured must be passed in as a pointer. You may specify a path to use a particular part of the configuration to configure the value. If a path is not specified, the whole configuration will be used.

            Example
            Output:
            
            1.0-alpha
            /data
            

            func (*Config) Data

            func (c *Config) Data() interface{}

              Data returns the complete configuration data. Nil will be returned if the configuration has never been loaded before.

              func (*Config) Get

              func (c *Config) Get(path string, defaultValue ...interface{}) interface{}

                Get retrieves the configuration value corresponding to the specified path.

                The path uses a dotted format. A path "Path.To.Xyz" corresponds to the configuration value config["Path"]["To"]["Xyz"], provided both config["Path"] and config["Path"]["To"] are both valid maps. If not, a default value will be returned. If you do not specify a default value, nil will be returned. You may use array keys in the dotted format as well to access arrays in the configuration. For example, a path "Path.2.Xyz" corresponds to the value config["Path"][2]["Xyz"], if config["Path"] is an array and config["Path"][2] is a valid.

                If any part of the path corresponds to an invalid value (not a map/array, or is nil), the default value will be returned. If you do not specify a default value, nil will be returned.

                Note that if you specify a default value, the return value of this method will be automatically converted to the same type of the default value. If the conversion cannot be conducted, the default value will be returned.

                Example
                Output:
                
                v1
                300
                not found
                true
                100
                

                func (*Config) GetBool

                func (c *Config) GetBool(path string, defaultValue ...bool) bool

                  GetString retrieves the bool-typed configuration value corresponding to the specified path. Please refer to Get for the detailed usage explanation.

                  func (*Config) GetFloat

                  func (c *Config) GetFloat(path string, defaultValue ...float64) float64

                    GetString retrieves the float64-typed configuration value corresponding to the specified path. Please refer to Get for the detailed usage explanation.

                    func (*Config) GetInt

                    func (c *Config) GetInt(path string, defaultValue ...int) int

                      GetString retrieves the int-typed configuration value corresponding to the specified path. Please refer to Get for the detailed usage explanation.

                      func (*Config) GetInt64

                      func (c *Config) GetInt64(path string, defaultValue ...int64) int64

                        GetString retrieves the int64-typed configuration value corresponding to the specified path. Please refer to Get for the detailed usage explanation.

                        func (*Config) GetString

                        func (c *Config) GetString(path string, defaultValue ...string) string

                          GetString retrieves the string-typed configuration value corresponding to the specified path. Please refer to Get for the detailed usage explanation.

                          func (*Config) Load

                          func (c *Config) Load(files ...string) error

                            Load loads configuration data from one or multiple files.

                            If multiple configuration files are given, the corresponding configuration data will be merged sequentially according to the rules described in SetData().

                            Supported configuration file formats include JSON, YAML, and TOML. The file formats are determined by the file name extensions (.json, .yaml, .yml, .toml). The method will return any file reading or parsing errors.

                            Note that this method will NOT clear the existing configuration data.

                            Example
                            Output:
                            
                            

                            func (*Config) LoadJSON

                            func (c *Config) LoadJSON(data ...[]byte) error

                              LoadJSON loads new configuration data which are given as JSON strings.

                              If multiple JSON strings are given, the corresponding configuration data will be merged sequentially according to the rules described in SetData().

                              The method will return any JSON parsing error.

                              Note that this method will NOT clear the existing configuration data.

                              Example
                              Output:
                              
                              true
                              200
                              xyz
                              abc
                              

                              func (*Config) Register

                              func (c *Config) Register(name string, provider interface{}) error

                                Register associates a type name with a provider that creates an instance of the type. The provider must be a function with a single output. Register is mainly needed when calling Configure() to configure an object and create new instances of the specified types.

                                Example
                                Output:
                                
                                

                                func (*Config) Set

                                func (c *Config) Set(path string, value interface{}) error

                                  Set sets the configuration value at the specified path.

                                  The path uses a dotted format. A path "Path.To.Xyz" corresponds to the configuration value config["Path"]["To"]["Xyz"], while "Path.2.Xyz" corresponds to config["Path"][2]["Xyz"]. If a value already exists at the specified path, it will be overwritten with the new value. If a partial path has no corresponding configuration value, one will be created. For example, if the map config["Path"] has no "To" element, a new map config["Path"]["To"] will be created so that we can set the value of config["Path"]["To"]["Xyz"].

                                  The method will return an error if it is unable to set the value for various reasons, such as the new value cannot be added to the existing array or map.

                                  Example
                                  Output:
                                  
                                  2
                                  100
                                  true
                                  

                                  func (*Config) SetData

                                  func (c *Config) SetData(data ...interface{})

                                    SetData sets the configuration data.

                                    If multiple configurations are given, they will be merged sequentially. The following rules are taken when merging two configurations C1 and C2: A). If either C1 or C2 is not a map, replace C1 with C2; B). Otherwise, add all key-value pairs of C2 to C1; If a key of C2 is also found in C1, merge the corresponding values in C1 and C2 recursively.

                                    Note that this method will clear any existing configuration data.

                                    Example
                                    Output:
                                    
                                    abc
                                    zzz
                                    true
                                    

                                    type ConfigPathError

                                    type ConfigPathError struct {
                                    	Path    string
                                    	Message string
                                    }

                                      ConfigPathError describes a path which cannot be used to set a configuration value.

                                      func (*ConfigPathError) Error

                                      func (s *ConfigPathError) Error() string

                                        Error returns the error message represented by ConfigPathError

                                        type ConfigTargetError

                                        type ConfigTargetError struct {
                                        	Value reflect.Value
                                        }

                                          ConfigTargetError describes a target value that cannot be configured

                                          func (*ConfigTargetError) Error

                                          func (e *ConfigTargetError) Error() string

                                            Error returns the error message represented by ConfigTargetError

                                            type ConfigValueError

                                            type ConfigValueError struct {
                                            	Path    string // path to the configuration value
                                            	Message string // the detailed error message
                                            }

                                              ConfigValueError describes a configuration that cannot be used to configure a target value

                                              func (*ConfigValueError) Error

                                              func (e *ConfigValueError) Error() string

                                                Error returns the error message represented by ConfigValueError

                                                type FileTypeError

                                                type FileTypeError string

                                                  FileTypeError describes the name of a file whose format is not supported.

                                                  func (FileTypeError) Error

                                                  func (s FileTypeError) Error() string

                                                    Error returns the error message represented by FileTypeError

                                                    type ProviderError

                                                    type ProviderError struct {
                                                    	Value reflect.Value
                                                    }

                                                      ProviderError describes a provider that was not appropriate for a type

                                                      func (*ProviderError) Error

                                                      func (e *ProviderError) Error() string

                                                        Error returns the error message represented by ProviderError

                                                        type UnmarshalFunc

                                                        type UnmarshalFunc func([]byte, interface{}) error

                                                          UnmarshalFunc parses the given configuration and populates it into the given variable.