go-envconfig

module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 5, 2020 License: Apache-2.0

README

Envconfig

GoDoc

Envconfig populates struct fields based on environment variable values.

Usage

Define a struct with fields using the env tag:

type MyConfig struct {
  Port     int    `env:"PORT"`
  Username string `env:"USERNAME"`
}

Set some environment variables:

export PORT=5555
export USERNAME=yoyo

Process it using envconfig:

package main

import (
  "context"
  "log"

  "github.com/sethvargo/envconfig/pkg/go-envconfig"
)

func main() {
  ctx := context.Background()

  var c MyConfig
  if err := envconfig.Process(ctx, &c); err != nil {
    log.Fatal(err)
  }

  // c.Port = 5555
  // c.Username = "yoyo"
}

Configuration

Use the env struct tag to define configuration.

Required

If a field is required, processing will error if the environment variable is unset.

type MyStruct struct {
  Port int `env:"PORT,required"`
}

It is invalid to have a field as both required and default.

Default

If an environment variable is not set, the field will be set to the default value. Note that the environment variable must not be set (e.g. unset PORT). If the environment variable is the empty string, that counts as a "value" and the default will not be used.

type MyStruct struct {
  Port int `env:"PORT,default=5555"`
}

Complex Types

Durations

In the environment, time.Duration values are specified as a parsable Go duration:

type MyStruct struct {
  MyVar time.Duration `env:"MYVAR"`
}
export MYVAR="10m" # 10 * time.Minute
TextUnmarshaler / BinaryUnmarshaler

Types that implement TextUnmarshaler or BinaryUnmarshaler are processed as such.

Slices

In the environment, slices are specified as comma-separated values:

type MyStruct struct {
  MyVar []string `env:"MYVAR"`
}
export MYVAR="a,b,c,d" # []string{"a", "b", "c", "d"}

Note that byte slices are special cased and interpreted as strings from the environment.

Maps

In the environment, maps are specified as comma-separated key:value pairs:

type MyStruct struct {
  MyVar map[string]string `env:"MYVAR"`
}
export MYVAR="a:b,c:d" # map[string]string{"a":"b", "c":"d"}
Structs

Envconfig walks the entire struct, so deeply-nested fields are also supported. You can also define your own decoder (see below).

Extension

All built-in types are supported except Func and Chan. If you need to define a custom decoder, implement Decoder:

type MyStruct struct {
  field string
}

func (v *MyStruct) EnvDecode(val string) error {
  v.field = fmt.Sprintf("PREFIX-%s", val)
  return nil
}

If you need to modify environment variable values before processing, you can specify a custom Mutator:

type Config struct {
  Password `env:"PASSWORD"`
}

func resolveSecretFunc(ctx context.Context, key, value string) (string, error) {
  if strings.HasPrefix(key, "secret://") {
    return secretmanager.Resolve(ctx, value) // example
  }
  return value, nil
}

var config Config
ProcessWith(&config, OsLookuper(), resolveSecretFunc)

Inspiration

This library is conceptually similar to kelseyhightower/envconfig, with the following major behavioral differences:

  • Adds support for specifying a custom lookup function (such as a map), which is useful for testing.

  • Only populates fields if they contain zero or nil values. This means you can pre-initialize a struct and any pre-populated fields will not be overwritten during processing.

  • Support for interpolation. The default value for a field can be the value of another field.

  • Support for arbitrary mutators that change/resolve data before type conversion.

Directories

Path Synopsis
pkg
envconfig
Package envconfig populates struct fields based on environment variable values (or anything that responds to "Lookup").
Package envconfig populates struct fields based on environment variable values (or anything that responds to "Lookup").

Jump to

Keyboard shortcuts

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