Git Product home page Git Product logo

envconfig's Introduction

envconfig

Build Status

import "github.com/kelseyhightower/envconfig"

Documentation

See godoc

Usage

Set some environment variables:

export MYAPP_DEBUG=false
export MYAPP_PORT=8080
export MYAPP_USER=Kelsey
export MYAPP_RATE="0.5"
export MYAPP_TIMEOUT="3m"
export MYAPP_USERS="rob,ken,robert"
export MYAPP_COLORCODES="red:1,green:2,blue:3"

Write some code:

package main

import (
    "fmt"
    "log"
    "time"

    "github.com/kelseyhightower/envconfig"
)

type Specification struct {
    Debug       bool
    Port        int
    User        string
    Users       []string
    Rate        float32
    Timeout     time.Duration
    ColorCodes  map[string]int
}

func main() {
    var s Specification
    err := envconfig.Process("myapp", &s)
    if err != nil {
        log.Fatal(err.Error())
    }
    format := "Debug: %v\nPort: %d\nUser: %s\nRate: %f\nTimeout: %s\n"
    _, err = fmt.Printf(format, s.Debug, s.Port, s.User, s.Rate, s.Timeout)
    if err != nil {
        log.Fatal(err.Error())
    }

    fmt.Println("Users:")
    for _, u := range s.Users {
        fmt.Printf("  %s\n", u)
    }

    fmt.Println("Color codes:")
    for k, v := range s.ColorCodes {
        fmt.Printf("  %s: %d\n", k, v)
    }
}

Results:

Debug: false
Port: 8080
User: Kelsey
Rate: 0.500000
Timeout: 3m0s
Users:
  rob
  ken
  robert
Color codes:
  red: 1
  green: 2
  blue: 3

Struct Tag Support

Envconfig supports the use of struct tags to specify alternate, default, and required environment variables.

For example, consider the following struct:

type Specification struct {
    ManualOverride1 string `envconfig:"manual_override_1"`
    DefaultVar      string `default:"foobar"`
    RequiredVar     string `required:"true"`
    IgnoredVar      string `ignored:"true"`
    AutoSplitVar    string `split_words:"true"`
    RequiredAndAutoSplitVar    string `required:"true" split_words:"true"`
}

Envconfig has automatic support for CamelCased struct elements when the split_words:"true" tag is supplied. Without this tag, AutoSplitVar above would look for an environment variable called MYAPP_AUTOSPLITVAR. With the setting applied it will look for MYAPP_AUTO_SPLIT_VAR. Note that numbers will get globbed into the previous word. If the setting does not do the right thing, you may use a manual override.

Envconfig will process value for ManualOverride1 by populating it with the value for MYAPP_MANUAL_OVERRIDE_1. Without this struct tag, it would have instead looked up MYAPP_MANUALOVERRIDE1. With the split_words:"true" tag it would have looked up MYAPP_MANUAL_OVERRIDE1.

export MYAPP_MANUAL_OVERRIDE_1="this will be the value"

# export MYAPP_MANUALOVERRIDE1="and this will not"

If envconfig can't find an environment variable value for MYAPP_DEFAULTVAR, it will populate it with "foobar" as a default value.

If envconfig can't find an environment variable value for MYAPP_REQUIREDVAR, it will return an error when asked to process the struct. If MYAPP_REQUIREDVAR is present but empty, envconfig will not return an error.

If envconfig can't find an environment variable in the form PREFIX_MYVAR, and there is a struct tag defined, it will try to populate your variable with an environment variable that directly matches the envconfig tag in your struct definition:

export SERVICE_HOST=127.0.0.1
export MYAPP_DEBUG=true
type Specification struct {
    ServiceHost string `envconfig:"SERVICE_HOST"`
    Debug       bool
}

Envconfig won't process a field with the "ignored" tag set to "true", even if a corresponding environment variable is set.

Supported Struct Field Types

envconfig supports these struct field types:

Embedded structs using these fields are also supported.

Custom Decoders

Any field whose type (or pointer-to-type) implements envconfig.Decoder can control its own deserialization:

export DNS_SERVER=8.8.8.8
type IPDecoder net.IP

func (ipd *IPDecoder) Decode(value string) error {
    *ipd = IPDecoder(net.ParseIP(value))
    return nil
}

type DNSConfig struct {
    Address IPDecoder `envconfig:"DNS_SERVER"`
}

Example for decoding the environment variables into map[string][]structName type

export SMS_PROVIDER_WITH_WEIGHT= `IND=[{"name":"SMSProvider1","weight":70},{"name":"SMSProvider2","weight":30}];US=[{"name":"SMSProvider1","weight":100}]`
type providerDetails struct {
	Name   string
	Weight int
}

type SMSProviderDecoder map[string][]providerDetails

func (sd *SMSProviderDecoder) Decode(value string) error {
	smsProvider := map[string][]providerDetails{}
	pairs := strings.Split(value, ";")
	for _, pair := range pairs {
		providerdata := []providerDetails{}
		kvpair := strings.Split(pair, "=")
		if len(kvpair) != 2 {
			return fmt.Errorf("invalid map item: %q", pair)
		}
		err := json.Unmarshal([]byte(kvpair[1]), &providerdata)
		if err != nil {
			return fmt.Errorf("invalid map json: %w", err)
		}
		smsProvider[kvpair[0]] = providerdata

	}
	*sd = SMSProviderDecoder(smsProvider)
	return nil
}

type SMSProviderConfig struct {
    ProviderWithWeight SMSProviderDecoder `envconfig:"SMS_PROVIDER_WITH_WEIGHT"`
}

Also, envconfig will use a Set(string) error method like from the flag.Value interface if implemented.

envconfig's People

Contributors

kelseyhightower avatar teepark avatar dan9186 avatar andrei-m avatar dbainbri-ciena avatar mark-adams avatar frangm avatar aleksi avatar aybabtme avatar relistan avatar extemporalgenome avatar marcosnils avatar rafaeljusto avatar hullarb avatar curtisallen avatar dvrkps avatar beono avatar fsouza avatar gedge avatar hypnoglow avatar ingve avatar jprobinson avatar jhillyerd avatar jenan-stripe avatar mrjbq7 avatar tantalic avatar sosiska avatar sircelsius avatar mwedgwood-rmn avatar medyagh avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.