envy

package module
v0.2.3 Latest Latest
Warning

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

Go to latest
Published: Mar 27, 2022 License: MIT Imports: 7 Imported by: 1

README

envy

Automatically load flags as environment variables with pflag!

Install

go install github.com/fernferret/envy

About

There are a lot of solutions for loaing environment variables, but I find a lot of them very heavy/confusing. All I wanted was:

  • Something to crawl the flags I'd defined and read from a PFX_ + flag
  • A way to define exclusions for desstructive flags that must be set explicitly
  • A way to define exclusions for "well known" variables like $KUBECONFIG
  • Don't mangle the default value in the flag help if an envvar was set

Enter: envy. The basic idea and name came from https://github.com/jamiealquiza/envy, however this version requires using cobra which I find a bit overkill for some of my small apps. It also didn't support some of the extended features like Disable and SetEnvName.

The order of values is kept very simple:

  1. Flag value
  2. Environment value
  3. Default flag value

This means the flag value, like --foo=x, will always take priority. If it's not set, then the environment variable will be checked, and if that's not set envy will use the default flag value.

Usage

Here's a really simple use case, with more examples in the documentation.

package main

import (
    "fmt"

    "github.com/fernferret/envy"
    "github.com/spf13/pflag"
)

func main() {
    url := pflag.String("url", "http://localhost:8080", "set the url")
    once := pflag.Bool("once", false, "only run processing once")

    // Don't use FOO_URL, instead use MY_HTTP_URL as the env var
    envy.SetEnvName("url", "MY_HTTP_URL")

    // Parse items with a prefix of MYAPP_
    envy.Parse("MYAPP")

    pflag.Parse()

    fmt.Printf("url was %s\n", *url)
    fmt.Printf("once was %v\n", *once)
}

# Environment defaults show up in brackets, these are unset
./foo -h
Usage of ./foo:
      --once         only run processing once [MYAPP_ONCE]
      --url string   set the url [MY_HTTP_URL] (default "http://localhost:8080")
pflag: help requested

./foo --once
url was http://localhost:8080
once was true

# Now let's set both envvars, booleans are set with just "true" or "false"
export MYAPP_ONCE true
export MY_HTTP_URL https://www.google.com

# Environment defaults show up inside the brackets if set at runtime
./foo -h
Usage of ./foo:
      --once         only run processing once [MYAPP_ONCE true]
      --url string   set the url [MY_HTTP_URL https://www.google.com] (default "http://localhost:8080")
pflag: help requested

# Load both values from envvars
./foo
url was https://www.google.com
once was true

# Flags *always* take priority
./foo --once=false
url was https://www.google.com
once was false

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrFlagNotExists            = errors.New("flag does not exist")
	ErrCustomAlreadyDefined     = errors.New("custom flag already exists")
	ErrInvalidBoolFlagValue     = errors.New("bool flag got value that was't 'true' or 'false'")
	ErrInvalidDurationFlagValue = errors.New("duration flag got value that was't parsable as a golang duration, example: 1m30s")
)

Functions

func Disable

func Disable(name string)

Disable removes the given flag from using any environment variables. It must be called before the call to envy.Parse().

Example
package main

import (
	"os"

	"github.com/fernferret/envy"
	"github.com/spf13/pflag"
)

func main() {
	// Reset CommandLine flags for example, you don't need this in your code!
	pflag.CommandLine = pflag.NewFlagSet("test", pflag.PanicOnError)

	// Define a few flags
	pflag.String("url", "http://localhost:8080", "set the url")
	pflag.Bool("once", false, "only run processing once")

	// Don't allow FOO_ONCE to set the --once flag.
	envy.Disable("once")

	// Pre-parse with envy with a prefix of FOO_
	envy.Parse("FOO")

	// Parse the flags
	pflag.Parse()

	// Output results to stdout instead of the default stderr
	pflag.CommandLine.SetOutput(os.Stdout)
	pflag.PrintDefaults()
}
Output:

--once         only run processing once
      --url string   set the url [FOO_URL] (default "http://localhost:8080")

func DisableOnFlagSet

func DisableOnFlagSet(name string, fs *pflag.FlagSet)

DisableOnFlagSet removes the given flag from using any environment variables. It must be called before the call to envy.Parse().

func Parse

func Parse(pfx string)

ParseFlagSet will loop through defined flags in the default pflag.CommandLine and automatically add an environment variable parser for the flag name. This Parse func must be called before the call to pflag.Parse() and after you've defined all your flags.

Example
package main

import (
	"os"
	"time"

	"github.com/fernferret/envy"
	"github.com/spf13/pflag"
)

func main() {
	// Reset CommandLine flags for example, don't include these in your code!
	pflag.CommandLine = pflag.NewFlagSet("test", pflag.PanicOnError)
	os.Clearenv()

	// Define a few flags
	pflag.String("url", "http://localhost:8080", "set the url")
	pflag.Bool("once", false, "only run processing once")
	pflag.DurationP("interval", "i", time.Minute, "interval to check widgets")

	// Simulate COOL_APP_INTERVAL being set
	os.Setenv("COOL_APP_INTERVAL", "10m")

	// Pre-parse with envy with a prefix of COOL_APP_
	envy.Parse("COOL_APP")

	// Don't sort the flags.
	pflag.CommandLine.SortFlags = false

	// Parse the flags
	pflag.Parse()

	// Output results to stdout instead of the default stderr
	pflag.CommandLine.SetOutput(os.Stdout)
	pflag.PrintDefaults()
}
Output:

--url string          set the url [COOL_APP_URL] (default "http://localhost:8080")
      --once                only run processing once [COOL_APP_ONCE]
  -i, --interval duration   interval to check widgets [COOL_APP_INTERVAL 10m0s] (default 1m0s)

func ParseFlagSet

func ParseFlagSet(pfx string, fs *pflag.FlagSet)

ParseFlagSet will loop through defined flags in the given pflag.FlagSet and automatically add an environment variable parser for the flag name. This ParseFlagSet func must be called before the call to pflag.Parse() and after you've defined all your flags.

func SetEnvName

func SetEnvName(name, envName string)

SetEnvName allows setting a custom environment variable for a given flag. It must be called before the call to envy.Parse().

Example
package main

import (
	"os"

	"github.com/fernferret/envy"
	"github.com/spf13/pflag"
)

func main() {
	// Reset CommandLine flags for example, you don't need this in your code!
	pflag.CommandLine = pflag.NewFlagSet("test", pflag.PanicOnError)

	// Define a few flags
	pflag.String("url", "http://localhost:8080", "set the url")
	pflag.Bool("once", false, "only run processing once")

	// Don't use FOO_URL, instead use MY_HTTP_URL as the env var
	envy.SetEnvName("url", "MY_HTTP_URL")

	// Pre-parse with envy with a prefix of FOO_
	envy.Parse("FOO")

	pflag.Parse()

	// Output results to stdout instead of the default stderr
	pflag.CommandLine.SetOutput(os.Stdout)
	pflag.PrintDefaults()
}
Output:

--once         only run processing once [FOO_ONCE]
      --url string   set the url [MY_HTTP_URL] (default "http://localhost:8080")

func SetEnvNameOnFlagSet

func SetEnvNameOnFlagSet(name, envName string, fs *pflag.FlagSet)

SetEnvNameOnFlagSet allows setting a custom environment variable for a given flag. It must be called before the call to envy.Parse().

Types

This section is empty.

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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