conf

package
Version: v0.0.0-...-fdd12d1 Latest Latest
Warning

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

Go to latest
Published: Jan 4, 2020 License: Apache-2.0, MIT Imports: 11 Imported by: 0

README

Package conf provides support for using environmental variables and command line arguments for configuration.

It is compatible with the GNU extensions to the POSIX recommendations for command-line options. See http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html

There are no hard bindings for this package. This package takes a struct value and parses it for both the environment and flags. It supports several tags to customize the flag options.

default  - Provides the default value for the help
env      - Allows for overriding the default variable name.
flag     - Allows for overriding the default flag name.
short    - Denotes a shorthand option for the flag.
noprint  - Denotes to not include the field in any display string.
required - Denotes a value must be provided.
help     - Provides a description for the help.

The field name and any parent struct name will be used for the long form of the command name unless the name is overridden.

As an example, this config struct:

	type ip struct {
		Name string `conf:"default:localhost,env:IP_NAME_VAR"`
		IP   string `conf:"default:127.0.0.0"`
	}
	type Embed struct {
		Name     string        `conf:"default:bill"`
		Duration time.Duration `conf:"default:1s,flag:e-dur,short:d"`
	}
	type config struct {
		AnInt   int    `conf:"default:9"`
		AString string `conf:"default:B,short:s"`
		Bool    bool
		Skip    string `conf:"-"`
		IP      ip
		Embed
	}

Would produce the following usage output:

Usage: conf.test [options] [arguments]

OPTIONS
  --an-int/$CRUD_AN_INT         <int>       (default: 9)
  --a-string/-s/$CRUD_A_STRING  <string>    (default: B)
  --bool/$CRUD_BOOL             <bool>
  --ip-name/$CRUD_IP_NAME_VAR   <string>    (default: localhost)
  --ip-ip/$CRUD_IP_IP           <string>    (default: 127.0.0.0)
  --name/$CRUD_NAME             <string>    (default: bill)
  --e-dur/-d/$CRUD_DURATION     <duration>  (default: 1s)
  --help/-h
  display this help message

The API is a single call to Parse

	// Parse(args []string, namespace string, cfgStruct interface{}, sources ...Sourcer) error

	if err := conf.Parse(os.Args, "CRUD", &cfg); err != nil {
		log.Fatalf("main : Parsing Config : %v", err)
	}

Additionally, if the config struct has a field of the slice type conf.Args then it will be populated with any remaining arguments from the command line after flags have been processed.

For example a program with a config struct like this:

var cfg struct {
	Port int
	Args conf.Args
}

If that program is executed from the command line like this:

$ my-program --port=9000 serve http

Then the cfg.Args field will contain the string values ["serve", "http"]. The Args type has a method Num for convenient access to these arguments such as this:

arg0 := cfg.Args.Num(0) // "serve"
arg1 := cfg.Args.Num(1) // "http"
arg2 := cfg.Args.Num(2) // "" empty string: not enough arguments

Documentation

Overview

Package conf provides support for using environmental variables and command line arguments for configuration.

It is compatible with the GNU extensions to the POSIX recommendations for command-line options. See http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html

There are no hard bindings for this package. This package takes a struct value and parses it for both the environment and flags. It supports several tags to customize the flag options.

default  - Provides the default value for the help
env      - Allows for overriding the default variable name.
flag     - Allows for overriding the default flag name.
short    - Denotes a shorthand option for the flag.
noprint  - Denotes to not include the field in any display string.
required - Denotes a value must be provided.
help     - Provides a description for the help.

The field name and any parent struct name will be used for the long form of the command name unless the name is overridden.

As an example, this config struct:

type ip struct {
	Name string `conf:"default:localhost,env:IP_NAME_VAR"`
	IP   string `conf:"default:127.0.0.0"`
}
type Embed struct {
	Name     string        `conf:"default:bill"`
	Duration time.Duration `conf:"default:1s,flag:e-dur,short:d"`
}
type config struct {
	AnInt   int    `conf:"default:9"`
	AString string `conf:"default:B,short:s"`
	Bool    bool
	Skip    string `conf:"-"`
	IP      ip
	Embed
}

Would produce the following usage output:

Usage: conf.test [options] [arguments]

OPTIONS

--an-int/$CRUD_AN_INT         <int>       (default: 9)
--a-string/-s/$CRUD_A_STRING  <string>    (default: B)
--bool/$CRUD_BOOL             <bool>
--ip-name/$CRUD_IP_NAME_VAR   <string>    (default: localhost)
--ip-ip/$CRUD_IP_IP           <string>    (default: 127.0.0.0)
--name/$CRUD_NAME             <string>    (default: bill)
--e-dur/-d/$CRUD_DURATION     <duration>  (default: 1s)
--help/-h
display this help message

The API is a single call to Parse

// Parse(args []string, namespace string, cfgStruct interface{}, sources ...Sourcer) error

if err := conf.Parse(os.Args, "CRUD", &cfg); err != nil {
	log.Fatalf("main : Parsing Config : %v", err)
}

Additionally, if the config struct has a field of the slice type conf.Args then it will be populated with any remaining arguments from the command line after flags have been processed.

For example a program with a config struct like this:

var cfg struct {
	Port int
	Args conf.Args
}

If that program is executed from the command line like this:

$ my-program --port=9000 serve http

Then the cfg.Args field will contain the string values ["serve", "http"]. The Args type has a method Num for convenient access to these arguments such as this:

arg0 := cfg.Args.Num(0) // "serve"
arg1 := cfg.Args.Num(1) // "http"
arg2 := cfg.Args.Num(2) // "" empty string: not enough arguments

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrHelpWanted = errors.New("help wanted")

ErrHelpWanted provides an indication help was requested.

View Source
var ErrInvalidStruct = errors.New("configuration must be a struct pointer")

ErrInvalidStruct indicates that a configuration struct is not the correct type.

Functions

func Parse

func Parse(args []string, namespace string, cfgStruct interface{}, sources ...Sourcer) error

Parse parses configuration into the provided struct.

func String

func String(v interface{}) (string, error)

String returns a stringified version of the provided conf-tagged struct, minus any fields tagged with `noprint`.

Example
package main

import (
	"fmt"
	"os"
	"time"

	"github.com/events-app/events-api2/internal/platform/conf"
)

type ip struct {
	Name string `conf:"default:localhost,env:IP_NAME_VAR"`
	IP   string `conf:"default:127.0.0.0"`
}
type Embed struct {
	Name     string        `conf:"default:bill"`
	Duration time.Duration `conf:"default:1s,flag:e-dur,short:d"`
}
type config struct {
	AnInt   int    `conf:"default:9"`
	AString string `conf:"default:B,short:s"`
	Bool    bool
	Skip    string `conf:"-"`
	IP      ip
	Embed
}

func main() {
	tt := struct {
		name string
		envs map[string]string
	}{
		name: "one-example",
		envs: map[string]string{"TEST_AN_INT": "1", "TEST_S": "s", "TEST_BOOL": "TRUE", "TEST_SKIP": "SKIP", "TEST_IP_NAME": "local", "TEST_NAME": "andy", "TEST_DURATION": "1m"},
	}

	os.Clearenv()
	for k, v := range tt.envs {
		os.Setenv(k, v)
	}

	var cfg config
	if err := conf.Parse(nil, "TEST", &cfg); err != nil {
		fmt.Print(err)
		return
	}

	out, err := conf.String(&cfg)
	if err != nil {
		fmt.Print(err)
		return
	}

	fmt.Print(out)

}
Output:

--an-int=1
--a-string/-s=B
--bool=true
--ip-name=localhost
--ip-ip=127.0.0.0
--name=andy
--e-dur/-d=1m0s

func Usage

func Usage(namespace string, v interface{}) (string, error)

Usage provides output to display the config usage on the command line.

Types

type Args

type Args []string

Args holds command line arguments after flags have been parsed.

func (Args) Num

func (a Args) Num(i int) string

Num returns the i'th argument in the Args slice. It returns an empty string the request element is not present.

type FieldError

type FieldError struct {
	// contains filtered or unexported fields
}

A FieldError occurs when an error occurs updating an individual field in the provided struct value.

func (*FieldError) Error

func (err *FieldError) Error() string

type Setter

type Setter interface {
	Set(value string) error
}

Setter is implemented by types can self-deserialize values. Any type that implements flag.Value also implements Setter.

type Sourcer

type Sourcer interface {

	// Source takes the field key and attempts to locate that key in its
	// configuration data. Returns true if found with the value.
	Source(fld field) (string, bool)
}

Sourcer provides the ability to source data from a configuration source. Consider the use of lazy-loading for sourcing large datasets or systems.

Jump to

Keyboard shortcuts

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