Documentation ¶
Overview ¶
Package goconfigure provides configuration options for an application, allowing configuration to come from a variety of sources.
Example ¶
package main import ( "fmt" "os" "bitbucket.org/idomdavis/goconfigure" ) type Settings struct { Count int `json:"Message Count"` Message string `json:"Display Message"` Unset string `json:"Unset Option"` } func (s *Settings) Description() string { return "Example Options Block" } // Data can override the values in the backing type to hide or enhance what is // reported about the settings. func (s *Settings) Data() interface{} { return Settings{ Count: s.Count, Message: s.Message, // Here we will display the contents of s.Unset if it is set, otherwise // a generic unset message will be shown. Unset: goconfigure.Sanitise(s.Unset, s.Unset, goconfigure.UNSET), } } func (s *Settings) Register(opts goconfigure.OptionSet) { opts.Add(&goconfigure.Option{ Pointer: &s.Message, Description: "The message to display", ShortFlag: 'm', ConfigKey: "message", Default: "This space intentionally left blank", }) opts.Add(opts.Option(&s.Count, 1, "count", "The number of times to display the message")) opts.Add(&goconfigure.Option{ Pointer: &s.Unset, Default: "This can't get set", }) } func main() { settings := &Settings{} // When using environment variables they will all be of the form // EXAMPLE_<name> s := goconfigure.NewSettings("EXAMPLE") s.AddHelp() s.AddConfigFile() s.Add(settings) args := []string{"-c", "testdata/options.json", "--count", "2"} reporter := goconfigure.ConsoleReporter{} // You can use opts.Parse() to grab the command line arguments, however, // passing in the arguments makes testing easier. if err := s.ParseUsing(args, reporter); err != nil { fmt.Println(err) s.Options.Usage(os.Stdout) os.Exit(-1) } for i := 0; i < settings.Count; i++ { fmt.Println(settings.Message) } fmt.Println(settings.Unset) fmt.Println(s.UsageString()) }
Output: Example Options Block: [Display Message:Hello, world!, Message Count:2, Unset Option:This can't get set] Hello, world! Hello, world! This can't get set -h, --help Display this help -c, --config Configure via the given configuration file. Use $EXAMPLE_CONFIG_FILE to set this using environment variables. -m The message to display (default "This space intentionally left blank") Use 'message' to set this in the config file. --count The number of times to display the message (default 1) Use $EXAMPLE_COUNT to set this using environment variables. Use 'count' to set this in the config file. No CLI option (default "This can't get set")
Example (No_config_file) ¶
// Use Settings from goconfigure_test settings := &Settings{} s := goconfigure.NewSettings("TEST") s.AddConfigFile() s.Add(settings) reporter := goconfigure.ConsoleReporter{} if err := s.ParseUsing([]string{"-m", "msg", "--count", "2"}, reporter); err != nil { fmt.Println(err) }
Output: Example Options Block: [Display Message:msg, Message Count:2, Unset Option:This can't get set]
Index ¶
- Constants
- Variables
- func Sanitise(v, set, unset interface{}) string
- type Block
- type ConsoleReporter
- type Env
- type External
- type Flags
- type LogrusReporter
- type NullReporter
- type Option
- type OptionSet
- type Options
- func (o *Options) Add(option *Option)
- func (o *Options) Flag(i interface{}, name rune, description string) *Option
- func (o *Options) LoadUsing(option *Option)
- func (o *Options) Option(i, d interface{}, name, description string) *Option
- func (o *Options) Parse() error
- func (o *Options) ParseUsing(args []string) error
- func (o *Options) ToEnv(name string) string
- func (o *Options) Usage(w io.Writer)
- func (o *Options) UsageString() string
- type Reporter
- type Settings
Examples ¶
Constants ¶
const ( SET = "SET" UNSET = "UNSET" )
Common values used by Sanitise.
Variables ¶
var ( // ErrLoadingConfig is returned if a config file cannot be read from the // path or URL given. ErrLoadingConfig = errors.New("error loading config") // ErrParsingConfig is returned if the config file is not valid JSON. ErrParsingConfig = errors.New("error parsing config") // ErrInvalidDuration is returned if the config file contains an invalid // duration string. ErrInvalidDuration = errors.New("invalid duration value") // ErrConversionFailure is returned if a value from a config file cannot be // applied to the Option for that value. ErrConversionFailure = errors.New("cannot convert config type") )
var ( // ErrFlagError is returned when there is an error parsing the flags. It is // used to wrap errors from the flags package which are not wrapped errors. ErrFlagError = errors.New("flag parse error") // ErrInvalidTypeOption is returned when the type on the option cannot be // set via a flag. ErrInvalidTypeOption = errors.New("invalid option type for flag") // ErrInvalidDefault is returned if the default value cannot be used on the // type set for the option. ErrInvalidDefault = errors.New("cannot use default option") )
var ( // ErrNoPointer is returned by Option.Check() if no pointer is set on the // Option. ErrNoPointer = errors.New("no pointer set on option") // ErrNotPointer is returned by Option.Check() if the type set on // Option.Pointer is not a pointer. ErrNotPointer = errors.New("incorrect type on option") )
var ErrFailedToReadURI = errors.New("failed to read URI for config file")
ErrFailedToReadURI is returned if the URI for the config file is not in the expected format.
var ErrInvalidDataFormat = errors.New("invalid data format")
ErrInvalidDataFormat is returned by Settings.Parse and Settings.ParseUsing if the Block.Data function returns a struct that will not fit in a
map[string]interface{}
var ErrInvalidDataType = errors.New("invalid data type")
ErrInvalidDataType is returned by Settings.Parse and Settings.ParseUsing if the Block.Data function returns a struct with data types that are not supported by goconfigure.
var Help bool
Help will be set to true if the HelpOption has been registered and the relevant flag set on the command line. If Help is true then the application should output usage information and exit.
Functions ¶
func Sanitise ¶ added in v0.4.1
func Sanitise(v, set, unset interface{}) string
Sanitise a value, returning unset if v is nil or has a zero value, and set otherwise.
Example ¶
package main import ( "fmt" "bitbucket.org/idomdavis/goconfigure" ) func main() { fmt.Println(goconfigure.Sanitise(nil, goconfigure.SET, goconfigure.UNSET)) fmt.Println(goconfigure.Sanitise(1, goconfigure.SET, goconfigure.UNSET)) }
Output: UNSET SET
Types ¶
type Block ¶ added in v0.5.0
type Block interface { // Description of the option block. Description is used when reporting on // the options set. Description() string // Register the options in the block against the given OptionSet. Register(opts OptionSet) // Data set by the options. The type returned by Data should map to a // map[string]interface{} and is used when reporting on the options set // with the data being displayed as key/value pairs. All data to be // displayed must be on public properties and the display key can be set // using the json tag. Data() interface{} }
Block of Options. The block can Register itself against a set of Options and return its Description and current Data. The block Data should map to a map[string]interface{}.
type ConsoleReporter ¶ added in v0.5.0
type ConsoleReporter struct{}
ConsoleReporter reports information to STDOUT.
func (ConsoleReporter) Report ¶ added in v0.5.0
func (c ConsoleReporter) Report(description string, data map[string]interface{})
Report to STDOUT.
type Env ¶ added in v0.4.0
Env holds the settings passed from environment variables.
func NewEnv ¶ added in v0.4.0
func NewEnv() *Env
NewEnv returns a new, empty set of environment variable settings.
func (*Env) Register ¶ added in v0.4.0
Register an option, getting the environment variable for the option if it's set. If a Stub is set on the Env this is prepended to the EnvVar name with a _ in the form Stub_o.EnvVar.
Example ¶
package main import ( "fmt" "os" "bitbucket.org/idomdavis/goconfigure" ) func main() { var ( s string i int ) const ( stub = "GOCONFIGURE" name = "TEST_ENV_VAR" env = stub + "_" + name ) _ = os.Setenv(env, "set") defer func() { _ = os.Setenv(env, "") }() e := goconfigure.NewEnv() e.Stub = stub settings := goconfigure.NewSettings(stub) o := settings.Options.Option(&i, "", name, "") if err := e.Register(o); err != nil { fmt.Println("failed") } o.Pointer = &s if err := e.Register(o); err != nil { fmt.Println(err) } fmt.Println(e.Data[env].Pointer) }
Output: failed set
type External ¶ added in v0.4.0
type External map[string]interface{}
External configuration data. This can either be loaded as a JSON file from a URI (path or URL), or be set explicitly.
func (*External) Load ¶ added in v0.4.0
Load external configuration from a URI. The configuration details for an Option can be retrieved using Value.
func (*External) Value ¶ added in v0.5.0
Value for the given Option. If the Option has not been set in the external config, or the external config has not been loaded, then an empty, unset value.Data is returned. Returns ErrConversionFailure if the value set in config cannot be applied to the Option. Returns ErrInvalidDuration if an invalid duration string is given.
type Flags ¶ added in v0.4.0
Flags holds the settings passed in from the command line.
type LogrusReporter ¶ added in v0.5.0
LogrusReporter reports via Logrus.
func (LogrusReporter) Report ¶ added in v0.5.0
func (l LogrusReporter) Report(description string, data map[string]interface{})
Report to Logrus.
Example ¶
package main import ( "os" "bitbucket.org/idomdavis/goconfigure" "github.com/sirupsen/logrus" ) func main() { var l goconfigure.Reporter logger := logrus.New() logger.SetOutput(os.Stdout) logger.SetFormatter(&logrus.TextFormatter{ DisableColors: true, DisableTimestamp: true, }) l = goconfigure.LogrusReporter{} l.Report("data", map[string]interface{}{"k": "v"}) l.Report("message", nil) l = goconfigure.LogrusReporter{Logger: logger} l.Report("data", map[string]interface{}{"k": "v"}) l.Report("message", nil) l = goconfigure.ConsoleReporter{} l.Report("data", map[string]interface{}{"k": "v"}) l.Report("message", nil) l = goconfigure.NullReporter{} l.Report("data", map[string]interface{}{"k": "v"}) l.Report("message", nil) }
Output: level=info msg=data k=v level=info msg=message data: [k:v] message
type NullReporter ¶ added in v0.5.2
type NullReporter struct{}
NullReporter will not report anything.
func (NullReporter) Report ¶ added in v0.5.2
func (NullReporter) Report(string, map[string]interface{})
Report nothing.
type Option ¶
type Option struct { // ShortFlag defines a short flag for setting the Option from the command // line. For example: // // option.ShortFlag = 'f' // // allows the flag: // // myApp -f value // // Setting this does nothing if Parse has already been called. ShortFlag rune // LongFlag defines a long flag for setting the Option from the command // line. For example: // // option.LongFlag = "flag" // // allows the flag: // // myApp --flag value // // Setting this does nothing if Parse has already been called. LongFlag string // EnvVar defines the name of an environment variable that can be used to // set this option. The string value of the environment variable must be // convertible to the type of the Option. // // Setting this does nothing if Parse has already been called. EnvVar string // ConfigKey defines the key this option can use to set itself from a JSON // configuration file. The value stored under this key must be convertible // to the Option Type. // // Setting this does nothing if Parse has already been called. ConfigKey string // Description is used when producing usage information. It should explain // what the Option is used for. Description string // Pointer to a variable of the type of this option (*bool, *int, *int64, // *uint, *uint64, *float64, *string, *time.Duration). Pointer will be set // when the option is Set. Pointer interface{} // Default defines a value that will be used by the option if no flags, // environment variables, or configuration file values are set or found. The // value must be the same type as the Option Pointer. Default interface{} }
Option represents a configuration option that can be set either by flag, configuration file, environment variable, or a default value with the value to use being chosen in that order. Options must be one of bool, int, int64, uint, unit64, float64, string, or time.Duration.
func HelpOption ¶ added in v0.4.2
func HelpOption() *Option
HelpOption returns a flag configured on `h` and `help` which will be set to goconfigure.Help when parsed.
Example ¶
package main import ( "fmt" "bitbucket.org/idomdavis/goconfigure" ) func main() { opts := goconfigure.Options{} opts.Add(goconfigure.HelpOption()) _ = opts.ParseUsing([]string{"-h"}) fmt.Println(goconfigure.Help) }
Output: true
func (*Option) Set ¶ added in v0.4.0
Set the value for this option from one of the given values, or the default if none are set. The value chosen uses the precedence: short, long, env, external, Default.
func (*Option) Usage ¶ added in v0.4.0
Usage information for this option. nolint: gocyclo,cyclop
Example ¶
package main import ( "fmt" "bitbucket.org/idomdavis/goconfigure" ) func main() { var ( boolOpt bool intOpt int stringOpt string ) o := &goconfigure.Option{ ConfigKey: "config-key", Description: "What the option does", Pointer: &boolOpt, } fmt.Println(o.Usage()) o.LongFlag = "flag" o.Pointer = &intOpt o.Default = 1 fmt.Println(o.Usage()) o.ShortFlag = 'f' o.EnvVar = "ENV" o.Pointer = &stringOpt o.Default = "unset" fmt.Println(o.Usage()) }
Output: No CLI option What the option does Use 'config-key' to set this in the config file. --flag What the option does (default 1) Use 'config-key' to set this in the config file. -f, --flag What the option does (default "unset") Use $ENV to set this using environment variables. Use 'config-key' to set this in the config file.
type OptionSet ¶ added in v0.5.0
type OptionSet interface { Add(option *Option) Flag(i interface{}, name rune, description string) *Option Option(i, d interface{}, name, description string) *Option }
OptionSet that can be added to.
type Options ¶
type Options struct { // Stub is an optional stub that can be prepended to environment variable // names in the format Stub_Name. Stub string // contains filtered or unexported fields }
Options holds a set of configuration options which can be provided by the command line, environment variables, configuration files, or default values.
func (*Options) Add ¶
Add an Option to this set of Options.
Example ¶
package main import ( "fmt" "time" "bitbucket.org/idomdavis/goconfigure" ) func main() { var options struct { boolean bool integer int long int64 unsigned uint unsignedLong uint64 float float64 text string duration time.Duration } opts := &goconfigure.Options{} opts.Add(opts.Flag(&options.boolean, 'b', "boolean")) opts.Add(opts.Flag(&options.integer, 'i', "integer")) opts.Add(opts.Flag(&options.long, 'l', "long")) opts.Add(opts.Flag(&options.unsigned, 'u', "unsigned")) opts.Add(opts.Flag(&options.unsignedLong, 'z', "unsignedLong")) opts.Add(opts.Flag(&options.float, 'f', "float")) opts.Add(opts.Flag(&options.text, 't', "text")) opts.Add(opts.Flag(&options.duration, 'd', "duration")) err := opts.ParseUsing([]string{ "-b", "-i", "1", "-l", "2", "-u", "3", "-z", "4", "-f", "5.6", "-t", "words", "-d", "60s", }) if err == nil { fmt.Println(options) } else { fmt.Println(err) } }
Output: {true 1 2 3 4 5.6 words 60000000000}
func (*Options) Flag ¶ added in v0.5.3
Flag returns an option that only uses a command line flag. i is the Option.Pointer to set (which must be one of *bool, *int, *int64, *uint, *uint64, *float64, *string, or *time.Duration) The description is used when producing usage information. Providing an invalid type for i will not error here, but will generate an error when Option.Check is called.
func (*Options) LoadUsing ¶ added in v0.4.0
LoadUsing configuration file, the URI for which will be obtained from the given option. The option must resolve to a string. By definition this option can't be read from the configuration file and must come from a flag or environment variable.
Example ¶
package main import ( "fmt" "bitbucket.org/idomdavis/goconfigure" ) func main() { var options struct { config string numeric int text string overridden string } opts := &goconfigure.Options{Stub: "STUB"} opts.Add(opts.Option(&options.text, "unset", "", "unset option")) opts.Add(opts.Option(&options.numeric, 0, "numeric", "unset option")) opts.Add(&goconfigure.Option{ Pointer: &options.overridden, ShortFlag: 'o', }) opt := opts.Flag(&options.config, 'f', "config file") opts.Add(opt) opts.LoadUsing(opt) if err := opts.ParseUsing([]string{ "-f", "testdata/config.json", "-o", "overridden", }); err != nil { fmt.Println(err) } fmt.Println(options) }
Output: {testdata/config.json 4 unset overridden}
func (*Options) Option ¶ added in v0.5.3
Option returns an option with i being the Option.Pointer to set (which must be one of *bool, *int, *int64, *uint, *uint64, *float64, *string, or *time.Duration) and d being the default value of the same type, or nil for no default. The description is used when producing usage information. Providing an invalid type for i or d will not error here, but will generate an error when Option.Check is called. The Option.LongFlag and Option.ConfigKey are both set to name. Option.EnvVar is set to name with all `-` characters changed to `_`, and the entire string in upper case.
func (*Options) ParseUsing ¶
ParseUsing uses the given arguments as the set of command line arguments.
Example ¶
package main import ( "fmt" "bitbucket.org/idomdavis/goconfigure" ) func main() { var options struct { value string } opts := &goconfigure.Options{Stub: "STUB"} opts.Add(opts.Option(&options.value, "", "value", "value to set")) if err := opts.ParseUsing([]string{"--value", "set"}); err != nil { fmt.Println(err) } fmt.Println(options) }
Output: {set}
func (*Options) ToEnv ¶ added in v0.5.3
ToEnv will turn a name into an environment variable by replacing all non word characters with '_'.
func (*Options) Usage ¶
Usage displays the usage information for this set of options to the given writer. An error writing the usage will cause a panic. A nil writer will do nothing.
func (*Options) UsageString ¶
UsageString building of custom usage output by providing just the usage details for the defined options.
type Reporter ¶ added in v0.5.0
type Reporter interface { // Report the configuration block. The description is an arbitrary text // string used to identify the block, the data is the set of options. It is // save to assume the data will be a primitive, or fmt.Stringer. Report(description string, data map[string]interface{}) }
A Reporter is used to report configuration information.
type Settings ¶ added in v0.5.0
type Settings struct { Help bool Blocks []Block *Options // contains filtered or unexported fields }
Settings all for configuration of an app via Options and sets of Block types.
func NewSettings ¶ added in v0.5.0
NewSettings returns an empty Settings type set to use the given stub for environment variables.
func (*Settings) Add ¶ added in v0.5.0
Add a Block to the Settings. Settings may have any number of blocks, but generally have at least 1.
func (*Settings) AddConfigFile ¶ added in v0.5.0
func (s *Settings) AddConfigFile()
AddConfigFile to the Settings. This will register `-c` and `--config`, plus check <stub>_CONFIG_FILE and load settings from the file if these are set.
func (*Settings) AddHelp ¶ added in v0.5.0
func (s *Settings) AddHelp()
AddHelp to the Settings. This will register `-h` and `--help. Settings.Help will be set to true if the flag is passed.