Documentation ¶
Overview ¶
Package gofigure allows for configuration of an application using command line flags, environment variables and configuration files.
Example ¶
package main import ( "fmt" "time" "bitbucket.org/idomdavis/gofigure" ) func main() { var settings struct { Mode int Name string Address string Timeout time.Duration TLS bool Duration time.Duration Int int Float float64 } config := gofigure.NewConfiguration("EXAMPLE") config.AddHelp(gofigure.CommandLine) config.AddConfigFile(gofigure.CommandLine) group := config.Group("settings") group.Add(gofigure.Required("App Name", "name", &settings.Name, gofigure.AllSources, gofigure.ReportValue, "Application name")) group.Add(gofigure.Required("Mode", "mode", &settings.Mode, gofigure.Flag, gofigure.ReportValue, "Mode indicator")) group.Add(gofigure.Optional("IP Address", "address", &settings.Address, "", gofigure.AllSources, gofigure.MaskUnset, "Remote server address")) group.Add(gofigure.Optional("Timeout", "timeout", &settings.Timeout, time.Minute, gofigure.AllSources, gofigure.ReportValue, "Remote server address")) group.Add(gofigure.Optional("TLS", "tls", &settings.TLS, false, gofigure.NamedSources, gofigure.ReportValue, "Use TLS")) types := config.Group("JSON types") types.Add(gofigure.Required("Duration", "duration", &settings.Duration, gofigure.Key, gofigure.ReportValue, "Duration type")) types.Add(gofigure.Required("Int", "int", &settings.Int, gofigure.Key, gofigure.ReportValue, "int type")) types.Add(gofigure.Required("Float", "float", &settings.Float, gofigure.Key, gofigure.ReportValue, "float type")) // Ordinarily this would be config.Parse(). err := config.ParseUsing([]string{ "-c", "testdata/config.json", "--mode", "3", "--name", "example", "-h", }) if err != nil { fmt.Println(config.Format(err)) fmt.Println(config.Usage()) } fmt.Printf("%v\n\n", settings) if config.Help { fmt.Println(config.Usage()) } }
Output: {3 example localhost:8000 1m0s false 1h0m0s 0 0} usage: Help [-h, --help] Display usage information Config File [-c, --config] Provide configuration from an external JSON file App Name [JSON key: "name", env EXAMPLE_NAME, -n, --name] Application name (required) Mode [--mode] Mode indicator (required) IP Address [JSON key: "address", env EXAMPLE_ADDRESS, -a, --address] Remote server address Timeout [JSON key: "timeout", env EXAMPLE_TIMEOUT, -t, --timeout] Remote server address (default: 1m0s) TLS [JSON key: "tls", env EXAMPLE_TLS, --tls] Use TLS (default: false) Duration [JSON key: "duration"] Duration type (required) Int [JSON key: "int"] int type (required) Float [JSON key: "float"] float type (required)
Index ¶
- Constants
- Variables
- func Assign[T Type](target *T, value any) (err error)
- func Build() string
- func Cast(value, typeOf any) any
- func Coerce(value, typeOf any) (r any, err error)
- func Dereference(in any) any
- func Get(uri string) (map[string]any, error)
- type ConfigError
- type Configuration
- func (c *Configuration) AddConfigFile(sources Source)
- func (c *Configuration) AddHelp(sources Source)
- func (c *Configuration) Format(err error) string
- func (c *Configuration) Group(name string) *Group
- func (c *Configuration) Parse() error
- func (c *Configuration) ParseUsing(args []string) error
- func (c *Configuration) Report() Report
- func (c *Configuration) Usage() string
- type External
- type Group
- type Line
- type Mask
- type Options
- type Parameter
- type Parameters
- type Report
- type Setting
- type Settings
- type Source
- type Type
- type Value
Examples ¶
Constants ¶
const ( // HideSet will not report the value if it's set. HideSet = Mask(1 << iota) // HideUnset will not report anything if the value is not set. HideUnset = Mask(1 << iota) // MaskSet will report Set rather than the definition value. MaskSet = Mask(1 << iota) // MaskUnset will report Unset rather than the definition value. MaskUnset = Mask(1 << iota) // DefaultIsSet sets the behaviour of Mask to treat a default value as // Set rather than NotSet. DefaultIsSet = Mask(1 << iota) // ReportValue will report the definition value. ReportValue = 0 // HideValue will not report anything for the definition. HideValue = HideSet | HideUnset // MaskValue will report Set or Unset rather than the definition value. MaskValue = MaskSet | MaskUnset )
const ( // Set is used when MaskSet is specified. Set = "SET" // NotSet is used when MaskNotSet is specified. NotSet = "UNSET" // Invalid is used when a Value is invalid. Invalid = "INVALID" )
const ( // None indicates no source has set the Value. None = Source(1 << iota) // A Default Value has been used. No other sources have overwritten this. Default = Source(1 << iota) // A Key in a JSON file. Can be used either to indicate the Value can be set // via this Key, or has been set via this Key. Key = Source(1 << iota) // An EnvVar or environment variable. Can be used either to indicate the // Value can be set via this environment variable, or that it has been set // via this environment variable. EnvVar = Source(1 << iota) // A ShortFlag on the command line. Can be used either to indicate the // Value can be set via this flag, or that it has been set via this flag. ShortFlag = Source(1 << iota) // A Flag on the command line. Can be used either to indicate the // Value can be set via this flag, or that it has been set via this flag. Flag = Source(1 << iota) // Reference parameter that cannot be set. Reference parameters are used to // provide output in a report without being settable beyond the default // value. By definition Reference parameters must be Optional. Reference = Source(1 << iota) )
const ( // CommandLine indicates an option can come from a short or long flag. CommandLine = Flag | ShortFlag // NamedSources indicates an option should be set from a flag, environment // variable, or JSON key. NamedSources = Flag | EnvVar | Key // AllSources indicates an option should be set from a short flag, flag, // environment variable, or JSON key. AllSources = NamedSources | ShortFlag )
const Dev = "dev"
Dev identifier, used as a default when the Identifier is unset and cannot be inferred.
const Unset = "<unset>"
Unset is used when version data is unset and cannot be inferred.
Variables ¶
var ( Identifier = Dev BuildTime = Unset CommitHash = Unset )
Build identifiers. These are given sensible defaults, but can be overridden when an application is compiled using -ldflags. Within a Makefile this may look like:
PACKAGE = bitbucket.org/idomdavis/gofigure BUILD_TIME = $(shell date +"%Y/%m/%d-%H:%M:%S") HASH = $(shell git rev-parse HEAD) ifdef BITBUCKET_TAG TAG = $(BITBUCKET_TAG) else ifdef BITBUCKET_BRANCH TAG = $(BITBUCKET_BRANCH) else TAG = $(shell git rev-parse --abbrev-ref HEAD) endif ifeq (, $(TAG)) TAG = dev endif LDFLAGS = -X $(PACKAGE).BuildTime=$(BUILD_TIME) \ -X $(PACKAGE).CommitHash=$(HASH) \ -X $(PACKAGE).Identifier=$(TAG) build: go build -ldflags "$(LDFLAGS)"
The identifiers are used for reference only and have no impact on the operation of gofigure.
var ( ErrMissingName = errors.New("value for Value.Name is empty") ErrMissingDescription = errors.New("value for Value.Description is empty") ErrNilPointer = errors.New("value for Value.Ptr is nil") ErrInvalidType = errors.New("invalid type") )
Value validation errors.
var ErrInvalidValue = errors.New("invalid value")
ErrInvalidValue is used when an option can't be mapped.
var ErrLoadingConfig = errors.New("error loading config")
ErrLoadingConfig is given to a ConfigError if Load fails.
var ErrLoadingJSON = errors.New("error loading JSON")
ErrLoadingJSON is returned if an external file cannot be read from the path or URL given.
var ErrMissingRequiredOption = errors.New("missing required option")
ErrMissingRequiredOption is returned if a required option has not been set after parsing.
var ErrParsingJSON = errors.New("error parsing JSON")
ErrParsingJSON is returned if the external file is not valid JSON.
var ErrUnexpectedArgument = errors.New("unexpected argument")
ErrUnexpectedArgument is returned if an unexpected argument is passed.
Functions ¶
func Assign ¶
Assign the value to the target, returning an error if assignment fails. Assign will attempt to coerce string values to the correct type.
func Build ¶ added in v0.1.1
func Build() string
Build returns a build string for the application. This relies on the correct ldflags being set.
Example ¶
package main import ( "fmt" "bitbucket.org/idomdavis/gofigure" ) func main() { fmt.Println(gofigure.Build()) }
Output: dev [<unset>] (built: <unset>)
func Cast ¶ added in v0.2.6
Cast a float64 value to an integer value. If the value isn't a float64, or the type isn't an integer then Cast will simply return the value.
Example ¶
package main import ( "fmt" "bitbucket.org/idomdavis/gofigure" ) func main() { fmt.Printf("%T: %[1]v\n", gofigure.Cast(1.0, 0)) fmt.Printf("%T: %[1]v\n", gofigure.Cast(8.0, int8(0))) fmt.Printf("%T: %[1]v\n", gofigure.Cast(16.0, int16(0))) fmt.Printf("%T: %[1]v\n", gofigure.Cast(32.0, int32(0))) fmt.Printf("%T: %[1]v\n", gofigure.Cast(64.0, int64(0))) fmt.Printf("%T: %[1]v\n", gofigure.Cast(1.0, uint(0))) fmt.Printf("%T: %[1]v\n", gofigure.Cast(8.0, uint8(0))) fmt.Printf("%T: %[1]v\n", gofigure.Cast(16.0, uint16(0))) fmt.Printf("%T: %[1]v\n", gofigure.Cast(32.0, uint32(0))) fmt.Printf("%T: %[1]v\n", gofigure.Cast(64.0, uint64(0))) fmt.Printf("%T: %[1]v\n", gofigure.Cast(float32(1.0), float32(0))) fmt.Printf("%T: %[1]v\n", gofigure.Cast(1.0, float64(0))) fmt.Printf("%T: %[1]v\n", gofigure.Cast("1.0", 1)) }
Output: int: 1 int8: 8 int16: 16 int32: 32 int64: 64 uint: 1 uint8: 8 uint16: 16 uint32: 32 uint64: 64 float32: 1 float64: 1 string: 1.0
func Coerce ¶
Coerce will coerce string values to the correct type. All other value types are simply returned as is. If the string value cannot be coerced to the type an error is returned.
Example ¶
package main import ( "fmt" "time" "bitbucket.org/idomdavis/gofigure" ) func main() { fmt.Println(gofigure.Coerce(1, 0)) fmt.Println(gofigure.Coerce("1m0s", time.Nanosecond)) fmt.Println(gofigure.Coerce("true", false)) fmt.Println(gofigure.Coerce("1", 0)) fmt.Println(gofigure.Coerce("8", int8(0))) fmt.Println(gofigure.Coerce("16", int16(0))) fmt.Println(gofigure.Coerce("32", int32(0))) fmt.Println(gofigure.Coerce("64", int64(0))) fmt.Println(gofigure.Coerce("1", uint(0))) fmt.Println(gofigure.Coerce("8", uint8(0))) fmt.Println(gofigure.Coerce("16", uint16(0))) fmt.Println(gofigure.Coerce("32", uint32(0))) fmt.Println(gofigure.Coerce("64", uint64(0))) fmt.Println(gofigure.Coerce("1", float32(0))) fmt.Println(gofigure.Coerce("6.4", float64(0))) fmt.Println(gofigure.Coerce("1", uintptr(0))) }
Output: 1 <nil> 1m0s <nil> true <nil> 1 <nil> 8 <nil> 16 <nil> 32 <nil> 64 <nil> 1 <nil> 8 <nil> 16 <nil> 32 <nil> 64 <nil> 1 <nil> 6.4 <nil> 1 cannot coerce "1": invalid type: uintptr
func Dereference ¶
Dereference a value. If the value isn't a pointer then it is returned as is.
Example ¶
package main import ( "fmt" "bitbucket.org/idomdavis/gofigure" ) func main() { i := 1 fmt.Println(gofigure.Dereference(i)) fmt.Println(gofigure.Dereference(&i)) }
Output: 1 1
Types ¶
type ConfigError ¶
type ConfigError struct { Cause error Internal error Parameters Parameters Value any }
ConfigError holds data about what specifically caused configuration to fail. This can e used to generate a user-friendly report.
func NewConfigError ¶
func NewConfigError(cause, internal error, parameters ...Parameter) ConfigError
NewConfigError will return a new ConfigError for the given errors and Parameters.
func (ConfigError) Error ¶
func (c ConfigError) Error() string
func (ConfigError) Format ¶
func (c ConfigError) Format(prefix string) string
Format the error in a user-centric way.
func (ConfigError) Unwrap ¶
func (c ConfigError) Unwrap() error
type Configuration ¶
type Configuration struct { Help bool Prefix string Groups []*Group // contains filtered or unexported fields }
Configuration for a program.
func NewConfiguration ¶
func NewConfiguration(envPrefix string) *Configuration
NewConfiguration returns a new Configuration set to use the given prefix for environment variables.
func (*Configuration) AddConfigFile ¶ added in v0.2.4
func (c *Configuration) AddConfigFile(sources Source)
AddConfigFile will add a "config" option to the set of options. If ShortFlag is set on the sources then a short flag of 'h' is also added. All other sources are ignored. The provided value will be used as a path or URI to load and external configuration file from.
func (*Configuration) AddHelp ¶
func (c *Configuration) AddHelp(sources Source)
AddHelp will add a "help" flag to the set of options. If ShortFlag is set on the sources then a short flag of 'h' is also added. All other sources are ignored.
func (*Configuration) Format ¶
func (c *Configuration) Format(err error) string
Format an error for user consumption. This will remove most of the technical details and leave a simple message as to why the configuration failed. Format should be used to report any errors to the user.
func (*Configuration) Group ¶
func (c *Configuration) Group(name string) *Group
Group of Definitions for this Configuration.
func (*Configuration) ParseUsing ¶
func (c *Configuration) ParseUsing(args []string) error
ParseUsing uses the given arguments as the set of command line arguments.
func (*Configuration) Report ¶ added in v0.2.0
func (c *Configuration) Report() Report
Report on the configuration, returning the values in a format that can be displayed to the user. Empty groups will be stripped from the Report. Values in the Report will respect the Mask setting.
func (*Configuration) Usage ¶
func (c *Configuration) Usage() string
Usage string for this set of Options.
type Group ¶
Group of Settings.
func (*Group) Values ¶
Values set on this group. Values will strip any Setting with a Mask that indicates it should be hidden.
Example ¶
package main import ( "fmt" "bitbucket.org/idomdavis/gofigure" ) func main() { var a, b string g := gofigure.Group{} g.Add(gofigure.Required("a", "a", &a, gofigure.Flag, gofigure.HideUnset, "a")) g.Add(gofigure.Required("b", "b", &b, gofigure.Flag, gofigure.MaskValue, "b")) fmt.Println(g.Values()) }
Output: map[b:UNSET]
type Mask ¶
type Mask uint8
Mask definition values when they are logged.
type Options ¶
Options use to configure an application.
func Environment ¶
Environment Options defined by the Settings.
func Flags ¶
Flags will build a set of Options from the given argument list.
Example ¶
package main import ( "fmt" "bitbucket.org/idomdavis/gofigure" ) func main() { flags, err := gofigure.Flags([]string{"-v", "--name", "example"}) if err != nil { fmt.Println(err) } fmt.Println(flags) }
Output: [name:example, v:true]
func Load ¶
Load external Options from a URI. The external file can be any JSON object.
Example ¶
package main import ( "fmt" "bitbucket.org/idomdavis/gofigure" ) func main() { d, err := gofigure.Load("testdata/config.json") if err != nil { fmt.Println(err) } fmt.Println(d) }
Output: [address:localhost:8000, duration:1h, float:0, int:0, name:overridden]
type Parameter ¶
Parameter used to set a Value.
func (Parameter) FullName ¶
FullName returns the fully formatted name for the parameter. For most parameter types this is just the name. For Environment variables the prefix is appended if there is one, and all -'s are converted to _'s.
func (Parameter) Matches ¶
Matches returns true if the Argument matches the Parameter.
Example ¶
package main import ( "fmt" "bitbucket.org/idomdavis/gofigure" ) func main() { a := gofigure.Parameter{Name: "param", Source: gofigure.AllSources} b := gofigure.Parameter{Name: "param", Source: gofigure.Flag} c := gofigure.Parameter{Name: "param", Source: gofigure.ShortFlag} fmt.Println(a.Matches(b)) fmt.Println(b.Matches(c)) fmt.Println(b.Matches(a)) fmt.Println(c.Matches(b)) }
Output: true false true false
type Parameters ¶
type Parameters []Parameter
Parameters that can be used to set a Value.
func NewParameters ¶
func NewParameters(name string, sources Source) Parameters
NewParameters returns a set of named parameters for the given sources. Combine multiple sources with | (e.g. Flag | EnvVar). The given name is used for each source with Flag and Key using the name as is, EnvSuffix set to the uppercase version of the name, and ShortFlag set to the first character of name.
Example ¶
package main import ( "fmt" "bitbucket.org/idomdavis/gofigure" ) func main() { fmt.Println(gofigure.NewParameters("param", gofigure.AllSources)) }
Output: [JSON key: "param" env PARAM -p --param]
func (Parameters) Format ¶
func (p Parameters) Format(prefix string) string
Format the given Parameters into a human-readable string.
Example ¶
package main import ( "fmt" "bitbucket.org/idomdavis/gofigure" ) func main() { p := gofigure.NewParameters("param", gofigure.AllSources) fmt.Println(p.Format("STUB")) }
Output: [JSON key: "param", env STUB_PARAM, -p, --param]
type Report ¶ added in v0.2.0
type Report []Line
Report holds the setting configuration in a way that can be reported to the user. Values in the Report will respect Mask settings.
type Setting ¶
type Setting struct { Value *Value Parameters Parameters Mask Mask }
Setting in a Configuration. A Setting takes values from a set of Parameters and applies them to a Value. The Mask is used when generating a Display value.
func Optional ¶
func Optional[T Type](name, param string, ptr *T, value T, sources Source, mask Mask, description string) *Setting
Optional Setting uses the given default value if no value is provided via its parameters. The parameters are constructed using the param value and the defined sources. Combine multiple sources with | (e.g. Flag | EnvVar). The given name is used for each source with Flag and Key using the name as is, EnvSuffix set to the uppercase version of the name, and ShortFlag set to the first character of name.
func Required ¶
func Required[T Type](name, param string, ptr *T, sources Source, mask Mask, description string) *Setting
Required Setting must be set via one of its Parameters. The parameters are constructed using the param value and the defined sources. Combine multiple sources with | (e.g. Flag | EnvVar). The given name is used for each source with Flag and Key using the name as is, EnvSuffix set to the uppercase version of the name, and ShortFlag set to the first character of name.
type Settings ¶
type Settings []*Setting
func (Settings) Apply ¶
Apply the Parameter to the correct Setting in the set. Apply will return an error if the relevant Setting cannot be set, or if no Settings have been set.
type Source ¶
type Source uint8
Source of a Value, either accepted sources (i.e. what sources set a Value), or defining Source that set the Value. Combine multiple sources with | when defining accepted sources (e.g. Flag | EnvVar).
func (Source) Contains ¶
Contains returns true if the Source contains the given Source.
Example ¶
package main import ( "fmt" "bitbucket.org/idomdavis/gofigure" ) func main() { sources := gofigure.Flag | gofigure.ShortFlag fmt.Println(sources.Contains(gofigure.Flag)) fmt.Println(sources.Contains(gofigure.Key)) sources = gofigure.AllSources fmt.Println(sources.Contains(gofigure.Key)) }
Output: true false true
func (Source) String ¶
Example ¶
package main import ( "fmt" "math" "bitbucket.org/idomdavis/gofigure" ) func main() { fmt.Println(gofigure.None) fmt.Println(gofigure.Default) fmt.Println(gofigure.Key) fmt.Println(gofigure.EnvVar) fmt.Println(gofigure.ShortFlag) fmt.Println(gofigure.Flag) fmt.Println(gofigure.Reference) fmt.Println(gofigure.Source(math.MaxUint8)) fmt.Println(gofigure.Source(0)) }
Output: none default value config file key environment variable short flag flag reference value config file source
type Type ¶
type Type interface { ~bool | ~float32 | ~float64 | ~string | ~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 }
Type accepted by gofigure.
type Value ¶
type Value struct { Name string Description string Ptr any Source Source // contains filtered or unexported fields }
A Value is used to hold a configured value. The Value must be a pointer to the variable being set, and must satisfy Type. Once set the Value will contain the Source that provided the value.
func NewValue ¶
NewValue returns a new, valid value. An empty name, description, or an invalid ptr will result in a panic.