envh

package module
v1.5.0 Latest Latest
Warning

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

Go to latest
Published: May 5, 2022 License: MIT Imports: 6 Imported by: 6

README

Envh codecov Go Report Card GoDoc GitHub tag

This library is made up of two parts :

  • Env object : it wraps your environments variables in an object and provides convenient helpers.
  • Env tree object : it manages environment variables through a tree structure to store a config the same way as in a yaml file or whatever format allows to store a config hierarchically

Install

go get github.com/antham/envh

How it works

Check the godoc, there are many examples provided.

Example with a tree dumped in a config struct

package envh

import (
	"encoding/json"
	"fmt"
	"os"
	"strings"
)

type CONFIG2 struct {
	DB struct {
		USERNAME   string
		PASSWORD   string
		HOST       string
		NAME       string
		PORT       int
		URL        string
		USAGELIMIT float32
	}
	MAILER struct {
		HOST     string
		USERNAME string
		PASSWORD string
		ENABLED  bool
	}
	MAP map[string]string
}

func (c *CONFIG2) Walk(tree *EnvTree, keyChain []string) (bool, error) {
	if setter, ok := map[string]func(*EnvTree, []string) error{
		"CONFIG2_DB_URL": c.setURL,
		"CONFIG2_MAP":    c.setMap,
	}[strings.Join(keyChain, "_")]; ok {
		return true, setter(tree, keyChain)
	}

	return false, nil
}

func (c *CONFIG2) setMap(tree *EnvTree, keyChain []string) error {
	datas := map[string]string{}

	keys, err := tree.FindChildrenKeys(keyChain...)

	if err != nil {
		return err
	}

	for _, key := range keys {
		value, err := tree.FindString(append(keyChain, key)...)

		if err != nil {
			return err
		}

		datas[key] = value
	}

	c.MAP = datas

	return nil
}

func (c *CONFIG2) setURL(tree *EnvTree, keyChain []string) error {
	datas := map[string]string{}

	for _, key := range []string{"USERNAME", "PASSWORD", "HOST", "NAME"} {
		value, err := tree.FindString("CONFIG2", "DB", key)

		if err != nil {
			return err
		}

		datas[key] = value
	}

	port, err := tree.FindInt("CONFIG2", "DB", "PORT")

	if err != nil {
		return err
	}

	c.DB.URL = fmt.Sprintf("jdbc:mysql://%s:%d/%s?user=%s&password=%s", datas["HOST"], port, datas["NAME"], datas["USERNAME"], datas["PASSWORD"])

	return nil
}

func ExampleStructWalker_customFieldSet() {
	os.Clearenv()
	setEnv("CONFIG2_DB_USERNAME", "foo")
	setEnv("CONFIG2_DB_PASSWORD", "bar")
	setEnv("CONFIG2_DB_HOST", "localhost")
	setEnv("CONFIG2_DB_NAME", "my-db")
	setEnv("CONFIG2_DB_PORT", "3306")
	setEnv("CONFIG2_DB_USAGELIMIT", "95.6")
	setEnv("CONFIG2_MAILER_HOST", "127.0.0.1")
	setEnv("CONFIG2_MAILER_USERNAME", "foo")
	setEnv("CONFIG2_MAILER_PASSWORD", "bar")
	setEnv("CONFIG2_MAILER_ENABLED", "true")
	setEnv("CONFIG2_MAP_KEY1", "value1")
	setEnv("CONFIG2_MAP_KEY2", "value2")
	setEnv("CONFIG2_MAP_KEY3", "value3")

	env, err := NewEnvTree("^CONFIG2", "_")

	if err != nil {
		return
	}

	s := CONFIG2{}

	err = env.PopulateStruct(&s)

	if err != nil {
		return
	}

	b, err := json.Marshal(s)

	if err != nil {
		return
	}

	fmt.Println(string(b))
	// Output:
	// {"DB":{"USERNAME":"foo","PASSWORD":"bar","HOST":"localhost","NAME":"my-db","PORT":3306,"URL":"jdbc:mysql://localhost:3306/my-db?user=foo\u0026password=bar","USAGELIMIT":95.6},"MAILER":{"HOST":"127.0.0.1","USERNAME":"foo","PASSWORD":"bar","ENABLED":true},"MAP":{"KEY1":"value1","KEY2":"value2","KEY3":"value3"}}
}

Documentation

Overview

Package envh provides convenient helpers to manage easily your environment variables.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Env

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

Env manages environment variables by giving a convenient helper to interact with them

func NewEnv

func NewEnv() Env

NewEnv creates a new Env instance

func (Env) FindEntries

func (e Env) FindEntries(reg string) (map[string]string, error)

FindEntries retrieves all keys matching a given regexp and their corresponding values

Example
os.Clearenv()
setEnv("API_USERNAME", "user")
setEnv("API_PASSWORD", "password")
setEnv("DB_USERNAME", "user")
setEnv("DB_PASSWORD", "user")

env := NewEnv()

entries, err := env.FindEntries("API.*")

fmt.Printf("API -> PASSWORD = %s, API -> USERNAME = %s ", entries["API_PASSWORD"], entries["API_PASSWORD"])
fmt.Println(err)
fmt.Println(env.FindEntries("*"))
Output:

API -> PASSWORD = password, API -> USERNAME = password <nil>
map[] error parsing regexp: missing argument to repetition operator: `*`

func (Env) FindEntriesUnsecured added in v1.2.0

func (e Env) FindEntriesUnsecured(reg string) map[string]string

FindEntriesUnsecured is insecured version of FindEntriesUnsecured to avoid the burden of rechecking errors if it was done already. If any errors occurred cause the variable is missing or not a boolean value, it returns default empty map. This function has to be used carefully.

Example
os.Clearenv()
setEnv("API_USERNAME", "user")
setEnv("API_PASSWORD", "password")
setEnv("DB_USERNAME", "user")
setEnv("DB_PASSWORD", "user")

env := NewEnv()

entries := env.FindEntriesUnsecured("API.*")

fmt.Printf("API -> PASSWORD = %s, API -> USERNAME = %s\n", entries["API_PASSWORD"], entries["API_PASSWORD"])
fmt.Println(env.FindEntriesUnsecured("*"))
Output:

API -> PASSWORD = password, API -> USERNAME = password
map[]

func (Env) GetAllKeys

func (e Env) GetAllKeys() []string

GetAllKeys retrieves a slice of all environment variables keys

Example
os.Clearenv()
setEnv("HELLO", "world")
setEnv("FOO", "bar")

env := NewEnv()

keys := env.GetAllKeys()

sort.Strings(keys)

fmt.Println(keys)
Output:

[FOO HELLO]

func (Env) GetAllValues

func (e Env) GetAllValues() []string

GetAllValues retrieves a slice of all environment variables values

Example
os.Clearenv()
setEnv("HELLO", "world")
setEnv("FOO", "bar")

env := NewEnv()

values := env.GetAllValues()

sort.Strings(values)

fmt.Println(values)
Output:

[bar world]

func (Env) GetBool

func (e Env) GetBool(key string) (bool, error)

GetBool returns a boolean if variable exists or an error if value is not a boolean or doesn't exist

Example
os.Clearenv()
setEnv("BOOL", "true")
setEnv("STRING", "TEST")

env := NewEnv()

fmt.Println(env.GetBool("BOOL"))
fmt.Println(env.GetBool("STRING"))
Output:

true <nil>
false Value "TEST" can't be converted to type "bool"

func (Env) GetBoolUnsecured added in v1.2.0

func (e Env) GetBoolUnsecured(key string) bool

GetBoolUnsecured is insecured version of GetBool to avoid the burden of rechecking errors if it was done already. If any errors occurred cause the variable is missing or not a boolean value, it returns default zero boolean value. This function has to be used carefully

Example
os.Clearenv()
setEnv("BOOL", "true")
setEnv("STRING", "TEST")

env := NewEnv()

fmt.Println(env.GetBoolUnsecured("BOOL"))
fmt.Println(env.GetBoolUnsecured("STRING"))
Output:

true
false

func (Env) GetFloat

func (e Env) GetFloat(key string) (float32, error)

GetFloat returns a float if variable exists or an error if value is not a float or doesn't exist

Example
os.Clearenv()
setEnv("FLOAT", "1.1")
setEnv("STRING", "TEST")

env := NewEnv()

f, err := env.GetFloat("FLOAT")

fmt.Printf("%0.1f ", f)
fmt.Println(err)
fmt.Println(env.GetFloat("STRING"))
Output:

1.1 <nil>
0 Value "TEST" can't be converted to type "float"

func (Env) GetFloatUnsecured added in v1.2.0

func (e Env) GetFloatUnsecured(key string) float32

GetFloatUnsecured is insecured version of GetFloat to avoid the burden of rechecking errors if it was done already. If any errors occurred cause the variable is missing or not a floating value, it returns default zero floating value. This function has to be used carefully

Example
os.Clearenv()
setEnv("FLOAT", "1.1")
setEnv("STRING", "TEST")

env := NewEnv()

fmt.Printf("%0.1f\n", env.GetFloatUnsecured("FLOAT"))
fmt.Println(env.GetFloatUnsecured("STRING"))
Output:

1.1
0

func (Env) GetInt

func (e Env) GetInt(key string) (int, error)

GetInt returns an integer if variable exists or an error if value is not an integer or doesn't exist

Example
os.Clearenv()
setEnv("INT", "1")
setEnv("STRING", "TEST")

env := NewEnv()

fmt.Println(env.GetInt("INT"))
fmt.Println(env.GetInt("STRING"))
Output:

1 <nil>
0 Value "TEST" can't be converted to type "int"

func (Env) GetIntUnsecured added in v1.2.0

func (e Env) GetIntUnsecured(key string) int

GetIntUnsecured is insecured version of GetInt to avoid the burden of rechecking errors if it was done already. If any errors occurred cause the variable is missing or not an int value, it returns default zero int value. This function has to be used carefully

Example
os.Clearenv()
setEnv("INT", "1")
setEnv("STRING", "TEST")

env := NewEnv()

fmt.Println(env.GetIntUnsecured("INT"))
fmt.Println(env.GetIntUnsecured("STRING"))
Output:

1
0

func (Env) GetString

func (e Env) GetString(key string) (string, error)

GetString returns a string if variable exists or an error otherwise

Example
os.Clearenv()
setEnv("HELLO", "world")

env := NewEnv()

fmt.Println(env.GetString("HELLO"))
Output:

world <nil>

func (Env) GetStringUnsecured added in v1.2.0

func (e Env) GetStringUnsecured(key string) string

GetStringUnsecured is insecured version of GetString to avoid the burden of rechecking errors if it was done already. If any errors occurred cause the variable is missing, it returns default zero string value. This function has to be used carefully

Example
os.Clearenv()
setEnv("HELLO", "world")

env := NewEnv()

fmt.Println(env.GetStringUnsecured("HELLO"))
Output:

world

type EnvTree

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

EnvTree manages environment variables through a tree structure to store a config the same way as in a yaml file or whatever format allows to store a config hierarchically

func NewEnvTree

func NewEnvTree(reg string, delimiter string) (EnvTree, error)

NewEnvTree creates an environment variable tree. A delimiter is used to split key, reg is a regexp used to filter entries

func (EnvTree) FindBool

func (e EnvTree) FindBool(keyChain ...string) (bool, error)

FindBool returns a boolean if key chain exists or an error if value is not a boolean or doesn't exist

Example
os.Clearenv()
setEnv("ENVH_DB_USERNAME", "foo")
setEnv("ENVH_DB_PASSWORD", "bar")
setEnv("ENVH_DB_PORT", "3306")
setEnv("ENVH_DB_USAGE_LIMIT", "95.6")
setEnv("ENVH_MAILER_HOST", "127.0.0.1")
setEnv("ENVH_MAILER_USERNAME", "foo")
setEnv("ENVH_MAILER_PASSWORD", "bar")
setEnv("ENVH_MAILER_ENABLED", "true")

env, err := NewEnvTree("^ENVH", "_")

if err != nil {
	return
}

fmt.Println(env.FindBool("ENVH", "MAILER", "ENABLED"))
fmt.Println(env.FindBool("ENVH", "DB", "USERNAME"))
fmt.Println(env.FindBool("ENVH", "DB", "WHATEVER"))
Output:

true <nil>
false Value "foo" can't be converted to type "bool"
false Variable not found

func (EnvTree) FindBoolUnsecured added in v1.2.0

func (e EnvTree) FindBoolUnsecured(keyChain ...string) bool

FindBoolUnsecured is insecured version of FindBool to avoid the burden of rechecking errors if it was done already. If any errors occurred cause the variable is missing or not a boolean value, it returns default zero boolean value. This function has to be used carefully

Example
os.Clearenv()
setEnv("ENVH_DB_USERNAME", "foo")
setEnv("ENVH_DB_PASSWORD", "bar")
setEnv("ENVH_DB_PORT", "3306")
setEnv("ENVH_DB_USAGE_LIMIT", "95.6")
setEnv("ENVH_MAILER_HOST", "127.0.0.1")
setEnv("ENVH_MAILER_USERNAME", "foo")
setEnv("ENVH_MAILER_PASSWORD", "bar")
setEnv("ENVH_MAILER_ENABLED", "true")

env, err := NewEnvTree("^ENVH", "_")

if err != nil {
	return
}

fmt.Println(env.FindBoolUnsecured("ENVH", "MAILER", "ENABLED"))
fmt.Println(env.FindBoolUnsecured("ENVH", "DB", "USERNAME"))
fmt.Println(env.FindBoolUnsecured("ENVH", "DB", "WHATEVER"))
Output:

true
false
false

func (EnvTree) FindChildrenKeys

func (e EnvTree) FindChildrenKeys(keyChain ...string) ([]string, error)

FindChildrenKeys returns all children keys for a given key chain. If sub node doesn't exist, it returns an error ErrNodeNotFound as second value

Example
os.Clearenv()
setEnv("ENVH_DB_USERNAME", "foo")
setEnv("ENVH_DB_PASSWORD", "bar")
setEnv("ENVH_DB_PORT", "3306")
setEnv("ENVH_DB_USAGE_LIMIT", "95.6")
setEnv("ENVH_MAILER_HOST", "127.0.0.1")
setEnv("ENVH_MAILER_USERNAME", "foo")
setEnv("ENVH_MAILER_PASSWORD", "bar")
setEnv("ENVH_MAILER_ENABLED", "true")

env, err := NewEnvTree("^ENVH", "_")

if err != nil {
	return
}

children, err := env.FindChildrenKeys("ENVH", "DB")

sort.Strings(children)

fmt.Print(children)
fmt.Print(" ")
fmt.Println(err)
fmt.Println(env.FindChildrenKeys("ENVH", "WHATEVER"))
Output:

[PASSWORD PORT USAGE USERNAME] <nil>
[] No node found at path "ENVH -> WHATEVER"

func (EnvTree) FindChildrenKeysUnsecured added in v1.2.0

func (e EnvTree) FindChildrenKeysUnsecured(keyChain ...string) []string

FindChildrenKeysUnsecured is insecured version of FindChildrenKeys to avoid the burden of rechecking errors if it was done already. If any errors occurred cause the node doesn't exist, it returns empty string slice. This function has to be used carefully

Example
os.Clearenv()
setEnv("ENVH_DB_USERNAME", "foo")
setEnv("ENVH_DB_PASSWORD", "bar")
setEnv("ENVH_DB_PORT", "3306")
setEnv("ENVH_DB_USAGE_LIMIT", "95.6")
setEnv("ENVH_MAILER_HOST", "127.0.0.1")
setEnv("ENVH_MAILER_USERNAME", "foo")
setEnv("ENVH_MAILER_PASSWORD", "bar")
setEnv("ENVH_MAILER_ENABLED", "true")

env, err := NewEnvTree("^ENVH", "_")

if err != nil {
	return
}

children := env.FindChildrenKeysUnsecured("ENVH", "DB")

sort.Strings(children)

fmt.Println(children)
fmt.Println(env.FindChildrenKeysUnsecured("ENVH", "WHATEVER"))
Output:

[PASSWORD PORT USAGE USERNAME]
[]

func (EnvTree) FindFloat

func (e EnvTree) FindFloat(keyChain ...string) (float32, error)

FindFloat returns a float if key chain exists or an error if value is not a float or doesn't exist

Example
os.Clearenv()
setEnv("ENVH_DB_USERNAME", "foo")
setEnv("ENVH_DB_PASSWORD", "bar")
setEnv("ENVH_DB_PORT", "3306")
setEnv("ENVH_DB_USAGE_LIMIT", "95.6")
setEnv("ENVH_MAILER_HOST", "127.0.0.1")
setEnv("ENVH_MAILER_USERNAME", "foo")
setEnv("ENVH_MAILER_PASSWORD", "bar")
setEnv("ENVH_MAILER_ENABLED", "true")

env, err := NewEnvTree("^ENVH", "_")

if err != nil {
	return
}

fmt.Println(env.FindFloat("ENVH", "DB", "USAGE", "LIMIT"))
fmt.Println(env.FindFloat("ENVH", "DB", "USERNAME"))
fmt.Println(env.FindFloat("ENVH", "DB", "WHATEVER"))
Output:

95.6 <nil>
0 Value "foo" can't be converted to type "float"
0 Variable not found

func (EnvTree) FindFloatUnsecured added in v1.2.0

func (e EnvTree) FindFloatUnsecured(keyChain ...string) float32

FindFloatUnsecured is insecured version of FindFloat to avoid the burden of rechecking errors if it was done already. If any errors occurred cause the variable is missing or not a floating value, it returns default zero floating value. This function has to be used carefully

Example
os.Clearenv()
setEnv("ENVH_DB_USERNAME", "foo")
setEnv("ENVH_DB_PASSWORD", "bar")
setEnv("ENVH_DB_PORT", "3306")
setEnv("ENVH_DB_USAGE_LIMIT", "95.6")
setEnv("ENVH_MAILER_HOST", "127.0.0.1")
setEnv("ENVH_MAILER_USERNAME", "foo")
setEnv("ENVH_MAILER_PASSWORD", "bar")
setEnv("ENVH_MAILER_ENABLED", "true")

env, err := NewEnvTree("^ENVH", "_")

if err != nil {
	return
}

fmt.Println(env.FindFloatUnsecured("ENVH", "DB", "USAGE", "LIMIT"))
fmt.Println(env.FindFloatUnsecured("ENVH", "DB", "USERNAME"))
fmt.Println(env.FindFloatUnsecured("ENVH", "DB", "WHATEVER"))
Output:

95.6
0
0

func (EnvTree) FindInt

func (e EnvTree) FindInt(keyChain ...string) (int, error)

FindInt returns an integer if key chain exists or an error if value is not an integer or doesn't exist

Example
os.Clearenv()
setEnv("ENVH_DB_USERNAME", "foo")
setEnv("ENVH_DB_PASSWORD", "bar")
setEnv("ENVH_DB_PORT", "3306")
setEnv("ENVH_DB_USAGE_LIMIT", "95.6")
setEnv("ENVH_MAILER_HOST", "127.0.0.1")
setEnv("ENVH_MAILER_USERNAME", "foo")
setEnv("ENVH_MAILER_PASSWORD", "bar")
setEnv("ENVH_MAILER_ENABLED", "true")

env, err := NewEnvTree("^ENVH", "_")

if err != nil {
	return
}

fmt.Println(env.FindInt("ENVH", "DB", "PORT"))
fmt.Println(env.FindInt("ENVH", "DB", "USERNAME"))
fmt.Println(env.FindInt("ENVH", "DB", "WHATEVER"))
Output:

3306 <nil>
0 Value "foo" can't be converted to type "int"
0 Variable not found

func (EnvTree) FindIntUnsecured added in v1.2.0

func (e EnvTree) FindIntUnsecured(keyChain ...string) int

FindIntUnsecured is insecured version of FindInt to avoid the burden of rechecking errors if it was done already. If any errors occurred cause the variable is missing or not an int value, it returns default zero int value. This function has to be used carefully

Example
os.Clearenv()
setEnv("ENVH_DB_USERNAME", "foo")
setEnv("ENVH_DB_PASSWORD", "bar")
setEnv("ENVH_DB_PORT", "3306")
setEnv("ENVH_DB_USAGE_LIMIT", "95.6")
setEnv("ENVH_MAILER_HOST", "127.0.0.1")
setEnv("ENVH_MAILER_USERNAME", "foo")
setEnv("ENVH_MAILER_PASSWORD", "bar")
setEnv("ENVH_MAILER_ENABLED", "true")

env, err := NewEnvTree("^ENVH", "_")

if err != nil {
	return
}

fmt.Println(env.FindIntUnsecured("ENVH", "DB", "PORT"))
fmt.Println(env.FindIntUnsecured("ENVH", "DB", "USERNAME"))
fmt.Println(env.FindIntUnsecured("ENVH", "DB", "WHATEVER"))
Output:

3306
0
0

func (EnvTree) FindString

func (e EnvTree) FindString(keyChain ...string) (string, error)

FindString returns a string if key chain exists or an error otherwise

Example
os.Clearenv()
setEnv("ENVH_DB_USERNAME", "foo")
setEnv("ENVH_DB_PASSWORD", "bar")
setEnv("ENVH_DB_PORT", "3306")
setEnv("ENVH_DB_USAGE_LIMIT", "95.6")
setEnv("ENVH_MAILER_HOST", "127.0.0.1")
setEnv("ENVH_MAILER_USERNAME", "foo")
setEnv("ENVH_MAILER_PASSWORD", "bar")
setEnv("ENVH_MAILER_ENABLED", "true")

env, err := NewEnvTree("^ENVH", "_")

if err != nil {
	return
}

fmt.Println(env.FindString("ENVH", "DB", "USERNAME"))
fmt.Println(env.FindString("ENVH", "DB", "WHATEVER"))
Output:

foo <nil>
 Variable not found

func (EnvTree) FindStringUnsecured added in v1.2.0

func (e EnvTree) FindStringUnsecured(keyChain ...string) string

FindStringUnsecured is insecured version of FindString to avoid the burden of rechecking errors if it was done already. If any errors occurred cause the variable is missing, it returns default zero string value. This function has to be used carefully

Example
os.Clearenv()
setEnv("ENVH_DB_USERNAME", "foo")
setEnv("ENVH_DB_PASSWORD", "bar")
setEnv("ENVH_DB_PORT", "3306")
setEnv("ENVH_DB_USAGE_LIMIT", "95.6")
setEnv("ENVH_MAILER_HOST", "127.0.0.1")
setEnv("ENVH_MAILER_USERNAME", "foo")
setEnv("ENVH_MAILER_PASSWORD", "bar")
setEnv("ENVH_MAILER_ENABLED", "true")

env, err := NewEnvTree("^ENVH", "_")

if err != nil {
	return
}

fmt.Println(env.FindStringUnsecured("ENVH", "DB", "USERNAME"))
fmt.Println(env.FindStringUnsecured("ENVH", "DB", "WHATEVER"))
Output:

foo

func (EnvTree) FindSubTree

func (e EnvTree) FindSubTree(keyChain ...string) (EnvTree, error)

FindSubTree returns underlying tree from key chain, for instance given A -> B -> C -> D tree, "A" "B" "C" key chain will return C sub tree. If no node is found, it returns an error ErrNodeNotFound as second value

Example
os.Clearenv()
setEnv("ENVH_DB_USERNAME", "foo")
setEnv("ENVH_DB_PASSWORD", "bar")
setEnv("ENVH_DB_PORT", "3306")
setEnv("ENVH_DB_USAGE_LIMIT", "95.6")
setEnv("ENVH_MAILER_HOST", "127.0.0.1")
setEnv("ENVH_MAILER_USERNAME", "foo")
setEnv("ENVH_MAILER_PASSWORD", "bar")
setEnv("ENVH_MAILER_ENABLED", "true")

env, err := NewEnvTree("^ENVH", "_")

if err != nil {
	return
}

dbTree, err := env.FindSubTree("ENVH", "DB")
dbChildrenKeys := dbTree.GetChildrenKeys()
sort.Strings(dbChildrenKeys)

fmt.Print(dbChildrenKeys)
fmt.Print(" ")
fmt.Println(err)

mailerTree, err := env.FindSubTree("ENVH", "MAILER")
mailerChildrenKeys := mailerTree.GetChildrenKeys()
sort.Strings(mailerChildrenKeys)

fmt.Print(mailerChildrenKeys)
fmt.Print(" ")
fmt.Println(err)

fmt.Println(env.FindSubTree("ENVH", "MAILER", "WHATEVER"))
Output:

[PASSWORD PORT USAGE USERNAME] <nil>
[ENABLED HOST PASSWORD USERNAME] <nil>
{<nil>} No node found at path "ENVH -> MAILER -> WHATEVER"

func (EnvTree) FindSubTreeUnsecured added in v1.2.0

func (e EnvTree) FindSubTreeUnsecured(keyChain ...string) EnvTree

FindSubTreeUnsecured is insecured version of FindSubTree to avoid the burden of rechecking errors if it was done already. If any errors occurred cause the node doesn't exist, it returns empty EnvTree. This function has to be used carefully

Example
os.Clearenv()
setEnv("ENVH_DB_USERNAME", "foo")
setEnv("ENVH_DB_PASSWORD", "bar")
setEnv("ENVH_DB_PORT", "3306")
setEnv("ENVH_DB_USAGE_LIMIT", "95.6")
setEnv("ENVH_MAILER_HOST", "127.0.0.1")
setEnv("ENVH_MAILER_USERNAME", "foo")
setEnv("ENVH_MAILER_PASSWORD", "bar")
setEnv("ENVH_MAILER_ENABLED", "true")

env, err := NewEnvTree("^ENVH", "_")

if err != nil {
	return
}

dbTree := env.FindSubTreeUnsecured("ENVH", "DB")
dbChildrenKeys := dbTree.GetChildrenKeys()
sort.Strings(dbChildrenKeys)

fmt.Println(dbChildrenKeys)

mailerTree := env.FindSubTreeUnsecured("ENVH", "MAILER")
mailerChildrenKeys := mailerTree.GetChildrenKeys()
sort.Strings(mailerChildrenKeys)

fmt.Println(mailerChildrenKeys)

fmt.Println(env.FindSubTreeUnsecured("ENVH", "MAILER", "WHATEVER"))
Output:

[PASSWORD PORT USAGE USERNAME]
[ENABLED HOST PASSWORD USERNAME]
{<nil>}

func (EnvTree) GetBool

func (e EnvTree) GetBool() (bool, error)

GetBool returns current tree value as boolean if value exists or an error if value is not a boolean or doesn't exist

Example
os.Clearenv()
setEnv("ENVH_DB_USERNAME", "foo")
setEnv("ENVH_DB_PASSWORD", "bar")
setEnv("ENVH_DB_PORT", "3306")
setEnv("ENVH_DB_USAGE_LIMIT", "95.6")
setEnv("ENVH_MAILER_HOST", "127.0.0.1")
setEnv("ENVH_MAILER_USERNAME", "foo")
setEnv("ENVH_MAILER_PASSWORD", "bar")
setEnv("ENVH_MAILER_ENABLED", "true")

env, err := NewEnvTree("^ENVH", "_")

if err != nil {
	return
}

enabledTree, err := env.FindSubTree("ENVH", "MAILER", "ENABLED")

if err != nil {
	return
}

fmt.Println(env.GetBool())
fmt.Println(enabledTree.GetBool())
Output:

false Variable not found
true <nil>

func (EnvTree) GetBoolUnsecured added in v1.2.0

func (e EnvTree) GetBoolUnsecured() bool

GetBoolUnsecured is insecured version of GetBool to avoid the burden of rechecking errors if it was done already. If any errors occurred cause the variable is missing or not a boolean value, it returns default zero boolean value. This function has to be used carefully

Example
os.Clearenv()
setEnv("ENVH_DB_USERNAME", "foo")
setEnv("ENVH_DB_PASSWORD", "bar")
setEnv("ENVH_DB_PORT", "3306")
setEnv("ENVH_DB_USAGE_LIMIT", "95.6")
setEnv("ENVH_MAILER_HOST", "127.0.0.1")
setEnv("ENVH_MAILER_USERNAME", "foo")
setEnv("ENVH_MAILER_PASSWORD", "bar")
setEnv("ENVH_MAILER_ENABLED", "true")

env, err := NewEnvTree("^ENVH", "_")

if err != nil {
	return
}

enabledTree, err := env.FindSubTree("ENVH", "MAILER", "ENABLED")

if err != nil {
	return
}

fmt.Println(env.GetBoolUnsecured())
fmt.Println(enabledTree.GetBoolUnsecured())
Output:

false
true

func (EnvTree) GetChildrenKeys

func (e EnvTree) GetChildrenKeys() []string

GetChildrenKeys retrieves all current tree children node keys

Example
os.Clearenv()
setEnv("ENVH_DB_USERNAME", "foo")
setEnv("ENVH_DB_PASSWORD", "bar")
setEnv("ENVH_DB_PORT", "3306")
setEnv("ENVH_DB_USAGE_LIMIT", "95.6")
setEnv("ENVH_MAILER_HOST", "127.0.0.1")
setEnv("ENVH_MAILER_USERNAME", "foo")
setEnv("ENVH_MAILER_PASSWORD", "bar")
setEnv("ENVH_MAILER_ENABLED", "true")

env, err := NewEnvTree("^ENVH", "_")

if err != nil {
	return
}

dbTree, err := env.FindSubTree("ENVH", "DB")

if err != nil {
	return
}

children := dbTree.GetChildrenKeys()

sort.Strings(children)

fmt.Println(children)
Output:

[PASSWORD PORT USAGE USERNAME]

func (EnvTree) GetFloat

func (e EnvTree) GetFloat() (float32, error)

GetFloat returns current tree value as float if value exists or an error if value is not a float or doesn't exist

Example
os.Clearenv()
setEnv("ENVH_DB_USERNAME", "foo")
setEnv("ENVH_DB_PASSWORD", "bar")
setEnv("ENVH_DB_PORT", "3306")
setEnv("ENVH_DB_USAGE_LIMIT", "95.6")
setEnv("ENVH_MAILER_HOST", "127.0.0.1")
setEnv("ENVH_MAILER_USERNAME", "foo")
setEnv("ENVH_MAILER_PASSWORD", "bar")
setEnv("ENVH_MAILER_ENABLED", "true")

env, err := NewEnvTree("^ENVH", "_")

if err != nil {
	return
}

portTree, err := env.FindSubTree("ENVH", "DB", "USAGE", "LIMIT")

if err != nil {
	return
}

fmt.Println(env.GetFloat())
fmt.Println(portTree.GetFloat())
Output:

0 Variable not found
95.6 <nil>

func (EnvTree) GetFloatUnsecured added in v1.2.0

func (e EnvTree) GetFloatUnsecured() float32

GetFloatUnsecured is insecured version of GetFloat to avoid the burden of rechecking errors if it was done already. If any errors occurred cause the variable is missing or not a floating value, it returns default zero floating value. This function has to be used carefully

Example
os.Clearenv()
setEnv("ENVH_DB_USERNAME", "foo")
setEnv("ENVH_DB_PASSWORD", "bar")
setEnv("ENVH_DB_PORT", "3306")
setEnv("ENVH_DB_USAGE_LIMIT", "95.6")
setEnv("ENVH_MAILER_HOST", "127.0.0.1")
setEnv("ENVH_MAILER_USERNAME", "foo")
setEnv("ENVH_MAILER_PASSWORD", "bar")
setEnv("ENVH_MAILER_ENABLED", "true")

env, err := NewEnvTree("^ENVH", "_")

if err != nil {
	return
}

portTree, err := env.FindSubTree("ENVH", "DB", "USAGE", "LIMIT")

if err != nil {
	return
}

fmt.Println(env.GetFloatUnsecured())
fmt.Println(portTree.GetFloatUnsecured())
Output:

0
95.6

func (EnvTree) GetInt

func (e EnvTree) GetInt() (int, error)

GetInt returns current tree value as int if value exists or an error if value is not an integer or doesn't exist

Example
os.Clearenv()
setEnv("ENVH_DB_USERNAME", "foo")
setEnv("ENVH_DB_PASSWORD", "bar")
setEnv("ENVH_DB_PORT", "3306")
setEnv("ENVH_DB_USAGE_LIMIT", "95.6")
setEnv("ENVH_MAILER_HOST", "127.0.0.1")
setEnv("ENVH_MAILER_USERNAME", "foo")
setEnv("ENVH_MAILER_PASSWORD", "bar")
setEnv("ENVH_MAILER_ENABLED", "true")

env, err := NewEnvTree("^ENVH", "_")

if err != nil {
	return
}

portTree, err := env.FindSubTree("ENVH", "DB", "PORT")

if err != nil {
	return
}

fmt.Println(env.GetInt())
fmt.Println(portTree.GetInt())
Output:

0 Variable not found
3306 <nil>

func (EnvTree) GetIntUnsecured added in v1.2.0

func (e EnvTree) GetIntUnsecured() int

GetIntUnsecured is insecured version of GetInt to avoid the burden of rechecking errors if it was done already. If any errors occurred cause the variable is missing or not an int value, it returns default zero int value. This function has to be used carefully

Example
os.Clearenv()
setEnv("ENVH_DB_USERNAME", "foo")
setEnv("ENVH_DB_PASSWORD", "bar")
setEnv("ENVH_DB_PORT", "3306")
setEnv("ENVH_DB_USAGE_LIMIT", "95.6")
setEnv("ENVH_MAILER_HOST", "127.0.0.1")
setEnv("ENVH_MAILER_USERNAME", "foo")
setEnv("ENVH_MAILER_PASSWORD", "bar")
setEnv("ENVH_MAILER_ENABLED", "true")

env, err := NewEnvTree("^ENVH", "_")

if err != nil {
	return
}

portTree, err := env.FindSubTree("ENVH", "DB", "PORT")

if err != nil {
	return
}

fmt.Println(env.GetIntUnsecured())
fmt.Println(portTree.GetIntUnsecured())
Output:

0
3306

func (EnvTree) GetKey

func (e EnvTree) GetKey() string

GetKey returns current tree key

Example
os.Clearenv()
setEnv("ENVH_DB_USERNAME", "foo")
setEnv("ENVH_DB_PASSWORD", "bar")
setEnv("ENVH_DB_PORT", "3306")
setEnv("ENVH_DB_USAGE_LIMIT", "95.6")
setEnv("ENVH_MAILER_HOST", "127.0.0.1")
setEnv("ENVH_MAILER_USERNAME", "foo")
setEnv("ENVH_MAILER_PASSWORD", "bar")
setEnv("ENVH_MAILER_ENABLED", "true")

env, err := NewEnvTree("^ENVH", "_")

if err != nil {
	return
}

dbTree, err := env.FindSubTree("ENVH", "DB")

if err != nil {
	return
}

fmt.Println(dbTree.GetKey())
Output:

DB

func (EnvTree) GetString

func (e EnvTree) GetString() (string, error)

GetString returns current tree value as string if value exists or an error as second parameter

Example
os.Clearenv()
setEnv("ENVH_DB_USERNAME", "foo")
setEnv("ENVH_DB_PASSWORD", "bar")
setEnv("ENVH_DB_PORT", "3306")
setEnv("ENVH_DB_USAGE_LIMIT", "95.6")
setEnv("ENVH_MAILER_HOST", "127.0.0.1")
setEnv("ENVH_MAILER_USERNAME", "foo")
setEnv("ENVH_MAILER_PASSWORD", "bar")
setEnv("ENVH_MAILER_ENABLED", "true")

env, err := NewEnvTree("^ENVH", "_")

if err != nil {
	return
}

usernameTree, err := env.FindSubTree("ENVH", "DB", "USERNAME")

if err != nil {
	return
}

fmt.Println(env.GetString())
fmt.Println(usernameTree.GetString())
Output:

 Variable not found
foo <nil>

func (EnvTree) GetStringUnsecured added in v1.2.0

func (e EnvTree) GetStringUnsecured() string

GetStringUnsecured is insecured version of GetString to avoid the burden of rechecking errors if it was done already. If any errors occurred cause the variable is missing, it returns default zero string value. This function has to be used carefully

Example
os.Clearenv()
setEnv("ENVH_DB_USERNAME", "foo")
setEnv("ENVH_DB_PASSWORD", "bar")
setEnv("ENVH_DB_PORT", "3306")
setEnv("ENVH_DB_USAGE_LIMIT", "95.6")
setEnv("ENVH_MAILER_HOST", "127.0.0.1")
setEnv("ENVH_MAILER_USERNAME", "foo")
setEnv("ENVH_MAILER_PASSWORD", "bar")
setEnv("ENVH_MAILER_ENABLED", "true")

env, err := NewEnvTree("^ENVH", "_")

if err != nil {
	return
}

usernameTree, err := env.FindSubTree("ENVH", "DB", "USERNAME")

if err != nil {
	return
}

fmt.Println(env.GetStringUnsecured())
fmt.Println(usernameTree.GetStringUnsecured())
Output:


foo

func (EnvTree) HasSubTreeValue

func (e EnvTree) HasSubTreeValue(keyChain ...string) (bool, error)

HasSubTreeValue returns true if key chain has a value or false if not. If sub node doesn't exist, it returns an error ErrNodeNotFound as second value

Example
os.Clearenv()
setEnv("ENVH_DB_USERNAME", "foo")
setEnv("ENVH_DB_PASSWORD", "bar")
setEnv("ENVH_DB_PORT", "3306")
setEnv("ENVH_DB_USAGE_LIMIT", "95.6")
setEnv("ENVH_MAILER_HOST", "127.0.0.1")
setEnv("ENVH_MAILER_USERNAME", "foo")
setEnv("ENVH_MAILER_PASSWORD", "bar")
setEnv("ENVH_MAILER_ENABLED", "true")

env, err := NewEnvTree("^ENVH", "_")

if err != nil {
	return
}

fmt.Println(env.HasSubTreeValue("ENVH", "MAILER", "HOST"))
fmt.Println(env.HasSubTreeValue("ENVH", "MAILER"))
fmt.Println(env.HasSubTreeValue("ENVH", "MAILER", "WHATEVER"))
Output:

true <nil>
false <nil>
false No node found at path "ENVH -> MAILER -> WHATEVER"

func (EnvTree) HasSubTreeValueUnsecured added in v1.2.0

func (e EnvTree) HasSubTreeValueUnsecured(keyChain ...string) bool

HasSubTreeValueUnsecured is insecured version of HasSubTreeValue to avoid the burden of rechecking errors if it was done already. If any errors occurred cause the node doesn't exist, it returns false. This function has to be used carefully

Example
os.Clearenv()
setEnv("ENVH_DB_USERNAME", "foo")
setEnv("ENVH_DB_PASSWORD", "bar")
setEnv("ENVH_DB_PORT", "3306")
setEnv("ENVH_DB_USAGE_LIMIT", "95.6")
setEnv("ENVH_MAILER_HOST", "127.0.0.1")
setEnv("ENVH_MAILER_USERNAME", "foo")
setEnv("ENVH_MAILER_PASSWORD", "bar")
setEnv("ENVH_MAILER_ENABLED", "true")

env, err := NewEnvTree("^ENVH", "_")

if err != nil {
	return
}

fmt.Println(env.HasSubTreeValueUnsecured("ENVH", "MAILER", "HOST"))
fmt.Println(env.HasSubTreeValueUnsecured("ENVH", "MAILER"))
fmt.Println(env.HasSubTreeValueUnsecured("ENVH", "MAILER", "WHATEVER"))
Output:

true
false
false

func (EnvTree) HasValue

func (e EnvTree) HasValue() bool

HasValue returns true if current tree has a value defined false otherwise

Example
os.Clearenv()
setEnv("ENVH_DB_USERNAME", "foo")
setEnv("ENVH_DB_PASSWORD", "bar")
setEnv("ENVH_DB_PORT", "3306")
setEnv("ENVH_DB_USAGE_LIMIT", "95.6")
setEnv("ENVH_MAILER_HOST", "127.0.0.1")
setEnv("ENVH_MAILER_USERNAME", "foo")
setEnv("ENVH_MAILER_PASSWORD", "bar")
setEnv("ENVH_MAILER_ENABLED", "true")

env, err := NewEnvTree("^ENVH", "_")

if err != nil {
	return
}

usernameTree, err := env.FindSubTree("ENVH", "DB", "USERNAME")

if err != nil {
	return
}

fmt.Println(env.HasValue())
fmt.Println(usernameTree.HasValue())
Output:

false
true

func (EnvTree) IsExistingSubTree

func (e EnvTree) IsExistingSubTree(keyChain ...string) bool

IsExistingSubTree returns true if key chain has a tree associated or false if not

Example
os.Clearenv()
setEnv("ENVH_DB_USERNAME", "foo")
setEnv("ENVH_DB_PASSWORD", "bar")
setEnv("ENVH_DB_PORT", "3306")
setEnv("ENVH_DB_USAGE_LIMIT", "95.6")
setEnv("ENVH_MAILER_HOST", "127.0.0.1")
setEnv("ENVH_MAILER_USERNAME", "foo")
setEnv("ENVH_MAILER_PASSWORD", "bar")
setEnv("ENVH_MAILER_ENABLED", "true")

env, err := NewEnvTree("^ENVH", "_")

if err != nil {
	return
}

fmt.Println(env.IsExistingSubTree("ENVH", "MAILER", "HOST"))
fmt.Println(env.IsExistingSubTree("ENVH", "MAILER", "WHATEVER"))
Output:

true
false

func (EnvTree) PopulateStruct

func (e EnvTree) PopulateStruct(structure interface{}) error

PopulateStruct fills a structure with datas extracted. Missing values are ignored and only type errors are reported. It's possible to control the way struct fields are defined implementing StructWalker interface on structure, checkout StructWalker documentation for further examples.

Example
type ENVH struct {
	DB struct {
		USERNAME   string
		PASSWORD   string
		PORT       int
		USAGELIMIT float32
	}
	MAILER struct {
		HOST     string
		USERNAME string
		PASSWORD string
		ENABLED  bool
	}
}

os.Clearenv()
setEnv("ENVH_DB_USERNAME", "foo")
setEnv("ENVH_DB_PASSWORD", "bar")
setEnv("ENVH_DB_PORT", "3306")
setEnv("ENVH_DB_USAGELIMIT", "95.6")
setEnv("ENVH_MAILER_HOST", "127.0.0.1")
setEnv("ENVH_MAILER_USERNAME", "foo")
setEnv("ENVH_MAILER_PASSWORD", "bar")
setEnv("ENVH_MAILER_ENABLED", "true")

env, err := NewEnvTree("^ENVH", "_")

if err != nil {
	return
}

s := ENVH{}

err = env.PopulateStruct(&s)

if err != nil {
	return
}

b, err := json.Marshal(s)

if err != nil {
	return
}

fmt.Println(string(b))
Output:

{"DB":{"USERNAME":"foo","PASSWORD":"bar","PORT":3306,"USAGELIMIT":95.6},"MAILER":{"HOST":"127.0.0.1","USERNAME":"foo","PASSWORD":"bar","ENABLED":true}}

func (EnvTree) PopulateStructWithStrictMode

func (e EnvTree) PopulateStructWithStrictMode(structure interface{}) error

PopulateStructWithStrictMode fills a structure with datas extracted. A missing environment variable returns an error and type errors are reported. It's possible to control the way struct fields are defined implementing StructWalker interface on structure, checkout StructWalker documentation for further examples.

Example
type ENVH struct {
	DB struct {
		USERNAME   string
		PASSWORD   string
		PORT       int
		USAGELIMIT float32
	}
	MAILER struct {
		HOST     string
		USERNAME string
		PASSWORD string
		ENABLED  bool
	}
}

os.Clearenv()
setEnv("ENVH_DB_USERNAME", "foo")
setEnv("ENVH_DB_PASSWORD", "bar")
setEnv("ENVH_DB_PORT", "3306")
setEnv("ENVH_DB_USAGELIMIT", "95.6")
setEnv("ENVH_MAILER_HOST", "127.0.0.1")
setEnv("ENVH_MAILER_USERNAME", "foo")
setEnv("ENVH_MAILER_PASSWORD", "bar")

env, err := NewEnvTree("^ENVH", "_")

if err != nil {
	return
}

s := ENVH{}

err = env.PopulateStructWithStrictMode(&s)

fmt.Println(err)
Output:

Variable not found

type NodeNotFoundError

type NodeNotFoundError struct {
	KeyChain []string
}

NodeNotFoundError is triggered when tree node cannot be found

func (NodeNotFoundError) Error

func (e NodeNotFoundError) Error() string

Error dump error

type StructWalker added in v1.2.0

type StructWalker interface {
	Walk(tree *EnvTree, keyChain []string) (bypassWalkingProcess bool, err error)
}

StructWalker must be implemented, when using PopulateStruct* functions, to be able to set a value for a custom field with an unsupported field (a map for instance), to add transformation before setting a field or for custom validation purpose. Walk function is called when struct is populated for every struct field a matching is made with an EnvTree node. Two parameters are given : tree represents whole parsed tree and keyChain is path leading to the node in tree. Returning true as first parameter will bypass walking process and false not, so it's possible to completely control how some part of a structure are defined and it's possible as well only to add some checking and let regular process do its job.

Example (CustomFieldSet)
package main

import (
	"encoding/json"
	"fmt"
	"os"
	"strings"
)

type CONFIG2 struct {
	DB struct {
		USERNAME   string
		PASSWORD   string
		HOST       string
		NAME       string
		PORT       int
		URL        string
		USAGELIMIT float32
	}
	MAILER struct {
		HOST     string
		USERNAME string
		PASSWORD string
		ENABLED  bool
	}
	MAP map[string]string
}

func (c *CONFIG2) Walk(tree *EnvTree, keyChain []string) (bool, error) {
	if setter, ok := map[string]func(*EnvTree, []string) error{
		"CONFIG2_DB_URL": c.setURL,
		"CONFIG2_MAP":    c.setMap,
	}[strings.Join(keyChain, "_")]; ok {
		return true, setter(tree, keyChain)
	}

	return false, nil
}

func (c *CONFIG2) setMap(tree *EnvTree, keyChain []string) error {
	datas := map[string]string{}

	keys, err := tree.FindChildrenKeys(keyChain...)

	if err != nil {
		return err
	}

	for _, key := range keys {
		value, err := tree.FindString(append(keyChain, key)...)

		if err != nil {
			return err
		}

		datas[key] = value
	}

	c.MAP = datas

	return nil
}

func (c *CONFIG2) setURL(tree *EnvTree, keyChain []string) error {
	datas := map[string]string{}

	for _, key := range []string{"USERNAME", "PASSWORD", "HOST", "NAME"} {
		value, err := tree.FindString("CONFIG2", "DB", key)

		if err != nil {
			return err
		}

		datas[key] = value
	}

	port, err := tree.FindInt("CONFIG2", "DB", "PORT")

	if err != nil {
		return err
	}

	c.DB.URL = fmt.Sprintf("jdbc:mysql://%s:%d/%s?user=%s&password=%s", datas["HOST"], port, datas["NAME"], datas["USERNAME"], datas["PASSWORD"])

	return nil
}

func main() {
	os.Clearenv()
	setEnv("CONFIG2_DB_USERNAME", "foo")
	setEnv("CONFIG2_DB_PASSWORD", "bar")
	setEnv("CONFIG2_DB_HOST", "localhost")
	setEnv("CONFIG2_DB_NAME", "my-db")
	setEnv("CONFIG2_DB_PORT", "3306")
	setEnv("CONFIG2_DB_USAGELIMIT", "95.6")
	setEnv("CONFIG2_MAILER_HOST", "127.0.0.1")
	setEnv("CONFIG2_MAILER_USERNAME", "foo")
	setEnv("CONFIG2_MAILER_PASSWORD", "bar")
	setEnv("CONFIG2_MAILER_ENABLED", "true")
	setEnv("CONFIG2_MAP_KEY1", "value1")
	setEnv("CONFIG2_MAP_KEY2", "value2")
	setEnv("CONFIG2_MAP_KEY3", "value3")

	env, err := NewEnvTree("^CONFIG2", "_")

	if err != nil {
		return
	}

	s := CONFIG2{}

	err = env.PopulateStruct(&s)

	if err != nil {
		return
	}

	b, err := json.Marshal(s)

	if err != nil {
		return
	}

	fmt.Println(string(b))
}
Output:

{"DB":{"USERNAME":"foo","PASSWORD":"bar","HOST":"localhost","NAME":"my-db","PORT":3306,"URL":"jdbc:mysql://localhost:3306/my-db?user=foo\u0026password=bar","USAGELIMIT":95.6},"MAILER":{"HOST":"127.0.0.1","USERNAME":"foo","PASSWORD":"bar","ENABLED":true},"MAP":{"KEY1":"value1","KEY2":"value2","KEY3":"value3"}}
Example (CustomValidation)
package main

import (
	"fmt"
	"net"
	"os"
	"strings"
)

type CONFIG3 struct {
	SERVER1 struct {
		IP   string
		PORT string
	}
	SERVER2 struct {
		IP   string
		PORT string
	}
}

func (c *CONFIG3) Walk(tree *EnvTree, keyChain []string) (bool, error) {
	if validator, ok := map[string]func(*EnvTree, []string) error{
		"CONFIG3_SERVER1_IP":   c.validateIP,
		"CONFIG3_SERVER2_IP":   c.validateIP,
		"CONFIG3_SERVER1_PORT": c.validatePort,
		"CONFIG3_SERVER2_PORT": c.validatePort,
	}[strings.Join(keyChain, "_")]; ok {
		return false, validator(tree, keyChain)
	}

	return false, nil
}

func (c *CONFIG3) validateIP(tree *EnvTree, keyChain []string) error {
	ipStr, err := tree.FindString(keyChain...)

	if err != nil {
		return err
	}

	if ip := net.ParseIP(ipStr); ip == nil {
		return fmt.Errorf(`"%s" is not a valid IP change "%s"`, ipStr, strings.Join(keyChain, "_"))
	}

	return nil
}

func (c *CONFIG3) validatePort(tree *EnvTree, keyChain []string) error {
	port, err := tree.FindInt(keyChain...)

	if err != nil {
		return err
	}

	if port < 1 || port > 65535 {
		return fmt.Errorf(`"%d" is not a valid port, must be comprised between 1 and 65535 "%s"`, port, strings.Join(keyChain, "_"))
	}

	return nil
}

func main() {
	os.Clearenv()
	setEnv("CONFIG3_SERVER1_IP", "127.0.0.1")
	setEnv("CONFIG3_SERVER1_PORT", "3000")
	setEnv("CONFIG3_SERVER2_IP", "localhost")
	setEnv("CONFIG3_SERVER2_PORT", "4000")

	env, err := NewEnvTree("^CONFIG3", "_")

	if err != nil {
		return
	}

	s := CONFIG3{}

	err = env.PopulateStruct(&s)

	fmt.Println(err)
}
Output:

"localhost" is not a valid IP change "CONFIG3_SERVER2_IP"

type TypeUnsupported

type TypeUnsupported struct {
	ActualType   string
	RequiredType string
}

TypeUnsupported is triggered when a type isn't supported

func (TypeUnsupported) Error

func (e TypeUnsupported) Error() string

Error dump error

type VariableNotFoundError

type VariableNotFoundError struct {
}

VariableNotFoundError is triggered when environment variable cannot be found

func (VariableNotFoundError) Error

func (e VariableNotFoundError) Error() string

Error dump error

type WrongTypeError

type WrongTypeError struct {
	Value interface{}
	Type  string
}

WrongTypeError is triggered when we try to convert variable to a wrong type

func (WrongTypeError) Error

func (e WrongTypeError) Error() string

Error dump error

Jump to

Keyboard shortcuts

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