gonfig

package module
v0.9.2-0...-a72a885 Latest Latest
Warning

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

Go to latest
Published: Aug 2, 2021 License: MIT Imports: 15 Imported by: 0

README

Gonfig

Go Reference Build Status codecov Go Report Card GitHub release Mentioned in Awesome Go

Tag-based configuration parser which loads values from different providers into typesafe struct.

Installation

This package needs go version 1.15+

go get -u github.com/miladabc/gonfig

Usage

package main

import (
    "fmt"
    "net/url"
    "time"

    "github.com/miladabc/gonfig"
)

// Unexported struct fields are ignored
type Config struct {
	Host     string
	Log      bool
	Expiry   int
	Port     uint
	Pi       float64
	Com      complex128
	Byte     byte
	Rune     rune
	Duration time.Duration
	Time     time.Time
	url      url.URL
	Redis    struct {
		Hosts []string
		Ports []int
	}
}

func main() {
	var c Config

	// Input argument must be a pointer to struct
	err := gonfig.Load().FromEnv().Into(&c)
	if err != nil {
		fmt.Println(err)
	}
}

Tags

All the tags are optional.

Config

config tag is used to change default key for fetching the value of field.

type Config struct {
	HostName string `config:"HOST"`
}

func main() {
	var c Config

	os.Setenv("HOST", "golang.org")
	gonfig.Load().FromEnv().Into(&c)
}

json, yaml and toml tags are used to change default key for fetching the value from file.

type Config struct {
	HostName string `json:"host" yaml:"host" toml:"host"`
}

func main() {
	var c Config

	gonfig.Load().FromFile("config.json").Into(&c)
}
Default

default tag is used to declare a default value in case of missing value.

type Config struct {
	Host url.URL `default:"golang.org"`
}
Required

required tag is used to make sure a value is present for corresponding field.
Fields are optional by default.

type Config struct {
	Host url.URL `required:"true"`
}
Ignore

ignore tag is used to skip populating a field. Ignore is false by default.

type Config struct {
	Ignored     int `ignore:"true"`
	AlsoIgnored int `config:"-"`
}
Expand

expand tag is used to expand value from OS environment variables.
Expand is false by default.

type Config struct {
	Expanded int `expand:"true" default:"${ENV_VALUE}"`
}

func main() {
	var c Config

	os.Setenv("ENV_VALUE", "123")
	gonfig.Load().FromEnv().Into(&c)
	fmt.Println(c.Expanded) // 123
}
Separator

separator tag is used to separate slice/array items.
Default separator is a single space.

type Config struct {
	List []int `separator:"," default:"1, 2, 3"`
}
Format

format tag is used for parsing time strings.
Default format is time.RFC3339.

type Config struct {
	Time time.Time `format:"2006-01-02T15:04:05.999999999Z07:00"`
}

Providers

Providers can be chained together and they are applied in the specified order.
If multiple values are provided for a field, last one will get applied.

Supported providers
  • Environment variables
  • files
    • .json
    • .yaml (.yml)
    • .toml
    • .env
func main() {
	var c Config

	gonfig.
		Load().
		FromEnv().
		FromFile("config.json").
		FromFile("config.yaml").
		FromFile("config.toml").
		FromFile(".env").
		AddProvider(CustomProvider).
		Into(&c)
}
Env Provider

Env provider will populate struct fields based on the hierarchy of struct.

type Config struct {
	PrettyLog bool
	Redis     struct {
		Host string
		Port int
	}
}

func main() {
	var c Config

	gonfig.
		Load().
		FromEnv().
		Into(&c)
}

It will check for following keys:

  • PRETTY_LOG
  • REDIS_HOST
  • REDIS_PORT

To change default settings, make an EnvProvider and add it to the providers list manually:

type Config struct {
	PrettyLog bool
	Redis     struct {
		Host string
		Port int
	}
}

func main() {
	var c Config

	ep := gonfig.EnvProvider{
		Prefix:         "APP_", // Default to ""
		SnakeCase:      false,  // Defaults to true
		UpperCase:      false,  // Defaults to true
		FieldSeparator: "__",   // Defaults to "_"
		Source:         ".env", // Defaults to OS env vars
		Required:       true,   // Defaults to false
	}

	gonfig.
		Load().
		AddProvider(&ep).
		Into(&c)
}

It will check for following keys in .env file:

  • APP_PrettyLog
  • APP_Redis__Host
  • APP_Redis__Port
File Provider

File provider uses third party parsers for parsing files, read their documentation for more info.

Custom Provider

You can use your own provider by implementing Provider interface and one or both Unmarshaler and Filler interfaces.

type CustomProvider struct{}

func (cp *CustomProvider) Name() string {
	return "custom provider"
}

func (cp *CustomProvider) UnmarshalStruct(i interface{}) error {
	// UnmarshalStruct receives a struct pointer and unmarshalls values into it.
	return nil
}

func (cp *CustomProvider) Fill(in *gonfig.Input) error {
	// Fill receives struct fields and set their values.
	return nil
}

func main() {
	var c Config

	gonfig.
		Load().
		AddProvider(new(CustomProvider)).
		Into(&c)
}

Supported types

Any other type except the followings, results an error

  • string
  • bool
  • int, int8, int16, int32, int64
  • uint, uint8, uint16, uint32, uint64
  • float32, float64
  • complex64, complex128
  • byte
  • rune
  • time.Duration
  • time.Time
  • url.URL
  • pointer, slice and array of above types
  • nested and embedded structs

TODO

Any contribution is appreciated :)

Documentation

Take a look at docs for more information.

License

The library is released under the MIT license.
Checkout LICENSE file.

Documentation

Index

Constants

View Source
const (
	JSON = ".json"
	YML  = ".yml"
	YAML = ".yaml"
	TOML = ".toml"
	ENV  = ".env"
)

Supported file extensions

Variables

View Source
var (
	// ErrUnsupportedType indicates unsupported struct field
	ErrUnsupportedType = errors.New("unsupported type")

	// ErrUnsupportedFileExt indicated unsupported file format
	// Only ".json", ".yml", ".yaml" and ".env" file types are supported
	ErrUnsupportedFileExt = errors.New("unsupported file extension")

	// ErrUnSettableField indicated unexported struct field
	ErrUnSettableField = errors.New("unSettable field")

	// ErrKeyNotFound is returned when no value found with specified key
	ErrKeyNotFound = errors.New("key not found")

	// ErrRequiredField indicates that Field is required but no value is provided
	ErrRequiredField = errors.New("field is required")

	// ErrParsing is returned in case of bad value
	ErrParsing = errors.New("failed parsing")

	// ErrValueOverflow indicates value overflow
	ErrValueOverflow = errors.New("value overflow")
)

Functions

This section is empty.

Types

type Config

type Config struct {
	// Providers are applied at the order specified
	// If multiple values are provided for a field, last one will get applied
	Providers []Provider
	// contains filtered or unexported fields
}

Config loads values from specified providers into given struct

func Load

func Load() *Config

Load creates a new Config object

func (*Config) AddProvider

func (c *Config) AddProvider(p Provider) *Config

AddProvider adds a Provider to Providers list

func (*Config) FromEnv

func (c *Config) FromEnv() *Config

FromEnv adds an EnvProvider to Providers list

func (*Config) FromFile

func (c *Config) FromFile(path string) *Config

FromFile adds a FileProvider to Providers list In case of .env file, it adds a EnvProvider to the list

func (*Config) Into

func (c *Config) Into(i interface{}) error

Into will apply all specified providers in order declared and validate final struct for required and default fields If multiple values are provided for a field, last one will get applied

type ConfigErrors

type ConfigErrors []error

ConfigErrors is collection of errors during populating the input struct

func (ConfigErrors) Error

func (ce ConfigErrors) Error() string

type ConfigTags

type ConfigTags struct {
	// Key to be used by providers to retrieve the needed value, defaults to field name.
	// Use "-" to ignore the field.
	Config string

	// json tag for json files
	Json string

	// yaml tag for yaml files
	Yaml string

	// toml tag for toml files
	Toml string

	// Default value for field.
	Default string

	// Specify if value should be present, defaults to false.
	Required bool

	// Specify if field should be ignored, defaults to false.
	Ignore bool

	// Specify if value should be expanded from env, defaults to false.
	Expand bool

	// Separator to be used for slice/array items, defaults to " ".
	Separator string

	// Format to be used for parsing time strings, defaults to time.RFC3339.
	Format string
}

ConfigTags indicates possible tags All of them are optional

type EnvProvider

type EnvProvider struct {
	// Prefix is used when finding values from environment variables, defaults to ""
	Prefix string

	// SnakeCase specifies whether to convert field names to snake_case or not, defaults to true
	SnakeCase bool

	// UpperCase specifies whether to convert field names to UPPERCASE or not, defaults to true
	UpperCase bool

	// FieldSeparator is used to separate field names, defaults to "_"
	FieldSeparator string

	// Source is used to retrieve environment variables
	// It can be either a path to a file or empty string, if empty OS will be used
	Source string

	// Whether to report error if env file is not found, defaults to false
	Required bool
}

EnvProvider loads values from environment variables to provided struct

func NewEnvProvider

func NewEnvProvider() *EnvProvider

NewEnvProvider creates a new EnvProvider

func (*EnvProvider) Fill

func (ep *EnvProvider) Fill(in *Input) error

Fill takes struct fields and fills their values

func (*EnvProvider) Name

func (ep *EnvProvider) Name() string

Name of provider

type Field

type Field struct {
	// Field value
	Value reflect.Value

	// Field tags
	Tags *ConfigTags

	// Slice of field names from root of struct all the way down to the field
	Path []string

	// IsSet specifies whether field value is set by one of the providers
	IsSet bool
}

Field information

type FileProvider

type FileProvider struct {
	// Path to file
	FilePath string

	// File will be decoded based on extension
	// .json, .yml(.yaml), .env and .toml file extensions are supported
	FileExt string

	// Whether to report error if file is not found, defaults to false
	Required bool
}

FileProvider loads values from file to provided struct

func NewFileProvider

func NewFileProvider(path string) *FileProvider

NewFileProvider creates a new FileProvider from specified path

func (*FileProvider) Fill

func (fp *FileProvider) Fill(in *Input) error

Fill takes struct fields and and checks if their value is set

func (*FileProvider) Name

func (fp *FileProvider) Name() string

Name of provider

func (*FileProvider) UnmarshalStruct

func (fp *FileProvider) UnmarshalStruct(i interface{}) error

UnmarshalStruct takes a struct pointer and loads values from provided file into it

type Filler

type Filler interface {
	Fill(in *Input) (err error)
}

Filler can be implemented by providers to receive struct fields and set their value

type Input

type Input struct {
	// Struct name is used for error messages
	Name string

	// Fields information
	Fields []*Field
}

Input stores information about given struct

func NewInput

func NewInput(i interface{}) (*Input, error)

NewInput validates and returns a new Input with all settable fields Input argument must be a non-nil struct pointer

func (*Input) SetValue

func (in *Input) SetValue(f *Field, value string) error

SetValue validates and sets the value of a struct field returns error in case of unSettable field or unsupported type

type InvalidInputError

type InvalidInputError struct {
	Value reflect.Value
}

An InvalidInputError describes an invalid argument passed to Into function The argument must be a non-nil struct pointer

func (*InvalidInputError) Error

func (e *InvalidInputError) Error() string

type Provider

type Provider interface {
	Name() string
}

Provider is used to provide values It can implement either Unmarshaler or Filler interface or both Name method is used for error messages

type Unmarshaler

type Unmarshaler interface {
	UnmarshalStruct(i interface{}) (err error)
}

Unmarshaler can be implemented by providers to receive struct pointer and unmarshal values into it

Jump to

Keyboard shortcuts

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