Documentation ¶
Overview ¶
Package proteus is a package for defining the configuration of an Go application in a struct and loading it from different sources. Application can also opt-in to getting updates when the configuration changes.
Example ¶
package main import ( "fmt" "os" "github.com/simplesurance/proteus" ) func main() { params := struct { Server string Port uint16 `param:",optional"` }{ Port: 5432, } parsed, err := proteus.MustParse(¶ms) if err != nil { parsed.WriteError(os.Stderr, err) os.Exit(1) } fmt.Printf("Server: %s:%d\n", params.Server, params.Port) }
Output:
Example (ParamSet) ¶
package main import ( "fmt" "os" "github.com/simplesurance/proteus" ) func main() { params := struct { HTTP httpParams DB dbParams }{} parsed, err := proteus.MustParse(¶ms) if err != nil { parsed.WriteError(os.Stderr, err) os.Exit(1) } connectDB(params.DB) startHTTP(params.HTTP) } type httpParams struct { BindPort uint16 `param:"bind_port"` Password string `param:"pwd,secret"` } type dbParams struct { Server string Username string `param:"user"` Password string `param:"pwd,secret"` Database string } func connectDB(dbP dbParams) { fmt.Printf("Connecting to DB server %s (db=%q, user=%q)", dbP.Server, dbP.Database, dbP.Username) } func startHTTP(httpP httpParams) { fmt.Printf("Starting HTTP server on :%d\n", httpP.BindPort) }
Output:
Example (TagsAndDefaults) ¶
package main import ( "fmt" "os" "github.com/simplesurance/proteus" ) func main() { params := struct { Enabled bool `param:"is_enabled,optional" param_desc:"Allows enabling or disabling the HTTP server"` Port uint16 `param:",optional" param_desc:"Port to bind for the HTTP server"` Token string `param:",secret" param_desc:"Client authentication token"` }{ Enabled: true, Port: 8080, } parsed, err := proteus.MustParse(¶ms) if err != nil { parsed.WriteError(os.Stderr, err) os.Exit(1) } if params.Enabled { fmt.Printf("Starting HTTP server on :%d\n", params.Port) } }
Output:
Example (Xtypes) ¶
package main import ( "fmt" "os" "github.com/simplesurance/proteus" "github.com/simplesurance/proteus/xtypes" ) func main() { params := struct { BindPort uint16 PrivKey *xtypes.RSAPrivateKey RequestLog *xtypes.OneOf }{ RequestLog: &xtypes.OneOf{ Choices: []string{"none", "basic", "full"}, UpdateFn: func(s string) { fmt.Printf("Log level changed to %s", s) }, }, } parsed, err := proteus.MustParse(¶ms) if err != nil { parsed.WriteError(os.Stderr, err) os.Exit(1) } fmt.Printf("Starting HTTP server on :%d with an RSA key of size %d, log level %s\n", params.BindPort, params.PrivKey.Value().Size(), params.RequestLog.Value()) }
Output:
Index ¶
- type Option
- func WithAutoUsage(writer io.Writer, exitFn func()) Option
- func WithLogger(l plog.Logger) Option
- func WithPrintfLogger(logFn func(format string, v ...any)) Option
- func WithProviders(s ...sources.Provider) Option
- func WithShortDescription(oneline string) Option
- func WithValueFormatting(o ValueFormattingOptions) Option
- func WithVersion(version string) Option
- type Parsed
- type ValueFormattingOptions
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Option ¶
type Option func(*settings)
Option specifes options when creating a configuration parser.
func WithAutoUsage ¶
WithAutoUsage will change how the --help parameter is parsed, allowing to specify a writer, for the usage information and an "exit function". If not specified, proteus will use stdout for writer and will use os.Exit(0) as exit function.
func WithLogger ¶
WithLogger provides a custom logger. By default logs are suppressed.
Warning: the "Logger" interface is expected to change in the stable release.
func WithPrintfLogger ¶ added in v0.0.3
WithPrintfLogger use the printf-style logFn function as logger.
func WithProviders ¶ added in v0.0.2
WithProviders specifies from where the configuration should be read. If not specified, proteus will use the equivalent to:
WithEnv(cfgflags.New(), cfgenv.New("CFG"))
Providing this option override any previous configuration for providers.
func WithShortDescription ¶ added in v0.0.2
WithShortDescription species a short one-line description for the application. Is used when generating help information.
func WithValueFormatting ¶ added in v0.0.4
func WithValueFormatting(o ValueFormattingOptions) Option
WithValueFormatting specifies options for pre-processing values before using them. See ValueFormattingOptions for more details.
func WithVersion ¶ added in v0.0.6
type Parsed ¶
type Parsed struct {
// contains filtered or unexported fields
}
Parsed holds information about all parameters supported by the application, and their options, allowing interacting with them.
func MustParse ¶
MustParse receives on "config" a pointer to a struct that defines the expected application parameters and loads the parameters values into it. An example of a configuration is struct is as follows:
params := struct{ Name string // simple parameter IsEnabled bool `param:"is_enabled"` // rename parameter Password string `param:"pwd,secret"` // rename and mark parameter as secret Port uint16 `param:",optional"` // keep the name, mark as optional LogLevel string `param_desc:"Cut-off level for logs"` // describes the parameter X string `param:"-"` // ignore this field }{ Port: 8080, // default value for optional parameter }
The tag "param" has the format "name[,option]*", where name is either empty, "-" or a lowercase arbitrary string containing a-z, 0-9, _ or -, starting with a-z and terminating not with - or _. The value "-" for the name result in the field being ignored. The empty string value indicates to infer the parameter name from the struct name. The inferred parameter name is the struct name in lowercase. Option can be either "secret" or "optional". An option can be provided without providing the name of the parameter by using an empty value for the name, resulting in the "param" tag starting with ",".
The tag "param_desc" is an arbitrary string describing what the parameter is for. This will be shown to the user when usage information is requested.
The provided struct can have any level of embedded structs. Embedded structs are handled as if they were "flat":
type httpParams struct { Server string Port uint16 } parmas := struct{ httpParams LogLevel string }{}
Is the same as:
params := struct { Server string Port uint16 LogLevel string }{}
Configuration structs can also have "xtypes". Xtypes provide support for getting updates when parameter values change and other types-specific optons.
params := struct{ LogLevel *xtypes.OneOf }{ OneOf: &xtypes.OneOf{ Choices: []string{"debug", "info", "error"}, Default: "info", UpdateFn: func(newVal string) { fmt.Printf("new log level: %s\n", newVal) } } }
The "options" parameter provides further customization. The option WithProviders() must be specified to define from what sources the parameters must be read.
The configuration struct can have named sub-structs (in opposition to named, or embedded sub-structs, already mentioned above). The sub-structs can be up to 1 level deep, and can be used to represent "parameter sets". Two parameters can have the same name, as long as they belong to different parameter sets. Example:
params := struct{ Database struct { Host string Username string Password string `param:,secret` } Tracing struct { Host string Username string Password string `param:,secret` } }{}
Complete usage example:
func main() { params := struct { X int }{} parsed, err := proteus.MustParse(¶ms, proteus.WithAutoUsage(os.Stdout, "My Application", func() { os.Exit(0) }), proteus.WithProviders( cfgflags.New(), cfgenv.New("CFG"), )) if err != nil { parsed.ErrUsage(os.Stderr, err) os.Exit(1) } // "parsed" now have the parameter values }
See godoc for more examples.
A Parsed object is guaranteed to be always returned, even in case of error, allowing the creation of useful error messages.
Example ¶
package main import ( "fmt" "os" "github.com/simplesurance/proteus" ) func main() { params := struct { Server string Port uint16 }{} parsed, err := proteus.MustParse(¶ms) if err != nil { parsed.WriteError(os.Stderr, err) os.Exit(1) } fmt.Printf("Server: %s:%d\n", params.Server, params.Port) }
Output:
Example (Providers) ¶
ExampleMustParse_providers changes how and from where proteus reads configuration.
package main import ( "fmt" "os" "github.com/simplesurance/proteus" "github.com/simplesurance/proteus/sources/cfgenv" "github.com/simplesurance/proteus/sources/cfgflags" ) func main() { params := struct { Server string Port uint16 }{} parsed, err := proteus.MustParse(¶ms, proteus.WithProviders( cfgenv.New("CONFIG"), // change env var prefix to CONFIG cfgflags.New())) // flags are used, but priority is to env vars if err != nil { parsed.WriteError(os.Stderr, err) os.Exit(1) } fmt.Printf("Server: %s:%d\n", params.Server, params.Port) }
Output:
Example (TrimSpaces) ¶
ExampleMustParse_trimSpaces instructs proteus to trim values of parameters, removing leading and trailing spaces. This also removes trailing new lines.
package main import ( "fmt" "os" "github.com/simplesurance/proteus" ) func main() { params := struct { Server string Port uint16 }{} parsed, err := proteus.MustParse(¶ms, proteus.WithValueFormatting(proteus.ValueFormattingOptions{ TrimSpace: true, })) if err != nil { parsed.WriteError(os.Stderr, err) os.Exit(1) } fmt.Printf("Server: %s:%d\n", params.Server, params.Port) // Calling with: // // ./app -server "localhost" -port "8080" // // is the same as: // // ./app -server " localhost \n" -port "8080\n" }
Output:
Example (WithTags) ¶
package main import ( "fmt" "os" "github.com/simplesurance/proteus" ) func main() { params := struct { Enabled bool `param:"is_enabled,optional" param_desc:"Allows enabling or disabling the HTTP server"` Port uint16 `param:",optional" param_desc:"Port to bind for the HTTP server"` Token string `param:",secret" param_desc:"Client authentication token"` }{ Enabled: true, Port: 8080, } parsed, err := proteus.MustParse(¶ms) if err != nil { parsed.WriteError(os.Stderr, err) os.Exit(1) } if params.Enabled { fmt.Printf("Starting HTTP server on :%d\n", params.Port) } }
Output:
func (*Parsed) Stop ¶ added in v0.0.2
func (p *Parsed) Stop()
Stop release resources being used. Proteus itself does not use any resource that need to be released, but some providers might.
func (*Parsed) Usage ¶
Usage prints usage and detailed help output to the provided writer.
Example ¶
package main import ( "os" "github.com/simplesurance/proteus" "github.com/simplesurance/proteus/sources/cfgenv" ) func main() { params := struct { Server string `param_desc:"Name of the server to connect"` Port uint16 `param:",optional" param_desc:"Port to conect"` }{ Port: 5432, } parsed, _ := proteus.MustParse(¶ms, proteus.WithProviders(cfgenv.New("TEST"))) parsed.Usage(os.Stdout) }
Output: Usage: proteus.test [-help] -server <string> [-port <uint16>] PARAMETERS - help default=false Prints information about how to use this application - server Name of the server to connect - port default=5432 Port to conect
func (*Parsed) WriteError ¶ added in v0.0.5
WriteError writes the strings representation of err to w. The line is prefixed with "ERROR: " .
Example ¶
package main import ( "os" "github.com/simplesurance/proteus" ) func main() { params := struct { Latitude float64 Longitude float64 }{} parsed, err := proteus.MustParse(¶ms) if err != nil { // "parsed" is never nil; it can be used to parse the error parsed.WriteError(os.Stderr, err) os.Exit(1) } // use parameters }
Output:
type ValueFormattingOptions ¶ added in v0.0.4
type ValueFormattingOptions struct { // TrimSpace instructs proteus to trim leading and trailing spaces from // values of parameters. TrimSpace bool }
ValueFormattingOptions specifies how values of parameters are "trimmed".
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
internal
|
|
Package plog has the types and code used for logs on proteus.
|
Package plog has the types and code used for logs on proteus. |
Package sources defines the interface for configuration source providers.
|
Package sources defines the interface for configuration source providers. |
cfgenv
Package cfgenv is a parameter provider that reads values from environment variables.
|
Package cfgenv is a parameter provider that reads values from environment variables. |
cfgflags
Package cfgflags implements a configuration reader that reads from command-line flags.
|
Package cfgflags implements a configuration reader that reads from command-line flags. |
cfgtest
Package cfgtest is a configuration provider to be used on tests.
|
Package cfgtest is a configuration provider to be used on tests. |
Package types defines types used by proteus and by code using it.
|
Package types defines types used by proteus and by code using it. |
Package xtypes provide additional types that can be used for configuration.
|
Package xtypes provide additional types that can be used for configuration. |