configure

package module
Version: v0.0.0-...-28f9c3f Latest Latest
Warning

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

Go to latest
Published: Feb 18, 2019 License: MIT Imports: 9 Imported by: 19

README

Configure

GoDoc

Configure is a Go package that gives you easy configuration of your project through redundancy. It has an API inspired by negroni and the flag package.

What is it?

Configure aims to be the github.com/codegangsta/negroni of configuration. It is a Checker manager, in the same way negroni manages net/http middleware. A Checker is a way of retrieving configuration values from a source: these can be easily made by completing the Checker interface. The idea is that you as a developer provide Configure with a selection of Checkers, either built in or not and it will iterate over them attempting to find values defined by the developer. If a Checker is successful in its retrieval, then Configure will stop the iteration for that value. If it is not then Configure will attempt the next Checker in chronological order.

Getting Started

After you have installed Go (and have made sure to correctly setup your GOPATH) create a new .go file, maybe hello.go.

package main

import (
  "fmt"
  
  "github.com/paked/configure"
)

var (
  conf = configure.New()
  name = conf.String("name", "Harrison", "The name you want to greet")
)

func init() {
  conf.Use(configure.NewEnvironment())
  conf.Use(configure.NewFlag())
}

func main() {
  conf.Parse()
  fmt.Printf("Hello, %v", *name)
}

If you run this code with

go run hello.go

Hello, Harrison will be printed to your terminal, not that interesting right... read on!

Stage One : Declaration
var (
  conf = configure.New()
  name = conf.String("name", "Harrison", "The name you want to greet")
)

The declaration stage is important because it defines exactly what you CAN configure! First, conf is created which is your key to adding Checkers and retrieving variables. After that you begin properly declaring your variables, in this example only a string is declared but in practice you can use any number of Strings, Ints or Bools. The variables returned by these methods are pointers to their respective types.

Stage Two : Configuration
func init() {
  conf.Use(configure.NewEnvironment())
  conf.Use(configure.NewFlag())
}

The configuration stage is where you configure configure by adding Checkers to the stack. Checkers are objects which will attempt to retrieve your variables from their respective data sources. When a Checker fails the next one in the stack is called, the stack is in the same order that the Checker's were added in. You can configure configure anytime before you call the conf.Parse() function, but the init() function provides a reliable place to do so.

note: When using the Environment Checker, all keys will be translated to uppercase and have dashes replaced with underscores (ie. hello-world to HELLO_WORLD).

Stage Three : Usage
func main() {
  conf.Parse()
  fmt.Printf("Hello, %v", *name)
}

The final stage is where you can actually use the variables you have declared. After using conf.Parse() your variables should then be populated and accesible by dereferencing it (name).

Execution

If you were to run this code in its current state it would print Hello, Harrison because Harrison is the default value provided in the declaration stage. But if you provide --name=Johny when you execute the command it will print Hello, Johny. At this point configure is behaving like the default flag package through the Flag Checker. Now, run export NAME=Jarvis in your command line and execute the program again and ommit the entire --name=command line flag. You will see a Hello, Jarvis, as configure has fallen back upon the Environment Checker. Note that, if you provide both means of input the environment variable will be used, as it has higher priority as it was added before the Flag Checker in the configuration stage. This works with any number of Checkers from any source, as long as the fulfil the Checker interface.

Further Reading

More package documentation can be found on godoc.

A more complicated example can be found in the example folder, it uses all three variable types (Int, Bool and String) and all three of the default Checker's (JSON, Environment and Flag).

Contributing

If you notice something that you feel is broken or missing in configure feel free to open up an issue so that we can discuss it more. While small changes could be immediately put into a PR, I believe it saves everyones time to discuss major changes before implementing them. Contributions are welcome and appreciated.

Checkers

Name Location Initialiser Description
Environment [builtin] http://github.com/paked/configure NewEnvironment() Environment checks the os environment variables for values
JSON [builtin] http://github.com/paked/configure NewJSON(io.Reader) Retrieves values from an io.Reader containing JSON
Flag [builtin] http://github.com/paked/configure NewFlag() Retrieve flagged values from os.Args in a --x=y format
HCL [builtin] http://github.com/paked/configure NewHCL(io.Reader) Retrieve values from an io.Reader containing HCL

If you write your own Checker I would LOVE to see it, create a PR with a new entry in the table!

Note

As you may have noticed, I am not particularly great at English. If you notice a way to de-garble a few of my sentences be sure to let me know... Not only I, but future readers will be grateful too :)

designed and implemented by Harrison Shoebridge

Documentation

Overview

Package configure is an easy to use multi-layer configuration system.

Examples can be found in the example folder (http://github.com/paked/configure/blob/master/examples/) as well as a getting started guide in the main README file (http://github.com/paked/configure).

configure makes use of Checkers, which are used to retrieve values from their respective data sources. There are three built in Checkers, Environment, Flag and JSON. Environment retrieves environment variables. Flag retrieves variables within the flags of a command. JSON retrieves values from a JSON file/blob. Checkers can be essentially thought of as "middlewear for configuration", in fact parts of the package API was inspired by negroni (https://github.com/codegangsta/negroni, the awesome net/http middlewear manager) and the standard library's flag package.

It is very easy to create your own Checkers, all they have to do is satisfy the Checker interface.

 type Checker interface {
	  Int(name string) (int, error)
	  Bool(name string) (int, error)
	  String(name string) (string, error)
	  Setup() error
 }

That is an, Int method, String method and a Bool method. These functions are used to retrieve their respective data types. A setup method is also required, where the Checker should initialize itself and throw any errors.

If you do create your own Checkers I would be more than happy to add a link to the README in the github repository.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Checker

type Checker interface {
	// Setup initializes the Checker
	Setup() error
	// Int attempts to get an int value from the data source.
	Int(name string) (int, error)

	// String attempts to get a string value from the data source.
	String(name string) (string, error)

	// Bool attempts to get a bool value from the data source.
	Bool(name string) (bool, error)
}

Checker is the interface which external checkers must comply to. In the configure implementation, if one Checker fails the next one in the stack should be called.

type Configure

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

Configure is a stack of Checkers which are used to retrieve configuration values. It has a similar API as the flag package in the standard library, and is also partially inspired by negroni. Checkers are evaluated in the same order they are added.

func New

func New(stack ...Checker) *Configure

New returns a pointer to a new Configure instance with a stack provided through the variadic stack variable.

func (*Configure) Bool

func (c *Configure) Bool(name string, def bool, description string) *bool

Bool defines a bool flag with a name, default and description. The return value is a pointer which will be populated with the value of the flag.

func (*Configure) BoolVar

func (c *Configure) BoolVar(value *bool, name string, def bool, description string)

BoolVar binds a provided *bool to a flag value.

func (*Configure) Int

func (c *Configure) Int(name string, def int, description string) *int

Int defines an int flag with a name, default and description. The return value is a pointer which will be populated with the value of the flag.

func (*Configure) IntVar

func (c *Configure) IntVar(value *int, name string, def int, description string)

IntVar binds a provided *int to a flag value.

func (*Configure) Parse

func (c *Configure) Parse()

Parse populates all of the defined arguments with their values provided by the stacks Checkers.

func (*Configure) String

func (c *Configure) String(name string, def string, description string) *string

String defines a string flag with a name, default and description. The return value is a pointer which will be populated with the value of the flag.

func (*Configure) StringVar

func (c *Configure) StringVar(value *string, name string, def string, description string)

StringVar binds a provided *string to a flag value.

func (*Configure) Use

func (c *Configure) Use(checkers ...Checker)

Use adds a variable amount of Checkers onto the stack.

type Environment

type Environment struct {
}

Environment is a Checker. It retrieves values from the host OS's environment variables. In this process, it will take a flag-like name, and convert it to a environmnet-like name. The process for this is to change all characters to upper case, and then replace hyphons with underscores.

func NewEnvironment

func NewEnvironment() *Environment

NewEnvironment creates a new instance of the Environment Checker. Note: If you request a value "peanut-butter", the environment variable that will be checked is `PEANUT_BUTTER`.

func (*Environment) Bool

func (e *Environment) Bool(name string) (bool, error)

Bool returns a bool if it exists in the set environment variables.

func (Environment) Int

func (e Environment) Int(name string) (int, error)

Int returns an int if it exists in the set environment variables.

func (Environment) Setup

func (e Environment) Setup() error

func (Environment) String

func (e Environment) String(name string) (string, error)

String returns a string if it exists in the set environment variables.

type Flag

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

Flag is an ULTRA simple flag parser for strings, ints and bools. It expects flags in the format --x=2 (where x is the var name and 2 is the value). It can be provided with a "usage printer", which by default will be printed when the "-h" flag is used.

func NewFlag

func NewFlag() *Flag

NewFlag returns a new instance of the Flag Checker, using os.Args as its flag source.

func NewFlagWithUsage

func NewFlagWithUsage(defaulter func() string) *Flag

NewFlagWithUsage returns a new instance of the Flag Checker with a custom usage printer. It uses os.Args as its flag source.

func (*Flag) Bool

func (f *Flag) Bool(name string) (bool, error)

Bool returns a bool if it exists in the set flags.

func (Flag) Int

func (f Flag) Int(name string) (int, error)

Int returns an int if it exists in the set flags.

func (Flag) Setup

func (f Flag) Setup() error

func (Flag) String

func (f Flag) String(name string) (string, error)

String returns a string if it exists in the set flags.

type HCL

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

HCL represents the HCL Checker. It reads an io.Reader and then pulls a value out of a map[string]interface{}.

func NewHCL

func NewHCL(gen func() (io.Reader, error)) *HCL

NewHCL returns an instance of the HCL checker. It takes a function which returns an io.Reader which will be called when the first value is recalled. The contents of the io.Reader MUST be decodable into HCL or JSON.

func NewHCLFromFile

func NewHCLFromFile(path string) *HCL

NewHCLFromFile returns an instance of the HCL checker. It reads its data from a file (file content can be HCL or JSON) which its location has been specified through the path parameter

func (*HCL) Bool

func (h *HCL) Bool(name string) (bool, error)

Bool returns a bool if it exists within the HCL io.Reader.

func (*HCL) Int

func (h *HCL) Int(name string) (int, error)

Int returns an int if it exists within the HCL io.Reader

func (*HCL) Setup

func (h *HCL) Setup() error

Setup initializes the HCL Checker

func (*HCL) String

func (h *HCL) String(name string) (string, error)

String returns a string if it exists within the HCL io.Reader.

type JSON

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

JSON represents the JSON Checker. It reads an io.Reader and then pulls a value out of a map[string]interface{}.

func NewJSON

func NewJSON(gen func() (io.Reader, error)) *JSON

NewJSON returns an instance of the JSON checker. It takes a function which returns an io.Reader which will be called when the first value is recalled. The contents of the io.Reader MUST be decodable into JSON.

func NewJSONFromFile

func NewJSONFromFile(path string) *JSON

NewJSONFromFile returns an instance of the JSON checker. It reads its data from a file which its location has been specified through the path parameter

func (*JSON) Bool

func (j *JSON) Bool(name string) (bool, error)

Bool returns a bool if it exists within the marshalled JSON io.Reader.

func (*JSON) Int

func (j *JSON) Int(name string) (int, error)

Int returns an int if it exists within the marshalled JSON io.Reader.

func (*JSON) Setup

func (j *JSON) Setup() error

Setup initializes the JSON Checker

func (*JSON) String

func (j *JSON) String(name string) (string, error)

String returns a string if it exists within the marshalled JSON io.Reader.

Directories

Path Synopsis
hcl

Jump to

Keyboard shortcuts

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