Documentation ¶
Overview ¶
Package mcfg implements the creation of different types of configuration parameters and various methods of filling those parameters from external configuration sources (e.g. the command line and environment variables).
Parameters are registered onto a Component, and that same Component (or one of its ancestors) is used later to collect and fill those parameters.
Index ¶
- func AddParam(cmp *mcmp.Component, param Param, opts ...ParamOption)
- func Bool(cmp *mcmp.Component, name string, opts ...ParamOption) *bool
- func CLISubCommand(cmp *mcmp.Component, name, descr string, callback func(*mcmp.Component)) *bool
- func CLITail(cmp *mcmp.Component, descr string) *[]string
- func Duration(cmp *mcmp.Component, name string, opts ...ParamOption) *mtime.Duration
- func Float64(cmp *mcmp.Component, name string, opts ...ParamOption) *float64
- func Int(cmp *mcmp.Component, name string, opts ...ParamOption) *int
- func Int64(cmp *mcmp.Component, name string, opts ...ParamOption) *int64
- func JSON(cmp *mcmp.Component, name string, into interface{}, opts ...ParamOption)
- func Populate(cmp *mcmp.Component, src Source) error
- func String(cmp *mcmp.Component, name string, opts ...ParamOption) *string
- func TS(cmp *mcmp.Component, name string, opts ...ParamOption) *mtime.TS
- type Param
- type ParamOption
- type ParamValue
- type ParamValues
- type Source
- type SourceCLI
- type SourceEnv
- type Sources
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AddParam ¶
func AddParam(cmp *mcmp.Component, param Param, opts ...ParamOption)
AddParam adds the given Param to the given Component. It will panic if a Param with the same Name already exists in the Component.
func Bool ¶
func Bool(cmp *mcmp.Component, name string, opts ...ParamOption) *bool
Bool returns a *bool which will be populated once Populate is run on the Component, and which defaults to false if unconfigured.
The default behavior of all Sources is that a boolean parameter will be set to true unless the value is "", 0, or false. In the case of the CLI Source the value will also be true when the parameter is used with no value at all, as would be expected.
func CLISubCommand ¶
CLISubCommand establishes a sub-command which can be activated on the command-line. When a sub-command is given on the command-line, the bool returned for that sub-command will be set to true.
Additionally, the Component which was passed into Parse (i.e. the one passed into Populate) will be passed into the given callback, and can be modified for subsequent parsing. This allows for setting sub-command specific Params, sub-command specific runtime behavior (via mrun.WithStartHook), support for sub-sub-commands, and more. The callback may be nil.
If any sub-commands have been defined on a Component which is passed into Parse, it is assumed that a sub-command is required on the command-line.
When parsing the command-line options, it is assumed that sub-commands will be found before any other options.
This function panics if not called on a root Component (i.e. a Component which has no parents).
Example ¶
var ( cmp *mcmp.Component foo, bar, baz *int aFlag, bFlag *bool ) // resetExample re-initializes all variables used in this example. We'll // call it multiple times to show different behaviors depending on what // arguments are passed in. resetExample := func() { // Create a new Component with a parameter "foo", which can be used across // all sub-commands. cmp = new(mcmp.Component) foo = Int(cmp, "foo") // Create a sub-command "a", which has a parameter "bar" specific to it. aFlag = CLISubCommand(cmp, "a", "Description of a.", func(cmp *mcmp.Component) { bar = Int(cmp, "bar") }) // Create a sub-command "b", which has a parameter "baz" specific to it. bFlag = CLISubCommand(cmp, "b", "Description of b.", func(cmp *mcmp.Component) { baz = Int(cmp, "baz") }) } // Use Populate with manually generated CLI arguments, calling the "a" // sub-command. resetExample() args := []string{"a", "--foo=1", "--bar=2"} if err := Populate(cmp, &SourceCLI{Args: args}); err != nil { panic(err) } fmt.Printf("foo:%d bar:%d aFlag:%v bFlag:%v\n", *foo, *bar, *aFlag, *bFlag) // reset for another Populate, this time calling the "b" sub-command. resetExample() args = []string{"b", "--foo=1", "--baz=3"} if err := Populate(cmp, &SourceCLI{Args: args}); err != nil { panic(err) } fmt.Printf("foo:%d baz:%d aFlag:%v bFlag:%v\n", *foo, *baz, *aFlag, *bFlag)
Output: foo:1 bar:2 aFlag:true bFlag:false foo:1 baz:3 aFlag:false bFlag:true
func CLITail ¶
CLITail modifies the behavior of SourceCLI's Parse. Normally when SourceCLI encounters an unexpected Arg it will immediately return an error. This function modifies the Component to indicate to Parse that the unexpected Arg, and all subsequent Args (i.e. the tail), should be set to the returned []string value.
The descr (optional) will be appended to the "Usage" line which is printed with the help document when "-h" is passed in.
This function panics if not called on a root Component (i.e. a Component which has no parents).
Example ¶
cmp := new(mcmp.Component) foo := Int(cmp, "foo", ParamDefault(1), ParamUsage("Description of foo.")) tail := CLITail(cmp, "[arg...]") bar := String(cmp, "bar", ParamDefault("defaultVal"), ParamUsage("Description of bar.")) err := Populate(cmp, &SourceCLI{ Args: []string{"--foo=100", "arg1", "arg2", "arg3"}, }) fmt.Printf("err:%v foo:%v bar:%v tail:%#v\n", err, *foo, *bar, *tail)
Output: err:<nil> foo:100 bar:defaultVal tail:[]string{"arg1", "arg2", "arg3"}
func Duration ¶
Duration returns an *mtime.Duration which will be populated once Populate is run on the Component.
func Float64 ¶
func Float64(cmp *mcmp.Component, name string, opts ...ParamOption) *float64
Float64 returns a *float64 which will be populated once Populate is run on the Component
func Int ¶
func Int(cmp *mcmp.Component, name string, opts ...ParamOption) *int
Int returns an *int which will be populated once Populate is run on the Component.
func Int64 ¶
func Int64(cmp *mcmp.Component, name string, opts ...ParamOption) *int64
Int64 returns an *int64 which will be populated once Populate is run on the Component.
func JSON ¶
func JSON(cmp *mcmp.Component, name string, into interface{}, opts ...ParamOption)
JSON reads the parameter value as a JSON value and unmarshals it into the given interface{} (which should be a pointer) once Populate is run on the Component.
The receiver (into) is also used to determine the default value. ParamDefault should not be used as one of the opts.
func Populate ¶
Populate uses the Source to populate the values of all Params which were added to the given Component, and all of its children. Populate may be called multiple times with the same Component, each time will only affect the values of the Params which were provided by the respective Source.
Source may be nil to indicate that no configuration is provided. Only default values will be used, and if any parameters are required this will error.
Populating Params can affect the Component itself, for example in the case of sub-commands.
Types ¶
type Param ¶
type Param struct { // How the parameter will be identified within a Component. Name string // A helpful description of how a parameter is expected to be used. Usage string // If the parameter's value is expected to be read as a go string. This is // used for configuration sources like CLI which will automatically add // double-quotes around the value if they aren't already there. IsString bool // If the parameter's value is expected to be a boolean. This is used for // configuration sources like CLI which treat boolean parameters (aka flags) // differently. IsBool bool // If true then the parameter _must_ be set by at least one Source. Required bool // The pointer/interface into which the configuration value will be // json.Unmarshal'd. The value being pointed to also determines the default // value of the parameter. Into interface{} // The Component this Param was added to. NOTE that this will be // automatically filled in by AddParam when the Param is added to the // Component. Component *mcmp.Component }
Param is a configuration parameter which can be populated by Populate. The Param will exist as part of a Component. For example, a Param with name "addr" under a Component with path of []string{"foo","bar"} will be setable on the CLI via "--foo-bar-addr". Other configuration Sources may treat the path/name differently, however.
Param values are always unmarshaled as JSON values into the Into field of the Param, regardless of the actual Source.
func CollectParams ¶
CollectParams gathers all Params by recursively retrieving them from the given Component and its children. Returned Params are sorted according to their Path and Name.
type ParamOption ¶
type ParamOption func(*Param)
ParamOption is a modifier which can be passed into most Param-generating functions (e.g. String, Int, etc...)
func ParamDefault ¶
func ParamDefault(value interface{}) ParamOption
ParamDefault returns a ParamOption which ensures the parameter uses the given default value when no Sources set a value for it. If not given then mcfg will use the zero value of the Param's type as the default value.
If ParamRequired is given then this does nothing.
func ParamDefaultOrRequired ¶
func ParamDefaultOrRequired(value interface{}) ParamOption
ParamDefaultOrRequired returns a ParamOption whose behavior depends on the given value. If the given value is the zero value for its type, then this returns ParamRequired(), otherwise this returns ParamDefault(value).
func ParamRequired ¶
func ParamRequired() ParamOption
ParamRequired returns a ParamOption which ensures the parameter is required to be set by some configuration source. The default value of the parameter will be ignored.
func ParamUsage ¶
func ParamUsage(usage string) ParamOption
ParamUsage returns a ParamOption which sets the usage string on the Param. This is used in some Sources, like SourceCLI, when displaying information about available parameters.
type ParamValue ¶
type ParamValue struct { Name string Path []string Value json.RawMessage }
ParamValue describes a value for a parameter which has been parsed by a Source.
type ParamValues ¶
type ParamValues []ParamValue
ParamValues is simply a slice of ParamValue elements, which implements Parse by always returning itself as-is.
func (ParamValues) Parse ¶
func (pvs ParamValues) Parse(*mcmp.Component) ([]ParamValue, error)
Parse implements the method for the Source interface.
type Source ¶
type Source interface {
Parse(*mcmp.Component) ([]ParamValue, error)
}
Source parses ParamValues out of a particular configuration source, given the Component which the Params were added to (via WithInt, WithString, etc...). CollectParams can be used to retrieve these Params.
It's possible for Parsing to affect the Component itself, for example in the case of sub-commands.
Source should not return ParamValues which were not explicitly set to a value by the configuration source.
The returned []ParamValue may contain duplicates of the same Param's value. in which case the latter value takes precedence. It may also contain ParamValues which do not correspond to any of the passed in Params. These will be ignored in Populate.
type SourceCLI ¶
SourceCLI is a Source which will parse configuration from the CLI.
Possible CLI options are generated by joining a Param's Path and Name with dashes. For example:
cmp := new(mcmp.Component) cmpFoo = cmp.Child("foo") cmpFooBar = foo.Child("bar") addr := mcfg.String(cmpFooBar, "addr", "", "Some address") // the CLI option to fill addr will be "--foo-bar-addr"
If the "-h" option is seen then a help page will be printed to stdout and the process will exit. Since all normally-defined parameters must being with double-dash ("--") they won't ever conflict with the help option.
SourceCLI behaves a little differently with boolean parameters. Setting the value of a boolean parameter directly _must_ be done with an equals, or with no value at all. For example: `--boolean-flag`, `--boolean-flag=1` or `--boolean-flag=false`. Using the space-separated format will not work. If a boolean has no equal-separated value it is assumed to be setting the value to `true`.
type SourceEnv ¶
type SourceEnv struct { // In the format key=value. Defaults to os.Environ() if nil. Env []string // If set then all expected Env options must be prefixed with this string, // which will be uppercased and have dashes replaced with underscores like // all the other parts of the option names. Prefix string }
SourceEnv is a Source which will parse configuration from the process environment.
Possible Env options are generated by joining a Param's Path and Name with underscores and making all characters uppercase, as well as changing all dashes to underscores.
cmp := new(mcmp.Component) cmpFoo := cmp.Child("foo") cmpFooBar := cmp.Child("bar") addr := mcfg.String(cmpFooBar, "srv-addr", "", "Some address") // the Env option to fill addr will be "FOO_BAR_SRV_ADDR"