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 ¶
var DefaultResolvers = []Resolver{ &FlagResolver{Args: os.Args}, &EnvResolver{}, }
DefaultResolvers used by Resolve() and MustResolve().
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.
Types ¶
type Bytes ¶
type Bytes uint64
Bytes value.
func ParseBytes ¶
ParseBytes is a utility function to parse initial Bytes values.
This function panics if parsing fails.
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.
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) 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) 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.