configuro

package module
v0.0.3 Latest Latest
Warning

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

Go to latest
Published: Sep 25, 2022 License: MIT Imports: 15 Imported by: 9

README



Opinionated configuration loading framework for Containerized and 12-Factor compliant applications.

Read configurations from Environment Variables, and/or Configuration Files. With support to Environment Variables Expanding and Validation Methods.

Mentioned in Awesome Go Go Doc Go Version Coverage Status Go Report GitHub license

Introduction

Configuro is an opinionated configuration loading and validation framework with not very much to configure. It defines a method for loading configurations without so many options for a straight-forward and simple code.

The method defined by Configuro allow you to implement 12-Factor's Config and it mimics how many mature applications do configurations (e.g Elastic, Neo4J, etc); and is also fit for containerized applications.


With Only with two lines of code, and zero setting up you get loading configuration from Config File, Overwrite values /or rely exclusively on Environment Variables, Expanding values using ${ENV} expressions, and validation tags.

Loading Configuration

1. Define Application configurations in a struct
  • Which Configuro will Load() the read configuration into.
2. Setting Configuration by Environment Variables.
  • Value for key database.password can be set by setting CONFIG_DATABASE_PASSWORD. (CONFIG_ default prefix can be changed)
  • If the key itself contains _ then replace with __ in the Environment Variable.
  • You can express Maps and Lists in Environment Variables by JSON encoding them. (e.g CONFIG: {"a":123, "b": "abc"})
  • You can provide a .env file to load environment variables that are not set by the OS.
3. Setting Configuration by Configuration File.
  • Defaults to config.yml; name and extension can be configured.
  • Supported extensions are .yml, .yaml, .json, and .toml.
4. Support Environment Variables Expanding.
  • Configuration Values can have ${ENV|default} expression that will be expanded at loading time.
  • Example host: www.example.com:%{PORT|3306} with 3306 being the default value if env ${PORT} is not set).
5. Validate Loaded Values
  • Configuro can validate structs recursively using Validation Tags.
  • By Implementing Validatable Interface Validate() error.
Notes
  • 📣 Values' precedence is OS EnvVar > .env EnvVars > Config File > Value set in Struct before loading.

Install

go get github.com/sherifabdlnaby/configuro
import "github.com/sherifabdlnaby/configuro"

Usage

1. Define You Config Struct.

This is the struct you're going to use to retrieve your config values in-code.

type Config struct {
    Database struct {
        Host     string
        Port     int
    }
    Logging struct {
        Level  string
        LineFormat string `config:"line_format"`
    }
}
  • Nested fields accessed with . (e.g Database.Host )
  • Use config tag to change field name if you want it to be different from the Struct field name.
  • All mapstructure tags apply to config tag for unmarshalling.
  • Fields must be public to be accessible by Configuro.
2. Create and Configure the Configuro.Config object.
    // Create Configuro Object with supplied options (explained below)
    config, err := configuro.NewConfig( opts ...configuro.ConfigOption )

    // Create our Config Struct
    configStruct := &Config{ /*put defaults config here*/ }

    // Load values in our struct
    err = config.Load(configStruct)
  • Create Configuro Object Passing to the constructor opts ...configuro.ConfigOption which is explained in the below sections.
  • This should happen as early as possible in the application.
3. Loading from Environment Variables
  • Values found in Environment Variables take precedence over values found in config file.
  • The key database.host can be expressed in environment variables as CONFIG_DATABASE_HOST.
  • If the key itself contains _ then replace them with __ in the Environment Variable.
  • CONFIG_ prefix can be configured.
  • You can express Maps and Lists in Environment Variables by JSON encoding them. (e.g CONFIG: {"a":123, "b": "abc"})
  • You can provide a .env file to load environment variables that are not set by the OS. (notice that .env is loaded globally in the application scope)

The above settings can be changed upon constructing the configuro object via passing these options.

    configuro.WithLoadFromEnvVars(EnvPrefix string)  // Enable Env loading and set Prefix.
    configuro.WithoutLoadFromEnvVars()               // Disable Env Loading Entirely
    configuro.WithLoadDotEnv(envDotFilePath string)  // Enable loading .env into Environment Variables
    configuro.WithoutLoadDotEnv()                    // Disable loading .env
4. Loading from Configuration Files
  • Upon setting up you will declare the config filepath.
    • Default filename => "config.yml"
  • Supported formats are Yaml, Json, and Toml.
  • Config file directory can be overloaded with a defined Environment Variable.
    • Default: CONFIG_DIR.
  • If file was not found Configuro won't raise an error unless configured too. This is you can rely 100% on Environment Variables.

The above settings can be changed upon constructing the configuro object via passing these options.

    configuro.WithLoadFromConfigFile(Filepath string, ErrIfFileNotFound bool)    // Enable Config File Load
    configuro.WithoutLoadFromConfigFile()                                        // Disable Config File Load
    configuro.WithEnvConfigPathOverload(configFilepathENV string)                // Enable Overloading Path with ENV var.
    configuro.WithoutEnvConfigPathOverload()                                     // Disable Overloading Path with ENV var.
5. Expanding Environment Variables in Config
  • ${ENV} and ${ENV|default} expressions are evaluated and expanded if the Environment Variable is set or with the default value if defined, otherwise it leaves it as it is.
config:
    database:
        host: xyz:${PORT:3306}
        username: admin
        password: ${PASSWORD}

The above settings can be changed upon constructing the configuro object via passing these options.

    configuro.WithExpandEnvVars()       // Enable Expanding
    configuro.WithoutExpandEnvVars()    // Disable Expanding
6. Validate Struct
    err := config.Validate(configStruct)
    if err != nil {
        return err
    }
  • Configuro Validate Config Structs using two methods.
    1. Using Validation Tags for quick validations.
    2. Using Validatable Interface that will be called on any type that implements it recursively, also on each element of a Map or a Slice.
  • Validation returns an error of type configuro.ErrValidationErrors if more than error occurred.
  • It can be configured to not recursively validate types with Validatable Interface. (default: recursively)
  • It can be configured to stop at the first error. (default: false)
  • It can be configured to not use Validation Tags. (default: false) The above settings can be changed upon constructing the configuro object via passing these options.
    configuro.WithValidateByTags()
    configuro.WithoutValidateByTags()
    configuro.WithValidateByFunc(stopOnFirstErr bool, recursive bool)
    configuro.WithoutValidateByFunc()
7. Miscellaneous
  • config and validate tag can be renamed using configuro.Tag(structTag, validateTag) construction option.

Built on top of

License

MIT License Copyright (c) 2020 Sherif Abdel-Naby

Contribution

PR(s) are Open and Welcomed.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

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

Config Loads and WithValidateByTags Arbitrary structs based on options (set at constructing)

func NewConfig

func NewConfig(opts ...ConfigOptions) (*Config, error)

NewConfig Create config Loader/Validator according to options.

func (*Config) Load

func (c *Config) Load(configStruct interface{}) error

Load load config into supported struct.

func (*Config) LoadKey added in v0.0.3

func (c *Config) LoadKey(key string, configStruct interface{}) error

Load load config with key into supported struct.

func (*Config) Validate

func (c *Config) Validate(configStruct interface{}) error

Validate Validates Struct using Tags and Any Fields that Implements the Validatable interface.

type ConfigOptions

type ConfigOptions func(*Config) error

ConfigOptions Modify Config Options Accordingly

func DefaultOptions added in v0.0.2

func DefaultOptions() []ConfigOptions

DefaultOptions Returns The Default Configuro Options

func KeyDelimiter added in v0.0.3

func KeyDelimiter(keyDelimiter string) ConfigOptions

KeyDelimiter Сhange default key delimiter.

func Tag

func Tag(structTag, validateTag string) ConfigOptions

Tag Change default tag.

func WithEnvConfigPathOverload added in v0.0.2

func WithEnvConfigPathOverload(configFilepathENV string) ConfigOptions

WithEnvConfigPathOverload Allow to override Config file Path with an Env Variable

func WithExpandEnvVars added in v0.0.2

func WithExpandEnvVars() ConfigOptions

WithExpandEnvVars Expand config values with ${ENVVAR} with the value of ENVVAR in environment variables. Example: ${DB_URI}:3201 ==> localhost:3201 (Where $DB_URI was equal "localhost" ) You can set default if ENVVAR is not set using the following format ${ENVVAR|defaultValue}

func WithLoadDotEnv added in v0.0.2

func WithLoadDotEnv(envDotFilePath string) ConfigOptions

WithLoadDotEnv Allow loading .env file (notice that this is application global not to this config instance only)

func WithLoadFromConfigFile added in v0.0.2

func WithLoadFromConfigFile(Filepath string, ErrIfFileNotFound bool) ConfigOptions

WithLoadFromConfigFile Load Config from file provided by filepath.

  • Supported Formats/Extensions (.yml, .yaml, .toml, .json)
  • ErrIfFileNotFound let you determine behavior when files is not found. Typically if you rely on Environment Variables you may not need to Error if file is not found.

func WithLoadFromEnvVars added in v0.0.2

func WithLoadFromEnvVars(EnvPrefix string) ConfigOptions

WithLoadFromEnvVars Load Configuration from Environment Variables if they're set.

  • Require Environment Variables to prefixed with the set prefix (All CAPS)
  • For Nested fields replace `.` with `_` and if key itself has any `_` replace it with `__` (e.g `config.host` to be `CONFIG_HOST`)
  • Arrays can be declared in environment variables using 1. comma separated list. 2. json encoded array in a string.
  • Maps and objects can be declared in environment using a json encoded object in a string.

func WithValidateByFunc added in v0.0.2

func WithValidateByFunc(stopOnFirstErr bool, recursive bool) ConfigOptions

WithValidateByFunc Validate struct by calling the Validate() function on every type that implement Validatable interface. - stopOnFirstErr will abort validation after the first error. - recursive will call Validate() on nested interfaces where the parent itself is also Validatable.

func WithValidateByTags added in v0.0.2

func WithValidateByTags() ConfigOptions

WithValidateByTags Validate using struct tags.

func WithoutEnvConfigPathOverload added in v0.0.2

func WithoutEnvConfigPathOverload() ConfigOptions

WithoutEnvConfigPathOverload Disallow overriding Config file Path with an Env Variable

func WithoutExpandEnvVars added in v0.0.2

func WithoutExpandEnvVars() ConfigOptions

WithoutExpandEnvVars Disable Expanding Environment Variables in Config.

func WithoutLoadDotEnv added in v0.0.2

func WithoutLoadDotEnv() ConfigOptions

WithoutLoadDotEnv disable loading .env file into Environment Variables

func WithoutLoadFromConfigFile added in v0.0.2

func WithoutLoadFromConfigFile() ConfigOptions

WithoutLoadFromConfigFile Disable loading configuration from a file.

func WithoutLoadFromEnvVars added in v0.0.2

func WithoutLoadFromEnvVars() ConfigOptions

WithoutLoadFromEnvVars will not load configuration from Environment Variables.

func WithoutValidateByFunc added in v0.0.2

func WithoutValidateByFunc() ConfigOptions

WithoutValidateByFunc Disable validating using Validatable interface.

func WithoutValidateByTags added in v0.0.2

func WithoutValidateByTags() ConfigOptions

WithoutValidateByTags Disable validate using struct tags.

type ErrValidationErrors added in v0.0.2

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

ErrValidationErrors Error that hold multiple errors.

func (*ErrValidationErrors) Errors added in v0.0.2

func (e *ErrValidationErrors) Errors() []error

Errors Return a list of Errors held inside ErrValidationErrors.

func (*ErrValidationErrors) Unwrap added in v0.0.2

func (e *ErrValidationErrors) Unwrap() error

Unwrap to support errors IS|AS

type ErrValidationFunc added in v0.0.2

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

ErrValidationFunc Error if validation failed by Validatable Interface.

func (*ErrValidationFunc) Error added in v0.0.2

func (e *ErrValidationFunc) Error() string

func (*ErrValidationFunc) Unwrap added in v0.0.2

func (e *ErrValidationFunc) Unwrap() error

Unwrap to support errors IS|AS

type ErrValidationTag added in v0.0.2

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

ErrValidationTag Error if validation failed by a tag

func (*ErrValidationTag) Error added in v0.0.2

func (e *ErrValidationTag) Error() string

func (*ErrValidationTag) Unwrap added in v0.0.2

func (e *ErrValidationTag) Unwrap() error

Unwrap to support errors IS|AS

type Validatable

type Validatable interface {
	Validate() error
}

Validatable Any Type that Implements this interface will have its WithValidateByTags() function called when validating config.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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