copperhead

package module
v1.4.0 Latest Latest
Warning

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

Go to latest
Published: Nov 7, 2018 License: MIT Imports: 9 Imported by: 0

README

Copperhead

GoDoc Goreport Build Status codecov

Configuration loader that can load configuration from environment, files, or byte slices.

Copperhead was written to match the features that we actually used in viper (https://github.com/spf13/viper). Configuration is always loaded into a struct. Unless you pass an UnmarshalerFunc the only supported format is JSON. The predecence of configuration sources is completely controlled by the order in which you load them. URLs can be parsed as a part of the configuration loading step.

Copperhead supports the "option function"-style shown below, which has the advantage of just giving you one place to error check. You can also call func (c *Config) Environment, func (c *Config) File, and func (c *Config) Data to load configuration sources one by one.

Example usage:

// Configuration is an example configuration struct
type Configuration struct {
	Name    string
	WD      string
	URL     *copperhead.URL
	FileURL *copperhead.URL
	Birdie  *ExampleNest
}

// ExampleNest is an exampe of a nested configuration struct.
type ExampleNest struct {
	Name       string
	Value      int64
	YamlIT     string `yaml:"yaml_it"`
	ComplexEnv int
}

// ExampleUsage is a testable example for Copperhead
func ExampleUsage() {
	os.Setenv("APP_NAME", "example-app")
	os.Setenv("APP_URL", "https://www.example.com")
	os.Setenv("APP_BIRD", "12")
	os.Setenv("DUMB_USAGE", `{"ComplexEnv":42}`)

	cfg := Configuration{
		WD: "with defaults",
	}
	ch, err := copperhead.New(&cfg,
		copperhead.WithConfigurationFile(
			"./test-data/example.conf", copperhead.FileRequired, nil,
		),
		copperhead.WithConfigurationFile(
			"./test-data/example.conf.yaml",
			copperhead.FileRequired,
			copperhead.UnmarshalerFunc(yaml.Unmarshal),
		),
		copperhead.WithEnvironment(map[string]string{
			"Name":         "APP_NAME",
			"URL":          "APP_URL",
			"Birdie.Value": "APP_BIRD",
			"Birdie":       "DUMB_USAGE",
		}),
	)
	if err != nil {
		println(err.Error())
		os.Exit(1)
	}

	fmt.Println("Name:", cfg.Name)
	fmt.Println("WD:", cfg.WD)
	fmt.Println("URL:", cfg.URL.String())
	fmt.Println("URL proto:", cfg.URL.Scheme)
	fmt.Println("Birdie.Name:", cfg.Birdie.Name)
	fmt.Println("Birdie.Value:", cfg.Birdie.Value)
	fmt.Println("Birdie.YamlIT:", cfg.Birdie.YamlIT)
	fmt.Println("Birdie.ComplexEnv:", cfg.Birdie.ComplexEnv)

	// Load additional config file.
	err = ch.File("./test-data/file-url.json",
		copperhead.FileRequired, nil)
	if err != nil {
		println(err.Error())
		os.Exit(1)
	}
	fmt.Println("File URL (json):", cfg.FileURL.String())

	err = ch.File("./test-data/file-url.yaml",
		copperhead.FileRequired,
		copperhead.UnmarshalerFunc(yaml.Unmarshal))
	if err != nil {
		println(err.Error())
		os.Exit(1)
	}
	fmt.Println("File URL (yaml):", cfg.FileURL.String())

	// Output:
	// Name: example-app
	// WD: with defaults
	// URL: https://www.example.com
	// URL proto: https
	// Birdie.Name: Heron
	// Birdie.Value: 12
	// Birdie.YamlIT: Hello from YAML
	// Birdie.ComplexEnv: 42
	// File URL (json): http://www.example.com/json
	// File URL (yaml): http://www.example.com/yaml
}

Documentation

Overview

Package copperhead provides a configuration loader that can load configuration from environment, files, or byte slices.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

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

Config encapsulates configuration loading.

Example

ExampleConfig is a testable example for Copperhead

package main

import (
	"fmt"
	"os"

	"github.com/Sydsvenskan/copperhead"
	yaml "gopkg.in/yaml.v2"
)

// Configuration is an example configuration struct
type Configuration struct {
	Name    string
	WD      string
	URL     *copperhead.URL
	FileURL *copperhead.URL
	Birdie  *ExampleNest
}

// ExampleNest is an exampe of a nested configuration struct.
type ExampleNest struct {
	Name       string
	Value      int64
	YamlIT     string `yaml:"yaml_it"`
	ComplexEnv int
}

// ExampleConfig is a testable example for Copperhead
func main() {
	os.Setenv("APP_NAME", "example-app")
	os.Setenv("APP_URL", "https://www.example.com")
	os.Setenv("APP_BIRD", "12")
	os.Setenv("DUMB_USAGE", `{"ComplexEnv":42}`)

	cfg := Configuration{
		WD: "with defaults",
	}
	ch, err := copperhead.New(&cfg,
		copperhead.WithConfigurationFile(
			"./test-data/example.conf", copperhead.FileRequired, nil,
		),
		copperhead.WithConfigurationFile(
			"./test-data/example.conf.yaml",
			copperhead.FileRequired,
			copperhead.UnmarshalerFunc(yaml.Unmarshal),
		),
		copperhead.WithEnvironment(map[string]string{
			"Name":         "APP_NAME",
			"URL":          "APP_URL",
			"Birdie.Value": "APP_BIRD",
			"Birdie":       "DUMB_USAGE",
		}),
	)
	if err != nil {
		println(err.Error())
		os.Exit(1)
	}

	fmt.Println("Name:", cfg.Name)
	fmt.Println("WD:", cfg.WD)
	fmt.Println("URL:", cfg.URL.String())
	fmt.Println("URL proto:", cfg.URL.Scheme)
	fmt.Println("Birdie.Name:", cfg.Birdie.Name)
	fmt.Println("Birdie.Value:", cfg.Birdie.Value)
	fmt.Println("Birdie.YamlIT:", cfg.Birdie.YamlIT)
	fmt.Println("Birdie.ComplexEnv:", cfg.Birdie.ComplexEnv)

	// Load additional config file.
	err = ch.File("./test-data/file-url.json",
		copperhead.FileRequired, nil)
	if err != nil {
		println(err.Error())
		os.Exit(1)
	}
	fmt.Println("File URL (json):", cfg.FileURL.String())

	err = ch.File("./test-data/file-url.yaml",
		copperhead.FileRequired,
		copperhead.UnmarshalerFunc(yaml.Unmarshal))
	if err != nil {
		println(err.Error())
		os.Exit(1)
	}
	fmt.Println("File URL (yaml):", cfg.FileURL.String())

}
Output:

Name: example-app
WD: with defaults
URL: https://www.example.com
URL proto: https
Birdie.Name: Heron
Birdie.Value: 12
Birdie.YamlIT: Hello from YAML
Birdie.ComplexEnv: 42
File URL (json): http://www.example.com/json
File URL (yaml): http://www.example.com/yaml

func New

func New(conf interface{}, opts ...Option) (*Config, error)

New creates a new configuration that populates conf.

func (*Config) Data

func (c *Config) Data(data []byte, unm Unmarshaler) error

Data reads the provided configuration data.

func (*Config) Environment

func (c *Config) Environment(envMap map[string]string) error

Environment populates our configuration with environment variables.

func (*Config) File

func (c *Config) File(filename string, mode FileMode, unm Unmarshaler) error

File reads configuration from a file.

func (*Config) Getenv added in v1.2.0

func (c *Config) Getenv(field, env string) error

Getenv reads a single environment variable.

func (*Config) Require added in v1.4.0

func (c *Config) Require(names ...string) error

type Duration added in v1.2.0

type Duration struct {
	time.Duration
}

Duration is an TextUnmarshaler-aware Duration

func (*Duration) UnmarshalText added in v1.2.0

func (d *Duration) UnmarshalText(text []byte) error

UnmarshalText implements encoding.TextUnmarshaler.

type FileMode

type FileMode string

FileMode controls file loading behaviour.

const (
	FileRequired FileMode = "required"
	FileOptional          = "optional"
)

The file loading modes

type Option

type Option func(c *Config) error

Option configures our... inception!

func WithConfigurationData

func WithConfigurationData(data []byte, unm Unmarshaler) Option

WithConfigurationData reads the provided configuration data.

func WithConfigurationFile

func WithConfigurationFile(filename string, mode FileMode, unm Unmarshaler) Option

WithConfigurationFile reads configuration from a file.

func WithEnvironment

func WithEnvironment(envMap map[string]string) Option

WithEnvironment bootstraps our configuration with environment variables.

type Time added in v1.2.0

type Time struct {
	time.Time
}

Time is an TextUnmarshaler-aware Time

func (*Time) UnmarshalText added in v1.2.0

func (t *Time) UnmarshalText(text []byte) error

UnmarshalText implements encoding.TextUnmarshaler.

type URL added in v1.1.0

type URL struct {
	url.URL
}

URL is an TextUnmarshaler-aware URL

func MustParseURL added in v1.3.0

func MustParseURL(rawURL string) *URL

MustParseURL is a helper function for setting configuration defaults. Panics if the passed url is invalid.

func (*URL) UnmarshalText added in v1.1.0

func (u *URL) UnmarshalText(text []byte) error

UnmarshalText implements encoding.TextUnmarshaler.

type Unmarshaler

type Unmarshaler interface {
	Unmarshal(data []byte, v interface{}) error
}

Unmarshaler is something that can unmarshal a configuration.

type UnmarshalerFunc

type UnmarshalerFunc func(data []byte, v interface{}) error

UnmarshalerFunc is an unmarshal function

func (UnmarshalerFunc) Unmarshal

func (uf UnmarshalerFunc) Unmarshal(
	data []byte, v interface{},
) error

Unmarshal the config data.

Jump to

Keyboard shortcuts

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