Socket
Socket
Sign inDemoInstall

github.com/PhiloInc/go-config

Package Overview
Dependencies
0
Alerts
File Explorer

Install Socket

Detect and block malicious and high-risk dependencies

Install

    github.com/PhiloInc/go-config

Package config provides types and functions for managing application configuration. A set of command-line flags or environment variables to parse can be inferred from a struct's type. The values are then subject to validation and assigned to the struct fields. The easiest way to use the package is to define a struct type and pass it to Configure. Struct tags can be used to control how fields are scanned or validated. If the program was given the -h flag, the following help would be written to stderr: Running the program with no command line flags and none of the environment variables set would output: Note that the entire Auth field is left as nil; nil pointers are only set if a value is configured for the field. Running the program again with flags provides the following: Finally, some of the values have validation tags for their struct fields. If the validations are not met, an error is given: The following types are supported by the package: In addition, any types derived from pointers and slices to those types are also supported. bool, float, int and uint values are parsed by strconv.ParseBool, strconv.ParseFloat, strconv.ParseInt and strconv.ParseUint. Trying to set a value that would overflow the type results in an error. net.IP values are parsed using net.ParseIP. net.IPNet values are parsed using net.ParseCIDR. url.URL values are parsed using url.Parse. time.Duration values are parsed using time.ParseDuration. time.Time values will be parsed using the following layouts until one is succesful or all have been tried: Additional types can be supported either by implementing the Setter API on that type, or by implementing and registering a SetterCreator for that type. The latter option will enable the package to automatically wrap derived pointer and struct types. Struct tags can be used to impose validation on parsed values. `min:"x"` or `ge:"x"` sets a minimum value for int, float, uint, time.Duration and time.Time values. The value must be appropriate for the type, and is parsed the same as values of that type. For example indicates that the Timeout value must be greater than or equal to 30 seconds. `max:"x"“ or `le:"x"` indicates a maximum value for the above types. Similarly, `gt:"x"` or `lt:"x"` will require values greater than or less than the values specified. Values can be combined to set ranges. Note, however, that it's possible to set impossible validations this way, e.g., `gt:"10" lt:"5"`. `regexp:"x"` sets a regular expression for validating string values. A match can occur anywhere in the string. To match the whole string, anchor the expression with "^$". Also note that the value in the struct tag will be subject to string unquoting; backslashes and double-quotes must be escaped with a backslash. `scheme:"x"`, `host:"x"` or `path:"x"` tags can be applied to url.URL values. They specify regular expressions that are used to validate the corresponding parts of the URL. The `is:"x"` tag can be used to specify required or disallowed classes of IP addresses for the net.IP or net.IPNet types. Valid values are: The class name can be prefixed with an exclamation point to indicate that the class is disallowed. Multiple values can be combined by separating with commas. For example, `is:"!loopback,!link local unicast"` would allow addresses that are neither loopback nor link local unicast. If any disallowed class is matched, the validation will fail. The allowed classes are matched in an "or" fashion, however, and any one match will cause the validation to succeed. The `net:"x"` tag can be used with net.IP or net.IPNet values to specify required or disallowed networks. Networks are specified in address/bits form, e.g., 169.254.0.0/16 or 2001:cdba:9abc:5678::/64. Disallowed networks are specified by prefixing with an exclamation point. Multiple values can be combined by separating with commas. The semantics are the same as for the 'is' tag: A match for any disallowed value fails validation; a match for any single allowed value causes validation to succeed. The `version:"4"` or `version:"6"` tags can be used with net.IP and net.IPNet values to specify that the value must be an IPv4 or IPv6 address. `config:"X"` can be used to override the name of a struct field, instead of using the reflected name. The name will still be subjected to parsing with SplitName. Setting `config:"-"` will cause the struct field to be skipped, i.e., it will not be scanned or configured. `prefix:"X"` can be used to override how nested structs are handled. If no prefix is set, the child struct uses the name of its field in the parent struct. If a name is given, that name will be used to group settings in the child struct. (`config:"X"` can be used for the same purpose.) If `prefix:"-"` is given, the child struct will use the same prefix as its parent, and names parsed from the child's fields will be added to the parent's level as if the fields had been parsed from the parent. For example: will result in command line flags being generated for -timeout, -user and -pass. Without the prefix tag, the names would have been -auth-user and -auth-pass. `from:"X"` will cause the value to only be configured by the named loaders. For example will only let the Interactive value be set from a command line flag. `append:"false"` or `append:"true"` (the default) can be used with slice types. When true, values are appended to existing values in a slice. When false, setting a new value will cause the slice to be overwritten. (Setting multiple values will still result in second and subsequent values being appended after the first new value). `sep:"X" can be used with slice types. It indicates a string on which the value should be split on in order to populate a slice.


Version published

Readme

Source

go-config

A Configuration Package for Go

Summary

go-config provides a convenient way to scan configuration settings from command line flags and environment variables into structs. Its aim is to provide logical organization of configuration parameters with minimal developer overhead.

It also provides for basic validation of configuration values by using struct tags, and parsing of single values.

Quick Start

type Auth struct {
    User     string
    Password string
}

type Options struct {
    Auth    *Auth
    URLs    []*url.URL `scheme:"^(http|https)$"`
    Verbose int        `min:"0" max:"8"`
}

opts := Options{Verbose: 1}
if err := config.Configure(&opts); err != nil {
    fmt.Fprintln(os.Stderr, err)
    os.Exit(1)
}
if opts.Auth != nil {
    fmt.Printf("Auth: %+v\n", *opts.Auth)
}
fmt.Printf("URLs: %s\nVerbose: %d\n", opts.URLs, opts.Verbose)

Running the program with -h demonstrates the generated command-line flags and environment variable settings:

Command Line Flags:
  -auth-password string
  -auth-user string
  -urls url
  -verbose int
         (default 1)

Environment Variables:
  AUTH_PASSWORD=string
  AUTH_USER=string
  URLS=url
  VERBOSE=int
         (default 1)

Help requested

Running the program with supported flags demonstrates how values are set:

prog -urls http://www.google.com/ -urls http://www.yahoo.com/ -auth-user user1
Auth: {User:user1 Password:}
URLs: [http://www.google.com/ http://www.yahoo.com/]
Verbose: 1

To set a default value, simply set the value in the struct before calling Configure. Struct tags can be used to specify permitted values. See the Validation section for details.

Detailed Usage

Supported Types

The following types are supported:

  • int
  • int8
  • int16
  • int32
  • int64
  • uint
  • uint8
  • uint16
  • uint32
  • uint64
  • float32
  • float64
  • string
  • bool
  • net.IP
  • net.IPNet
  • url.URL
  • time.Duration
  • time.Time
Pointers and Slices

Types that are pointer and/or slice types of a supported type are also supported. For example, []int, *int, *[]*int, or any other combination of slice and pointer indirection can be set.

Numeric types

int, int8, int16, int32, and int64, uint, uint8, uint16, uint32 and uint64 types are parsed as base 10, unless they have a leading zero or 0x, in which case they are parsed as, respectively, base 8 or base 16 values. Values which would overflow the type or discard a sign are considered invalid. For example, assigning a value larger than 255 to int8, or assigning a negative value to a uint.

float32 and float64 types are parsed using strconv.ParseFloat using the correct size (bits).

Booleans

bool values are parsed using strconv.ParseBool. 1, t, T, TRUE, true, and True are parsed as true. 0, f, F, FALSE, false, and False evaluate to false. Any other value is an error.

URLs

url.URL values are parsed using url.Parse.

IP Addresses

net.IP values are are parsed with net.ParseIP and accept, e.g., 192.168.1.1 or 2600:1700:5fa0:ef90:85e:79dc:5ea7:c711. net.IPNet values are parsed with net.ParseCIDR as address/bits, such as 169.254.0.0/16 or 2001:cdba:9abc:5678::/64. A value provided as a network address need not necessarily specify the 0 network address: 169.254.1.1/16 will be understood as 169.254.0.0/16.

Durations

time.Duration values are parsed using time.ParseDuration, e.g., 0.75s or 1h37m27s.

Times

A best effort is made to parse a time based on a static list of layouts:

  • "2006-01-02T15:04:05Z07:00"
  • "2006-01-02 15:04:05Z07:00"
  • "2006-01-02T15:04:05"
  • "2006-01-02 15:04:05"
  • "2006-01-02T15:04Z07:00"
  • "2006-01-02 15:04Z07:00"
  • "2006-01-02T15:04"
  • "2006-01-02 15:04"
  • "2006-01-02T15"
  • "2006-01-02 15"
  • "2006-01-02"
  • "2006-01"

If the time can not be parsed using any of the given layouts, it is an error.

Flag and Environment Variable Names

go-config attempts to generate human-friendly names by parsing the names of struct fields in a hierarchical way. For example, given

type UserAccount struct {
    Network struct {
        IPv6FriendlyName string
    }
}

go-config will generate the command line flag -user-account-network-ip-v6-friendly-name. See the section Overriding Names for details on how to change this behavior.

Validation

Note than for types in the below section, the validations also apply to other types that are pointer and/or slice types of the base type. For example, if a validation applies to int, it also applies to []int, *int, *[]*int, or any other combination of slice and pointer indirection.

Greater or Less Than Comparisons

Number types int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64 as well as time.Duration and time.Time support a number of struct tags for validation.

ge and min have the same meaning, and indicate a value must be greater than or equal to the argument. le and max similarly indicate a value must be less than or equal to a given value. Tags lt and gt indicate a strict less than or greater than comparison (not equal to).

All arguments to the above tags should be given in a valid string for the type. For example, 1s for a duration, 2001-01-01 11:59:59Z for a time, etc. The special value now may be used for time.Time values.

The above tags can be combined to require values within a range.

Examples:

type Example struct {
    Ratio   float64       `min:"0" lt:"1"`
    Timeout time.Duration `min:"0s"`
}
Regular Expressions

Fields of string type support the regexp tag. Only values that match the given regular expression will be accepted.

Similarly, url.URL fields support scheme, host and path struct tags to require that the URL scheme, host or path, respectively, match the given regular expression.

Go's regular expression matching will match any part of a string. To match the entire string, anchor the expression with ^ and $.

Struct tag values use quoted strings. This means that double quotes and backslahes must be backslash-escaped.

Examples:

type Example struct {
    BaseURL  *url.URL `scheme:"^(http|https)$"`
    Username string   `regexp:"^\\pL"` // usernames must start with a letter.
}
IP Addresses

net.IP and net.IPNet types support tags to validate a particular address.

is

The is tag can be used with values global unicast, interface local multicast, link local multicast, link local unicast, loopback, multicast, and unspecified. Each value matches the corresponding range of IP addresses. A negative match can be specified by prefixing with a !, and multiple values can be separated by commas. Validation succeeds if any non-negated term matches the value being set. Validation fails, however, if any negated term is matched.

Example:

type Example struct {
    IP net.IP `is:"multicast,!interface local multicast"`
}

The above field will accept a multicast address, but not if it is an interface local multicast.

net

The net tag can be used to specify restrictions for which networks an IP address can be part of. Network addresses are specified in address/bits notation, e.g., 169.254.0.0/16 or 2001:cdba:9abc:5678::/64. As with the net tag, a ! negates the match term, and multiple terms can be seprated by commas. Validation succeeds if any non-negated term matches, and fails if any negated term is matched.

Example:

type Example struct {
    IP net.IP `net:"192.168.0.0/16,!192.168.254.0/24"`
}
version

The version tag accepts values 4 or 6 to indicate that an address must be an IPv4 or IPv6 address.

Controlling Where Values are Loaded From

By default, values are parsed first from environment variables and then from command line flags. If a value is set by both an environment variable and a command line flag, the command line flag will overwrite the value set from the environment variable.

The from struct tag can be used to control where values are loaded from. The default is from:"flag,env". To prevent a field from being set from an environment variable, one could use from:"flag" in its struct tag.

The default loaders can also be overridden, either to change the order or to exclude defaults. For example, to cause environment variables to overwrite command line flags:

loaders := config.Loaders{new(config.FlagLoader), new(config.EnvLoader)}
config.DefaultConfig.SetLoaders(loaders)

Scanning Multiple Structs or Setting Individual Values

The Configuration function is convenient for scanning values from a single struct and then loading them. However, functions are also provided for loading values into more than one struct, or for setting individual variables. The functions Scan, Var and Load are available.

To scan more than one struct, simply call Scan for each struct. Call Var to add an individual variable. When finished, call Load to parse and set values from the command line and/or environment.

Note, however, that name collisions will cause a panic.

Using Non-global Configurations

For some cases, it may be desirable to avoid using the package global DefaultConfig. In order to support standalone or multiple configurations, simply use the config.Config type. The zero value is ready to use.

Overriding Names

The config struct tag can be used to skip fields or change the names that are generated for them. config:"-" will cause a field to be skipped. config:"OtherName" will cause go-config to use OtherName as the name for this field, which will be used in generating command line flag and environment variable names.

Using prefix:"-" will cause a child struct to use the same prefix as the parent struct. For example:

type Auth struct {
    User     string
    Password string
}

type Options struct {
    Auth    *Auth      `prefix:"-"`
    URLs    []*url.URL `scheme:"^(http|https)$"`
    Verbose int        `min:"0" max:"8"`
}

In this case, the command line flag for the User field will be simply -user, instead of -auth-user.

For even more control of naming, a struct can be passed to the Var function. See the documentation of that function for details.

Dependencies

Supports Go >= 1.10. go-config does not currently rely on any external packages.

License

go-config uses the MIT License.

Contributing

Pull requests and bug requests are welcome.

Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.

FAQs

Last updated on 27 Mar 2019

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc