envexist

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Apr 17, 2020 License: MPL-2.0 Imports: 5 Imported by: 2

README

Synopsis

use in lib
package mylib

import (
    "github.com/raohwork/envexist"
    _ "github.com/go-sql-driver/mysql"
)

var DB *sql.DB

// read db config from env var and create *sql.DB
func init() {
    m, data := envexist.New("mylib", mysetup)
    m.Need("DB_CONN", "connect string for mysql", "user:pass@tcp(mysql)/mydb")
    m.May("DB_PARAM", "additional param for constr", "parseTime=true")
}

func mysetup(env map[string]string) {
    var err error
    constr := env["DB_CONN"] 
    if param := env["DB_PARAM"]; param != "" {
        constr += "?" + param
    }
    if DB, err = sql.Open("mysql", constr); err != nil {
        log.Fatal(err)
    }
}
in application entry
package main

import (
    "github.com/raohwork/envexist"
    "./mylib"
)

func main() {
    m, ch := envexist.Main("myprog")
    m.Want("DEBUG", "any non-empty value enables debug mode", "")
    if !envexist.Parse() {
        envexist.PrintEnvList()
        os.Exist(1)
    }
    
    // codes below will always run after mylib.mysetup()
    data := <- ch
    if data["DEBUG"] != "" {
        // enable debug mode here
    }
    
    // other application codes
}

License

MPL 2.0

Documentation

Overview

Package envexist provides few tools to validate env vars based on modules

Each module registers itself to envexist (typically in init()), and waits the result in a callback. The application entry (main() in package main) takes responsibility to call envexist.Parse(), which validates env vars and triggers further initialization.

Package envexist IS NOT (and cannot be) thread-safe.

Example
// reset envexist as we're in test environment, you should not need this
Release()
// simulate
os.Setenv("MYMODULE_PARAM_2", "中文")

m, ch := Main("MYMODULE")
// there will be an asterisk before the Name column
m.Need("PARAM_1", "a super detailed and descriptive decription which introduces how this variable should be and what it should do", "example value")

// nothing special
m.Want("PARAM_2", "desc", "example")

// there will be an asterisk before the Example column
m.May("PARAM_3", "the value in example works as default value", "default_Value")

if !Parse() {
	PrintEnvList()
	return
}

// consume your data here
env := <-ch
param1 := env["PARAM_1"]
_ = param1
Output:

+----------------------+----------------------+---------------------------+-----------------+
| Name                 | Value                | Description               | Example         |
+----------------------+----------------------+---------------------------+-----------------+
|*MYMODULE_PARAM_1     |                      | a super detailed and desc | example value   |
|                      |                      | riptive decription which  |                 |
|                      |                      | introduces how this varia |                 |
|                      |                      | ble should be and what it |                 |
|                      |                      |  should do                |                 |
+----------------------+----------------------+---------------------------+-----------------+
| MYMODULE_PARAM_2     | 中文                 | desc                      | example         |
+----------------------+----------------------+---------------------------+-----------------+
| MYMODULE_PARAM_3     |                      | the value in example work |*default_Value   |
|                      |                      | s as default value        |                 |
+----------------------+----------------------+---------------------------+-----------------+

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Parse

func Parse() (ok bool)

Parse checks all required env vars are set, and pass final data through channel

It blocks until first error or all callbacks executed, that's why you should not use New() in application entry.

Env vars are passed only if this returns true.

YOU MUST NOT CALL New() or Main() AFTER THIS.

func PrintEnvList

func PrintEnvList()

PrintEnvList lists all registered env vars with fmt.Print

TODO: customizable formatting and output writer

func Release

func Release()

Release releases used resources

YOU SHOULD NOT CALL Parse() or PrintEnvList() AFTER THIS.

Types

type Module

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

Module represents a set of env vars

func Main

func Main(name string) (ret *Module, ch chan map[string]string)

Main registers a new module suitable for main application entry

The env var will passed through data after calling Parse()

It calls New() with a callback, which pushes data into ch. As ch is a buffered channel, Parse() can return before you retrieve the result from ch.

func New

func New(name string, cb func(data map[string]string)) (ret *Module)

New registers a new module suitable for libraries

The env var will passed through data after calling Parse()

It ALWAYS converts name to uppercase.

func (*Module) May

func (m *Module) May(name string, desc, example string) (ret *Module)

May registers an optional env var with default value in example

It ALWAYS converts name to uppercase.

You can always get some value if Parse() returns true. If corresponding envvar is not set, default value is used instead.

func (*Module) Need

func (m *Module) Need(name string, desc, example string) (ret *Module)

Need registers a required env var

It ALWAYS converts name to uppercase.

You have to set corresponding envvar or Parse() will fail.

When handling returned data in callback (or channel), it is guaranteed that _, ok := data[name] to be true.

func (*Module) Want

func (m *Module) Want(name string, desc, example string) (ret *Module)

Want registers an optional env var

It ALWAYS converts name to uppercase.

You can omit the envvar and Parse() will still success

The element will be emitted in data of callback if corresponding envvar is not set.

Jump to

Keyboard shortcuts

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