conf

package module
v2.2.0 Latest Latest
Warning

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

Go to latest
Published: Nov 30, 2021 License: Apache-2.0 Imports: 12 Imported by: 23

README

Conf

CircleCI

Copyright 2018, 2019, 2020, 2021, Ardan Labs
info@ardanlabs.com

Licensing

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

About The Project

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

All of the documentation can be found on the go.dev website.

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

Flags

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.
mask     - Includes the field in any display string but masks out the value.
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.

Example Usage

As an example, using 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
}

The following usage information would be output you can display.

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
--version/-v
display version information

Example Parsing

There is an API called Parse that can process a config struct with environment variable and command line flag overrides.

const prefix = "APP"
var cfg config
help, err := conf.Parse(prefix, &cfg)
if err != nil {
	if errors.Is(err, conf.ErrHelpWanted) {
		fmt.Println(help)
		return nil
	}
	return fmt.Errorf("parsing config: %w", err)
}

There is also YAML support using the yaml package that is part of this modeule.

var yamlData = `
a: Easy!
b:
	c: 2
	d: [3, 4]
`

type config struct {
	A string
	B struct {
		RenamedC int   `yaml:"c"`
		D        []int `yaml:",flow"`
	}
	E string `conf:"default:postgres"`
}

const prefix = "APP"
var cfg config
help, err := conf.Parse(prefix, &cfg, yaml.WithData([]byte{yamlData}))
if err != nil {
	if errors.Is(err, conf.ErrHelpWanted) {
		fmt.Println(help)
		return nil
	}
	return fmt.Errorf("parsing config: %w", err)
}

There is a WithParse function that takes a slice of bytes containing the YAML or WithParseReader that takes any concrete value that knows how to Read.

Command Line Args

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

Version Information

You can add a version with a description by adding the Version type to your config type and set these values at run time for display.

cfg := struct {
	conf.Version
	Web struct {
		APIHost         string        `conf:"default:0.0.0.0:3000"`
		DebugHost       string        `conf:"default:0.0.0.0:4000"`
		ReadTimeout     time.Duration `conf:"default:5s"`
		WriteTimeout    time.Duration `conf:"default:10s"`
		IdleTimeout     time.Duration `conf:"default:120s"`
		ShutdownTimeout time.Duration `conf:"default:20s"`
	}
}{
	Version: conf.Version{
		Build: "v1.0.0",
		Desc:  "Service Description",
	},
}

const prefix = "APP"
help, err := conf.Parse(prefix, &cfg)
if err != nil {
	if errors.Is(err, conf.ErrHelpWanted) {
		fmt.Println(help)
		return nil
	}
	return fmt.Errorf("parsing config: %w", err)
}

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrHelpWanted provides an indication help was requested.
	ErrHelpWanted = errors.New("help wanted")
)
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(prefix string, cfg interface{}, parsers ...Parsers) (string, error)

Parse parses the specified config struct. This function will apply the defaults first and then apply environment variables and command line argument overrides to the struct. ErrHelpWanted is returned when the --help or --version are detected.

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
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)
}

os.Args = []string{"conf.test"}

var cfg config
if _, err := conf.Parse("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
--ip-endpoints=[127.0.0.1:200 127.0.0.1:829]
--debug-host=http://xxxxxx:xxxxxx@0.0.0.0:4000
--password=xxxxxx
--custom=@hello@
--name=andy
--e-dur/-d=1m0s

func UsageInfo

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

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

func VersionInfo

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

VersionInfo provides output to display the application version and description 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 Field

type Field struct {
	Name    string
	FlagKey []string
	EnvKey  []string
	Field   reflect.Value
	Options FieldOptions

	// Important for flag parsing or any other source where
	// booleans might be treated specially.
	BoolField bool
}

Field maintains information about a field in the configuration struct.

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 FieldOptions

type FieldOptions struct {
	Help          string
	DefaultVal    string
	EnvName       string
	FlagName      string
	ShortFlagChar rune
	Noprint       bool
	Required      bool
	Mask          bool
}

FieldOptions maintain flag options for a given field.

type Parsers

type Parsers interface {
	Process(prefix string, cfg interface{}) error
}

Parsers declare behavior to extend the different parsers that can be used to unmarshal config.

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 Version

type Version struct {
	Build string
	Desc  string
}

Version provides the abitily to add version and description to the application.

Directories

Path Synopsis
Package yaml provides yaml support for conf.
Package yaml provides yaml support for conf.

Jump to

Keyboard shortcuts

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