yetenv

package module
v0.3.1 Latest Latest
Warning

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

Go to latest
Published: Apr 20, 2020 License: MIT Imports: 6 Imported by: 1

README

GoDoc

yetenv

yetenv is small util package which helps to detect on which environment the application is running and can load a configuration from a file into a configuration struct.

Install

go get -u github.com/pvormste/yetenv

Usage

  1. Environment detection
  2. Config Loader
Environment detection

Environment detection reads from a specific environment variable (Default: ENVIRONMENT). See examples below.

The ENVIRONMENT values are not case-sensitives.

ENVIRONMENT value Constant
production yetenv.Production
staging yetenv.Staging
test yetenv.Test
any other value yetenv.Develop
Using the defaults

Shell:

$ ENVIRONMENT="production" go run main.go  # yetenv.Production
$ ENVIRONMENT="staging" go run main.go     # yetenv.Staging
$ ENVIRONMENT="test" go run main.go        # yetenv.Test
$ ENVIRONMENT="local" go run main.go       # yetenv.Develop

Go Code:

environment := yetenv.GetEnvironment()

switch environment {
case yetenv.Production:
    // Do something in production environment
case yetenv.Staging:
    // Do something in staging environment
case yetenv.Test:
    // Do something in test environment
case yetenv.Develop:
    // Do something in develop environment
}
Changing the default variable name

Shell:

$ APP_ENV="production" go run main.go   # yetenv.Production
$ APP_ENV="staging" go run main.go      # yetenv.Staging
$ APP_ENV="test" go run main.go         # yetenv.Test
$ APP_ENV="local" go run main.go         # yetenv.Develop

Go Code:

yetenv.DefaultVariableName = "APP_ENV"
environment := yetenv.GetEnvironment()

switch environment {
case yetenv.Production:
    // Do something in production environment
case yetenv.Staging:
    // Do something in staging environment
case yetenv.Test:
    // Do something in test environment
case yetenv.Develop:
    // Do something in develop environment
}
Reading temporary from a custom variable name

Shell:

$ APP_ENV="production" go run main.go   # yetenv.Production
$ APP_ENV="staging" go run main.go      # yetenv.Staging
$ APP_ENV="test" go run main.go         # yetenv.Test
$ APP_ENV="local" go run main.go        # yetenv.Develop

Go Code:

environment := yetenv.GetEnvironmentFromVariable("APP_ENV")

switch environment {
case yetenv.Production:
    // Do something in production environment
case yetenv.Staging:
    // Do something in staging environment
case yetenv.Test:
    // Do something in staging environment
case yetenv.Develop:
    // Do something in develop environment
}
Config Loader

The config loader is able to load a configuration from one or more files into a configuration struct. To achieve this, it uses the cleanenv package under the hood - so please have a look into their documentation to get familar about the usage of configuration structs.

It also comes with a set of defaults, so it can be used with zero configuration out of the box. Nevertheless it is possible to customize the behavior of the ConfigLoader, so it doesn't get in your way.

Default Load Behavior

The default load behavior works like this depending on the environment:

  • For Develop: Load from ./cfg.dev.env and overwrite it by ./.env and OS environment values.
  • For Test: Load from ./cfg.test.env and overwrite it by ./.env and OS environment values.
  • For Staging: Load from ./cfg.staging.env and overwrite it by ./.env and OS environment values.
  • For Production: Load from ./cfg.prod.env and overwrite it by ./.env and OS environment values.
c := Config{}
err := yetenv.NewConfigLoader().
   UseDefaultLoadBehavior().
   LoadInto(&c)
Change load path
  • For Develop: Load from ./config/cfg.dev.env and overwrite it by ./config/.env and OS environment values.
  • For Test: Load from ./config/cfg.test.env and overwrite it by ./config/.env and OS environment values.
  • For Staging: Load from ./config/cfg.staging.env and overwrite it by ./config/.env and OS environment values.
  • For Production: Load from ./config/cfg.prod.env and overwrite it by ./config/.env and OS environment values.
c := Config{}
err := yetenv.NewConfigLoader().
   UseLoadPath("./config").
   UseDefaultLoadBehavior().
   LoadInto(&c)
Change file processor
  • For Develop: Load from ./cfg.dev.yaml and overwrite it by ./cfg.yaml and OS environment values.
  • For Test: Load from ./cfg.test.yaml and overwrite it by ./cfg.yaml and OS environment values.
  • For Staging: Load from ./cfg.staging.yaml and overwrite it by ./cfg.yaml and OS environment values.
  • For Production: Load from ./cfg.prod.yaml and overwrite it by ./cfg.yaml and OS environment values.
c := Config{}
err := yetenv.NewConfigLoader().
   UseFileProcessor(yetenv.YAML).
   UseDefaultLoadBehavior().
   LoadInto(&c)
Change file name for a specific environment

The default load behavior works like this depending on the environment:

  • For Develop: Load from ./cfg.local.env and overwrite it by ./.env and OS environment values.
  • For Test: Load from ./cfg.testing.env and overwrite it by ./.env and OS environment values.
  • For Staging: Load from ./cfg.qa.env and overwrite it by ./.env and OS environment values.
  • For Production: Load from ./cfg.production.env and overwrite it by ./.env and OS environment values.
c := Config{}
err := yetenv.NewConfigLoader().
   UseFileNameForEnvironment(yetenv.Develop, "cfg.local").
   UseFileNameForEnvironment(yetenv.Test, "cfg.testing").
   UseFileNameForEnvironment(yetenv.Staging, "cfg.qa").
   UseFileNameForEnvironment(yetenv.Production, "cfg.production").
   UseDefaultLoadBehavior().
   LoadInto(&c)
Inject environment

By default the ConfigLoader will use yetenv.GetEnvironment() to detect the current environment. If you customize the environment detection you can inject it this way:

customEnvironment := yetenv.Staging
c := Config{}
err := yetenv.NewConfigLoader().
   UseEnvironment(customEnvironment).
   UseDefaultLoadBehavior().
   LoadInto(&c)
Custom Load Behavior

The custom load behavior is highly customizable - but keep in mind that some settings only applies when using specific setting methods.

Setting Applies When using
UseLoadPath() LoadFromFileForEnvironment()
UseFileProcessor() LoadFromFileForEnvironment()
UseFileNameForEnvironment() LoadFromFileForEnvironment()
UseEnvironment() LoadFromFileForEnvironment() or LoadFromConditionalFile()
Example for a custom load behavior
  • For Develop and Staging and Test: Load from ./cfg.base.env and overwrite by OS environment values.
  • For Production: Load from ./config/cfg.prod.yaml and overwrite by OS environment values.
  • For All Environments: Load from ./other-config/cfg.toml and overwrite by OS environment values.
developAndStagingCondition := func(configLoader *ConfigLoader, currentEnvironment Environment) bool {
   return currentEnvironment == yetenv.Develop || currentEnvironment == yetenv.Staging || currentEnvironment == yetenv.Test
}

customEnvironment := yetenv.Staging
c := Config{}
err := yetenv.NewConfigLoader().
   UseLoadPath("./config").
   UseFileProcessor(yetenv.YAML).
   UseEnvironment(customEnvironment).
   UseCustomLoadBehavior().
   LoadFromConditionalFile("./cfg.base.env", developAndStagingCondition).
   LoadFromFileForEnvironment(yetenv.Production).
   LoadFromFile("./other-config/cfg.toml").
   LoadInto(&c)

As you can see: you can do very complicated things with it - I personally would recommend to keep it simple :-).

Documentation

Overview

Package yetenv provides some logic to determine the environment (develop, staging, production).

Index

Constants

This section is empty.

Variables

View Source
var DefaultConditionForDevelopEnvironment = func(configLoader *ConfigLoader, currentEnvironment Environment) bool {
	return currentEnvironment == Develop
}

DefaultConditionForDevelopEnvironment retuns true when the current environment is Develop otherwise false.

View Source
var DefaultConditionForProductionEnvironment = func(configLoader *ConfigLoader, currentEnvironment Environment) bool {
	return currentEnvironment == Production
}

DefaultConditionForProductionEnvironment returns true when the current environment is Production otherweise false.

View Source
var DefaultConditionForStagingEnvironment = func(configLoader *ConfigLoader, currentEnvironment Environment) bool {
	return currentEnvironment == Staging
}

DefaultConditionForStagingEnvironment returns true when the current environment is Staging otherwise false.

View Source
var DefaultConditionForTestEnvironment = func(configLoader *ConfigLoader, currentEnvironment Environment) bool {
	return currentEnvironment == Test
}

DefaultConditionForDevelopEnvironment retuns true when the current environment is Develop otherwise false.

View Source
var DefaultVariableName = "ENVIRONMENT"

DefaultVariableName defines the default name of the environment variable.

View Source
var (
	ErrUnknownLoadBehavior = errors.New("load behavior is unknown - only default or custom load behavior is allowed")
)

Functions

This section is empty.

Types

type ConditionalLoadFunc

type ConditionalLoadFunc func(configLoader *ConfigLoader, currentEnvironment Environment) bool

ConditionalLoadFunc allows to define a condition for a file to be loaded by the config loader.

type ConfigFileExtension

type ConfigFileExtension string

ConfigFileExtension represents a possible config file extension which is usable by the config loader.

const (
	YAML   ConfigFileExtension = ".yaml"
	JSON   ConfigFileExtension = ".json"
	TOML   ConfigFileExtension = ".toml"
	DOTENV ConfigFileExtension = ".env"
)

type ConfigLoader

type ConfigLoader struct {
	LoadPath      string
	FileExtension ConfigFileExtension
	ConfigFiles   map[Environment]string
	Environment   Environment
	LoadBehavior  LoadBehavior
	// contains filtered or unexported fields
}

ConfigLoader loads configuration values from files and the OS environment into a configuration struct. It uses the builder pattern and needs to be extecuted by the finishing method.

func NewConfigLoader

func NewConfigLoader() *ConfigLoader

NewConfigLoader initializes a new ConfigLoader builder.

func (*ConfigLoader) LoadFromConditionalFile

func (c *ConfigLoader) LoadFromConditionalFile(filePath string, conditionFunc ConditionalLoadFunc) *ConfigLoader

LoadFromConditionalFile can be used to load a config file only when the condition of the conditionFunc is met. It will not use the LoadPath, so the full path to config file should be provided.

func (*ConfigLoader) LoadFromFile

func (c *ConfigLoader) LoadFromFile(filePath string) *ConfigLoader

LoadFromFile can be used to load a specific config file when using custom load behavior. It will not use the LoadPath, so the full path to config file should be provided.

func (*ConfigLoader) LoadFromFileForEnvironment

func (c *ConfigLoader) LoadFromFileForEnvironment(environment Environment) *ConfigLoader

LoadFromFileForEnvironment can be used to reuse environmental load logic for a custom load behavior. For example: LoadFromFileForEnvironment(Develop) will behave the same as in the default load behavior.

func (*ConfigLoader) LoadInto

func (c *ConfigLoader) LoadInto(cfg interface{}) error

LoadInto will finish the ConfigLoader and execute the load process. The provided config struct should be a pointer.

func (*ConfigLoader) UseCustomLoadBehavior

func (c *ConfigLoader) UseCustomLoadBehavior() *ConfigLoader

UseCustomLoadBehavior sets load behavior to LoadBehaviorCustom.

func (*ConfigLoader) UseDefaultLoadBehavior

func (c *ConfigLoader) UseDefaultLoadBehavior() *ConfigLoader

UseDefaultLoadBehavior sets load behavior to LoadBehaviorDefault.

func (*ConfigLoader) UseEnvironment

func (c *ConfigLoader) UseEnvironment(environment Environment) *ConfigLoader

UseEnvironment can be used to change the current environment value of the ConfigLoader. Defaults to the value of the ENVIRONMENT variable.

func (*ConfigLoader) UseFileNameForEnvironment

func (c *ConfigLoader) UseFileNameForEnvironment(environment Environment, fileName string) *ConfigLoader

UseFileNameForEnvironment can be used to change the config file name for a specific environment. Default file names are: Develop -> 'cfg.dev' Develop -> 'cfg.test' Staging -> 'cfg.staging' Production -> 'cfg.prod' Custom -> 'cfg' or '.env'

func (*ConfigLoader) UseFileProcessor

func (c *ConfigLoader) UseFileProcessor(extension ConfigFileExtension) *ConfigLoader

UseFileProcessor can be used to change the file processor for config files when using the default load behavior. It defaults to "DOTENV".

func (*ConfigLoader) UseLoadBehavior

func (c *ConfigLoader) UseLoadBehavior(behavior LoadBehavior) *ConfigLoader

UseLoadBehavior can be used to set a LoadBehavior to a specific value.

func (*ConfigLoader) UseLoadPath

func (c *ConfigLoader) UseLoadPath(path string) *ConfigLoader

UseLoadPath can be used to change the load path for the default load behavior. It defaults to "./".

type Environment

type Environment string

Environment defines the environment of an application (e.g. Develop, Staging, Production, etc.)

const (
	Production Environment = "production"
	Staging    Environment = "staging"
	Test       Environment = "test"
	Develop    Environment = "develop"
	Custom     Environment = "custom"
)

func GetEnvironment

func GetEnvironment() Environment

GetEnvironment returns the current Environment value depending on the OS environment value of the variable defined by DefaultVariableName.

func GetEnvironmentFromVariable

func GetEnvironmentFromVariable(variableName string) Environment

GetEnvironmentFromVariable returns the current Environment value depending on the OS environment value of the variable provided by the parameter.

type LoadBehavior

type LoadBehavior int

LoadBehavior is used to define the load behavior of the config loader.

const (
	LoadBehaviorUnknown LoadBehavior = iota
	LoadBehaviorDefault
	LoadBehaviorCustom
)

Jump to

Keyboard shortcuts

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