env

package module
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Oct 26, 2020 License: MIT Imports: 10 Imported by: 3

README

go-env

GoDoc Build Status Coverage Status Go Report

Description

go-env is a Go library that can populate a struct with environment variable values. A common use of go-env is to load a configuration struct with values set in the environment variables.

Requirements

Go 1.13 or above.

Getting Started

Installation

Run the following command to install the package:

go get github.com/qiangxue/go-env
Loading From Environment Variables

The easiest way of using go-env is to call env.Load(), like the following:

package main

import (
	"fmt"
	"github.com/qiangxue/go-env"
	"os"
)

type Config struct {
	Host string
	Port int
}

func main() {
	_ = os.Setenv("APP_HOST", "127.0.0.1")
	_ = os.Setenv("APP_PORT", "8080")

	var cfg Config
	if err := env.Load(&cfg); err != nil {
		panic(err)
	}
	fmt.Println(cfg.Host)
	fmt.Println(cfg.Port)
	// Output:
	// 127.0.0.1
	// 8080
}
Environment Variable Names

When go-env populates a struct from environment variables, it uses the following rules to match a struct field with an environment variable:

  • Only public struct fields will be populated
  • If the field has an env tag, use the tag value as the name, unless the tag value is - in which case it means the field should NOT be populated.
  • If the field has no env tag, turn the field name into UPPER_SNAKE_CASE format and use that as the name. For example, a field name HostName will be turned into HOST_NAME, and MyURL becomes MY_URL.
  • Names are prefixed with the specified prefix when they are used to look up in the environment variables.

By default, prefix APP_ will be used. You can customize the prefix by using env.New() to create a customized loader. For example,

package main

import (
	"fmt"
	"github.com/qiangxue/go-env"
	"log"
	"os"
)

type Config struct {
	Host     string `env:"ES_HOST"`
	Port     int    `env:"ES_PORT"`
	Password string `env:"ES_PASSWORD,secret"`
}

func main() {
	_ = os.Setenv("API_ES_HOST", "127.0.0.1")
	_ = os.Setenv("API_ES_PORT", "8080")
	_ = os.Setenv("API_ES_PASSWORD", "test")

	var cfg Config
	loader := env.New("API_", log.Printf)
	if err := loader.Load(&cfg); err != nil {
		panic(err)
	}
	fmt.Println(cfg.Host)
	fmt.Println(cfg.Port)
	fmt.Println(cfg.Password)
	// Output:
	// 127.0.0.1
	// 8080
	// test
}

In the above code, the Password field is tagged as secret. The log function respects this flag by masking the field value when logging it in order not to reveal sensitive information.

By setting the prefix to an empty string, you can disable the name prefix completely.

Data Parsing Rules

Because the values of environment variables are strings, if the corresponding struct fields are of different types, go-env will convert the string values into appropriate types before assigning them to the struct fields.

  • If a struct contains embedded structs, the fields of the embedded structs will be populated like they are directly under the containing struct.

  • If a struct field type implements env.Setter, env.TextMarshaler, or env.BinaryMarshaler interface, the corresponding interface method will be used to load a string value into the field.

  • If a struct field is of a primary type, such as int, string, bool, etc., a string value will be parsed accordingly and assigned to the field. For example, the string value TRUE can be parsed correctly into a boolean true value, while TrUE will cause a parsing error.

  • If a struct field is of a complex type, such as map, slice, struct, the string value will be treated as a JSON string, and json.Unmarshal() will be called to populate the struct field from the JSON string.

Documentation

Overview

Example (One)
_ = os.Setenv("APP_HOST", "127.0.0.1")
_ = os.Setenv("APP_PORT", "8080")

var cfg Config
if err := env.Load(&cfg); err != nil {
	panic(err)
}
fmt.Println(cfg.Host)
fmt.Println(cfg.Port)
Output:

127.0.0.1
8080
Example (Two)
_ = os.Setenv("API_HOST", "127.0.0.1")
_ = os.Setenv("API_PORT", "8080")
_ = os.Setenv("API_PASSWORD", "test")

var cfg Config
loader := env.New("API_", log.Printf)
if err := loader.Load(&cfg); err != nil {
	panic(err)
}
fmt.Println(cfg.Host)
fmt.Println(cfg.Port)
fmt.Println(cfg.Password)
Output:

127.0.0.1
8080
test

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrStructPointer represents the error that a pointer to a struct is expected.
	ErrStructPointer = errors.New("must be a pointer to a struct")
	// ErrNilPointer represents the error that a nil pointer is received
	ErrNilPointer = errors.New("the pointer should not be nil")
	// TagName specifies the tag name for customizing struct field names when loading environment variables
	TagName = "env"
)

Functions

func Load

func Load(structPtr interface{}) error

Load populates a struct with the values read from the corresponding environment variables. Load uses "APP_" as the prefix for environment variable names. It uses log.Printf() to log the data population of each struct field. For more details on how Load() works, please refer to Loader.Load().

Types

type Loader

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

Loader loads a struct with values returned by a lookup function.

func New

func New(prefix string, log LogFunc) *Loader

New creates a new environment variable loader. The prefix will be used to prefix the struct field names when they are used to read from environment variables.

func NewWithLookup

func NewWithLookup(prefix string, lookup LookupFunc, log LogFunc) *Loader

NewWithLookup creates a new loader using the given lookup function. The prefix will be used to prefix the struct field names when they are used to read from environment variables.

func (*Loader) Load

func (l *Loader) Load(structPtr interface{}) error

Load populates a struct with the values read returned by the specified lookup function. The struct must be specified as a pointer.

Load calls a lookup function for each public struct field. If the function returns a value, it is parsed according to the field type and assigned to the field.

Load uses the following rules to determine what name should be used to look up the value for a struct field:

  • If the field has an "env" tag, use the tag value as the name, unless the tag is "-" in which case it means the field should be skipped.
  • If the field has no "env" tag, turn the field name into UPPER_SNAKE_CASE format and use that as the name.
  • Names are prefixed with the specified prefix.

The following types of struct fields are supported:

  • types implementing Setter, TextUnmarshaler, BinaryUnmarshaler: the corresponding interface method will be used to populate the field with a string
  • primary types (e.g. int, string): appropriate parsing functions will be called to parse a string value
  • other types (e.g. array, struct): the string value is assumed to be in JSON format and is decoded/assigned to the field.

Load will log every field that is populated. In case when a field is tagged with `env:",secret"`, the value being logged will be masked for security purpose.

type LogFunc

type LogFunc func(format string, args ...interface{})

LogFunc logs a message.

type LookupFunc

type LookupFunc func(name string) (string, bool)

LookupFunc looks up a name and returns the corresponding value and a flag indicating if the name is found.

type Setter

type Setter interface {
	// Set sets the object with a string value.
	Set(value string) error
}

Setter sets the object with a string value.

Jump to

Keyboard shortcuts

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