params

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 5, 2019 License: Apache-2.0 Imports: 12 Imported by: 12

README

params - command line parameter library

GoDoc Build Status Go Report Card codecov

This is (yet another) command line parameter library. The main goal for this library is to make it easy to set up and use the command line parameters. The standard Go flags library is quite tedious to use and you find yourself doing the same validation over and over again.

Command line parameters are declared as annotations on structs. Reflection is used to build the set of command line parameters.

Declaring the command line parameters with the defaults are straightforward:

type HTTPConfig struct {
    Endpoint      string `param:"desc=Server endpoint;default=:8080"`
    TLSCertFile   string `param:"desc=TLS cert file;file"`
    TLSKeyFile    string `param:"desc=TLS key file;file"`
    ACMECert      bool   `param:"desc=Let's Encrypt ACME certs;default=false"`
    ACMEHosts     string `param:"desc=ACME host names"`
    ACMESecretDir string `param:"desc=ACME secret dir"`
}

The parameters is named according to the casing and only the public parameters are used. Members that aren't annotated or public won't be used. The above example produces the following parameters:

  • --endpoint
  • --tls-cert-file
  • --tls-key-file
  • --acme-cert
  • --acme-hosts
  • --acme-secret-dir

The following data types are supported. The type is inferred from the type of the struct member.

  • strings (also as a set of options, see example below)
  • integers
  • booleans
  • floats
  • duration
  • files (see the file directive above). The file must exist for a valid parameter.

Nesting structures

Parameter structs can be nested. The parameters inside the struct will be prefixed according to the name of the containing struct. Note that the parameter struct itself doesn't have an annotation.

If you create a new struct that wraps the HTTPConfig struct above like this:

type parameters struct {
    HTTP        httpConfig
    LogType     string        `param:"desc=Log type;options=plain,syslog,fancy,ansi,full;default=plain"`
    MyOtherBool bool          `param:"default=true"`
}

You would get the following list of command line parameters:

  • --log-type
  • --my-other-bool
  • --http-endpoint
  • --http-tls-cert-file
  • --http-tls-key-file
  • --http-acme-cert
  • --http-acme-hosts
  • --http-acme-secret-dir

Parameters can be nested within parameters but don't go overboard. Remember: Someone has to type the parameters at one point and it might be you. It might be tempting to name the parameter struct HTTPConfig but that would result in some odd looking command line parameters so you should spend a few seconds contemplating the naming of member structs and parameters.

Reading the parameters

A single call will read and check the parameters. The error message can be used directly on the console:

var config parameters
if err := params.NewFlag(&config, os.Args[1:]); err == nil {
    fmt.Println(err.Error())
    return
}

Environment variables

Parameters can be specified via environment variables as well. The environment variables are ALL_CAPS and substitutes the dash for underscore. The parameter htt-tls-cert-file would be HTTP_TLS_CERT_FILE. The environment setting overrides any command line parameters that are used.

# This will set the LogType parameter to "plain"
[local ~]$ LOG_TYPE=plan ./my-command

# This will also set the LogType parameter to "plain" since the environment variable overrides
# the parameter
[local ~]$ LOG_TYPE=plan ./my-command --log-type=fancy

You can either read just the environment variables with params.NewEnv or read both environment and command line parameters at the same time with params.NewEnvFlag which is probably the one you are going to use the most:

var config parameters
if err := params.NewEnvFlag(&config, os.Args[1:]); err == nil {
    fmt.Println(err.Error())
    return
}

Parameter files

The third option is to use a configuration file. Each property is camelCased and nested ccording to the same rules so if you want to read the parameters struct above you can use this configuration file:

{
    "logType": "plain",
    "myOtherBool": false,
    "http": {
        "endpoint": "localhost:1234",
        "tlsCertFile": "",
        "tlsKeyFile": "",
        "acmeCert": true,
        "acmeHosts": "some.example.com",
        "acmeSecretDir": "/var/secret"
    }
}

Reading the file takes a reader:


var config parameters
f, err := os.Open("config.json")
if err != nil {
    panic(err.Error())
}
defer f.Close()
if err := params.NewFile(&config, f); err == nil {
    fmt.Println(err.Error())
    return
}

Note that the reader doesn't have to be a file. A reader is a reader so you could just as easily read the configuration from a network stream.

Documentation

Overview

Package params is a package to define configuration parameters for servers.

Parameters are defined as tags on structs. Configuration structs might have structs within structs for parameters.

A limited number of data types are supported: strings (string), integers (int, uint), booleans (bool), duration (time.Duration) and floats (float64)

The tags are set with the keyword "param". The fields must be publicly accessible:

type config struct {
   NameOfApp string `param:"desc=This is the parameter description"`
}

Keywords are separated by semicolons. There is no escaping so defaults can't contain equal or semicolons. The following keywords are supported:

desc      - a description
default   - the default value for the parameter
min       - minimum value for parameter. Flag must be int, uint, float or Duration
max       - maximum value for parameter. Flag must be int, uint, float or Duration
file      - if present the flag points to a file and that file must exist. Flag must be a string.
required  - if present the flag must be specfified in a valid config
options   - a list of options. Type must be string. Options are case insensitive.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewEnv

func NewEnv(config interface{}) error

NewEnv populates a configuration with values from environment variables.

func NewEnvFlag

func NewEnvFlag(config interface{}, args []string) error

NewEnvFlag returns a struct populated with settings from environment variables and command line arguments. The command line arguments overrides the environment variables.

func NewFile

func NewFile(config interface{}, reader io.Reader) error

NewFile populates a config struct with values from a config file

func NewFlag

func NewFlag(config interface{}, args []string) error

NewFlag parses the command line parameters. This uses the flag package internally. Flag names are derived from the names in the configuration structures If you have structs within structs the names are prefixed with the name of the structure containing the fields:

type serverConfig struct {
    HTTP httpConfig  // These parameters will be prefixed with http-
    HostName string  // This parameter will be named host-name
}

type httpConfig struct {
    Endpoint string  // This parameter will be named http-endpoint
    TLS      bool    // This parameter will be named http-tls
}

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL