config

package module
v0.0.0-...-8f757e7 Latest Latest
Warning

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

Go to latest
Published: Sep 5, 2015 License: MIT Imports: 12 Imported by: 0

README

GoDoc Build Status

go-config

Simpler Go configuration with structs.

Features

  • Declare configuration with structs and tags
  • Type coercion out of the box
  • Validation out of the box
  • Pluggable resolvers
  • Built-in resolvers (flag, env)
  • Unambiguous resolution (must be specified via from)

Example

Source:

package main

import (
	"log"
	"os"
	"time"

	"github.com/tj/go-config"
)

type Options struct {
	Timeout     time.Duration `desc:"message timeout"`
	Concurrency uint          `desc:"message concurrency"`
	CacheSize   config.Bytes  `desc:"cache size in bytes"`
	BatchSize   uint          `desc:"batch size" validate:"min=1,max=1000"`
	LogLevel    string        `desc:"log severity level" from:"env,flag"`
}

func main() {
	options := Options{
		Timeout:     time.Second * 5,
		Concurrency: 10,
		CacheSize:   config.ParseBytes("100mb"),
		BatchSize:   250,
	}

	config.MustResolve(&options)
	log.Printf("%+v", options)
}

Command-line:

$ LOG_LEVEL=error example --timeout 10s --concurrency 100 --cache-size 1gb

License

MIT

Documentation

Overview

Package config provides an API for resolving configuration values from structs, with extensible resolvers, type coercion and validation.

Out of the box FlagResolver and EnvResolver are provided, however you may provide your own by implementing the Resolver interface.

Each field may have a "name" tag, which is otherwise derived from field, a "desc" tag used to describe the field, and a "validate" tag which utilizes https://gopkg.in/validator.v2 under the hood for validation.

Defaults are provided by the initialized struct.

Example (Nested)

ExampleNested illustrates how nested structs may be used. In this example --nsq-address and --nsq-max-in-flight flags would be available, as well as NSQ_ADDRESS and NSQ_MAX_IN_FLIGHT.

package main

import (
	"log"
	"os"

	"github.com/tj/go-config"
)

type NestedOptions struct {
	LogLevel string `desc:"set the log severity"`
	NSQ      struct {
		Address     string   `desc:"nsqd address"`
		Lookup      []string `desc:"nsqlookupd addresses"`
		MaxInFlight int      `desc:"nsqd max in flight messages"`
	}
}

// ExampleNested illustrates how nested structs may be used. In this
// example --nsq-address and --nsq-max-in-flight flags would be
// available, as well as NSQ_ADDRESS and NSQ_MAX_IN_FLIGHT.
func main() {
	options := &NestedOptions{}

	c := config.Config{
		Options: options,
		Resolvers: []config.Resolver{
			&config.FlagResolver{Args: os.Args},
			&config.EnvResolver{},
		},
	}

	err := c.Resolve()
	if err != nil {
		log.Fatalf("error: %s", err)
	}
}
Output:

Example (Resolve)

ExampleResolve illustrates the simplest way to use go-config. Using the MustResolve function pre-configures the flag and env resolvers for the average use-case.

package main

import (
	"github.com/tj/go-config"
)

type Options struct {
	Concurrency uint   `desc:"max in-flight messages"`
	LogLevel    string `desc:"log level"`
}

// ExampleResolve illustrates the simplest way to use go-config. Using
// the MustResolve function pre-configures the flag and env resolvers for
// the average use-case.
func main() {
	options := &Options{
		Concurrency: 5,
		LogLevel:    "info",
	}

	err := config.Resolve(options)
	if err != nil {
		panic(err)
	}
}
Output:

Example (Resolvers)

ExampleResolvers illustrates how you may initialize a Config struct in order to provide custom resolvers for more flexibility.

package main

import (
	"log"
	"os"
	"time"

	"github.com/tj/go-config"
)

type ResolverOptions struct {
	Timeout     time.Duration `desc:"message timeout"`
	Concurrency uint          `desc:"max in-flight messages"`
	CacheSize   config.Bytes  `desc:"cache size in bytes"`
	BatchSize   uint          `desc:"batch size" validate:"min=1,max=1000"`
	LogLevel    string        `desc:"set the log severity" from:"env,flag"`
}

// ExampleResolvers illustrates how you may initialize a Config
// struct in order to provide custom resolvers for more flexibility.
func main() {
	options := &ResolverOptions{
		Timeout:     5 * time.Second,
		Concurrency: 5,
		CacheSize:   config.ParseBytes("150mb"),
		BatchSize:   1000,
		LogLevel:    "info",
	}

	c := config.Config{
		Options: options,
		Resolvers: []config.Resolver{
			&config.FlagResolver{Args: os.Args},
			&config.EnvResolver{},
		},
	}

	err := c.Resolve()
	if err != nil {
		log.Fatalf("error: %s", err)
	}
}
Output:

Index

Examples

Constants

This section is empty.

Variables

View Source
var DefaultResolvers = []Resolver{
	&FlagResolver{Args: os.Args},
	&EnvResolver{},
}

DefaultResolvers used by Resolve() and MustResolve().

View Source
var (
	ErrFieldNotFound = errors.New("field not found")
)

Errors used during resolution.

Functions

func MustResolve

func MustResolve(options interface{})

MustResolve `options` using the built-in flag and env resolvers.

func Resolve

func Resolve(options interface{}) error

Resolve `options` using the built-in flag and env resolvers.

Types

type Bytes

type Bytes uint64

Bytes value.

func ParseBytes

func ParseBytes(s string) (b Bytes)

ParseBytes is a utility function to parse initial Bytes values.

This function panics if parsing fails.

func (*Bytes) Set

func (b *Bytes) Set(s string) error

Set value from string.

func (*Bytes) String

func (b *Bytes) String() string

String representation.

type Config

type Config struct {
	// Options struct.
	Options interface{}

	// Resolvers list; the ordering is significant,
	// as it defines precedence. The first resolver
	// is used for all fields unless the "from" tag
	// of a field indictates otherwise.
	Resolvers []Resolver
}

Config resolves options from the provided struct using one or more Resolvers.

func (*Config) Resolve

func (c *Config) Resolve() error

Resolve the configuration.

type EnvResolver

type EnvResolver struct {
	// Prefix optionally applied to each lookup. Omit the
	// trailing "_", this is applied automatically.
	Prefix string
}

EnvResolver resolves configuration from environment variables.

For example LogLevel field would become LOG_LEVEL=error.

func (*EnvResolver) Field

func (e *EnvResolver) Field(field Field) error

Field implementation normalizing the field name and performing coercion to the field type.

func (*EnvResolver) Name

func (e *EnvResolver) Name() string

Name implementation.

func (*EnvResolver) Resolve

func (*EnvResolver) Resolve() error

Resolve implementation (temporary noop).

func (*EnvResolver) Setup

func (e *EnvResolver) Setup() error

Setup implementation (temporary noop).

type Field

type Field interface {
	// Name returns the field's name. The name is derived either from
	// the "name" tag, or via reflection. Nested structs inherit the
	// parent field's name.
	Name() string

	// Interface of the field's pointer.
	Interface() interface{}

	// Value representation of the field's value.
	Value() Value

	// Tag returns the field's tag via its `name`.
	Tag(name string) string
}

Field represents a struct field which is passed to resolvers for lookup.

type FlagResolver

type FlagResolver struct {
	Args []string // Args from the command-line
	// contains filtered or unexported fields
}

FlagResolver resolves configuration from command-line flags.

For example LogLevel field would become -log-level=error.

func (*FlagResolver) Field

func (f *FlagResolver) Field(field Field) error

Field implementation populating the flag set.

func (*FlagResolver) Name

func (f *FlagResolver) Name() string

Name implementation.

func (*FlagResolver) Resolve

func (f *FlagResolver) Resolve() error

Resolve implementation parsing the flag set.

func (*FlagResolver) Setup

func (f *FlagResolver) Setup() error

Setup implementation setting up the flag set.

type Resolver

type Resolver interface {
	// Name of the resolver such as "env", or "flag".
	Name() string

	// Field attempts to reoslve a field; this method should replace the
	// field's value by using its pointer via Field.Interface(), or return
	// ErrFieldNotFound.
	Field(Field) error

	// Setup (temporary method, don't get attached ;D).
	Setup() error

	// Resolve (temporary method, don't get attached ;D).
	Resolve() error
}

Resolver represents a struct which "resolves" configuration fields, for example flag, environment variables, key/value stores and so on.

Warning: this interface will be nicer in the near future, the current interface is limited due to a limitation with the stdlib flag package.

type Value

type Value interface {
	String() string
	Set(string) error
}

Value represents a custom type which may be represented as text, primarily used within resolvers which are string-based such as environment variables and flags.

For example the Value interface may be used to implement a custom comma-delimited string slice.

Directories

Path Synopsis
Example program.
Example program.

Jump to

Keyboard shortcuts

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