env

package module
v1.2.0 Latest Latest
Warning

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

Go to latest
Published: Nov 21, 2024 License: EUPL-1.2 Imports: 11 Imported by: 2

README

env

env is a small package for setting variables from environment variables. It works similarly to flag, and can be used in conjunction.

Note: env requires Go 1.18 or later.

Usage.

The basic usage is similar to flag, but with the Value type that flag hides exposed:

package main

import (
	"fmt"

	"gitlab.com/slxh/go/env"
)

func main() {
	var i int

	env.AddVar(&i, "NUMBER", 0, "Some number.")
	env.Parse()

	fmt.Println(i)
}

It can also be mixed with flag:

package main

import (
	"flag"
	"fmt"
 
	"gitlab.com/slxh/go/env"
)

func main() {
	var i int

	flag.IntVar(&i, "number", 0, "Some number.")

	// Parse both flags and environment variables.
	// The flag `number` above can be set using `NUMBER`.
	// This is also shown when calling `-h`, `-help` or setting `HELP`.
	// Note that flag overrides env.
	env.ParseWithFlags() 

	fmt.Println(i)
}

Documentation

Overview

Package env implements environment variable parsing.

Index

Examples

Constants

This section is empty.

Variables

View Source
var DefaultSet = NewEnvSet("", ReturnLastError)

DefaultSet contains the default environment variable set.

Functions

func Add

func Add[T Constraint](name string, value T, usage string) *T

Add a definition for an environment variable of the specified name, with the provided UsageString string. Any value allowed by Constraint may be given. Note that only the suffix has to be provided as name if SetPrefix is used.

Example
package main

import (
	"fmt"
	"os"

	"gitlab.com/slxh/go/env"
)

func main() {
	// Set the environment variable.
	// This is usually done outside the program.
	os.Setenv("A", "5")

	// Create and register the variable and initial value.
	i := env.Add("A", -1, "Initial count")
	env.Parse()

	// Show
	fmt.Printf("Count: %v", *i)

}
Output:

Count: 5

func AddVar

func AddVar[T Constraint](p *T, name string, value T, usage string)

AddVar adds a definition for an environment variable of the specified name, with the provided UsageString string. The argument `p` is a pointer to a variable that stores the value of the environment variable. Any value allowed by Constraint may be given. Note that only the suffix has to be provided as name if SetPrefix is used.

Example
package main

import (
	"fmt"
	"os"

	"gitlab.com/slxh/go/env"
)

func main() {
	var i int

	// Set the environment variable.
	// This is usually done outside the program.
	os.Setenv("A", "5")

	// Register the variable and initial value.
	env.AddVar(&i, "A", -1, "Initial count")
	env.Parse()

	// Show
	fmt.Printf("Count: %v", i)

}
Output:

Count: 5

func FlagUsage added in v1.2.0

func FlagUsage(set *flag.FlagSet) func()

FlagUsage returns a function that prints the usage of both the flags in the given flag.FlagSet and the default EnvSet. It uses flag.CommandLine if the given FlagSet is nil.

func Func

func Func(name, usage string, fn func(string) error)

Func adds a definition for an environment variable of the specified name, with the provided UsageString string. The argument `fn` should point to a function that is called every time the named environment variable is encountered. Note that only the suffix has to be provided as name if SetPrefix is used.

Example
package main

import (
	"fmt"
	"os"
	"strings"

	"gitlab.com/slxh/go/env"
)

func main() {
	var v string

	// This is usually done outside the program.
	os.Setenv("A", "Something or other.")

	// Register the function for the environment variable.
	env.Func("A", "Initial count", func(s string) error {
		v = strings.ToUpper(s)

		return nil
	})

	env.Parse()

	// Show
	fmt.Println(v)

}
Output:

SOMETHING OR OTHER.

func Parse

func Parse() error

Parse parses the environment variables. An error is returned if environment variables contain invalid values.

func ParseWithFlags

func ParseWithFlags() error

ParseWithFlags defines the flags as set in the flag package as environment variables and parses both the environment variables and flags. It overrides flag.Usage to contain both flag and env usage using SetFlagUsage. See EnvSet.SetFlag for details on the conversion between flags and environment variables.

Example
package main

import (
	"flag"
	"fmt"
	"os"

	"gitlab.com/slxh/go/env"
)

func main() {
	// Set the environment variable.
	// This is usually done outside the program.
	os.Setenv("A", "-1")

	// Define a CLI flag.
	i := flag.Int("A", 0, "Some flag")

	// Parse the flags as environment variables, and parse both flags and environment variables.
	env.ParseWithFlags()

	// Show
	fmt.Printf("Value: %v", *i)

}
Output:

Value: -1

func Parsed

func Parsed() bool

Parsed returns a boolean indicating if Parse() has been called.

Example
package main

import (
	"fmt"

	"gitlab.com/slxh/go/env"
)

func main() {
	env.Parse()

	fmt.Println(env.Parsed())

}
Output:

true

func PrintDefaults

func PrintDefaults()

PrintDefaults prints the UsageString string to os.Stderr.

func Set

func Set(name, value string) error

Set sets a variable to the given value.

Example
package main

import (
	"fmt"
	"os"

	"gitlab.com/slxh/go/env"
)

func main() {
	// Set the environment variable.
	// This is usually done outside the program.
	os.Setenv("A", "-1")

	// Create and register the variable and initial value.
	i := env.Add("A", 0, "A")

	env.Parse()

	fmt.Println(*i)

	env.Set("A", "15")

	fmt.Println(*i)

}
Output:

-1
15

func SetErrorHandling

func SetErrorHandling(errorHandling ErrorHandling)

SetErrorHandling sets the error handling for Parse. The default policy is the ReturnFirstError policy.

func SetFlagUsage added in v1.2.0

func SetFlagUsage(set *flag.FlagSet)

SetFlagUsage set the usage on the given flag.FlagSet to EnvSet.FlagUsage. It uses flag.CommandLine if the given FlagSet is nil.

Example
package main

import (
	"flag"
	"os"

	"gitlab.com/slxh/go/env"
)

func main() {
	// Override args and flag set to make this example produce consistent output.
	// This is not needed outside of tests.
	os.Args = []string{"example_application", "-help"}
	env.DefaultSet = env.NewEnvSet("", env.ReturnFirstError)
	flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ContinueOnError)
	flag.CommandLine.SetOutput(os.Stdout)

	// Define flags and environment variables to show help for.
	flag.Int("a", 1, "A variable")
	env.Add("B", 2, "Another variable")

	// Override usage message
	env.SetFlagUsage(nil)

	flag.Parse()
}
Output:

Usage of example_application:
Flags:
  -a int
    	A variable (default 1)

Environment variables:
  B int
    	Another variable (default 2)

func SetPrefix

func SetPrefix(prefix string)

SetPrefix sets the prefix for all environment variables. This allows environment variables to share a common prefix.

func Usage

func Usage() string

Usage returns the usage string for the defined environment variables.

func Var

func Var(v Value, name string, usage string)

Var adds a definition for an environment variable of the specified name, with the provided usage string. The type and value are contained in the first argument, of type Value. Note that only the suffix has to be provided as name if SetPrefix is used.

func Visit

func Visit(fn func(*Env))

Visit visits all the defined environment variables in lexicographical order. The given function is called for all variables that have been set.

Example
package main

import (
	"fmt"
	"os"

	"gitlab.com/slxh/go/env"
)

func main() {
	// Set the environment variable.
	// This is usually done outside the program.
	os.Setenv("A", "-1")
	os.Setenv("B", "-10")

	// Create and register the variable and initial value.
	env.Add("A", 0, "A")
	env.Add("B", 0, "B")

	env.Parse()

	env.Visit(func(e *env.Env) {
		fmt.Printf("Flag %q has been set to %q\n", e.Name, e.Value)
	})

}
Output:

Flag "A" has been set to "-1"
Flag "B" has been set to "-10"

func VisitAll

func VisitAll(fn func(*Env))

VisitAll visits all the defined environment variables in lexicographical order. The given function is called for all variables, including ones not set.

Types

type Constraint

type Constraint interface {
	bool |
		float32 | float64 |
		int | int8 | int16 | int32 | int64 |
		uint | uint8 | uint16 | uint32 | uint64 |
		string |
		time.Duration | time.Time
}

Constraint contains the constraint for the Add, AddVar, NewValue and NewValueVar functions. Other types are not supported by these functions.

type Env

type Env struct {
	// Name is the name of the environment variable.
	Name string

	// Usage is the basic usage string for the environment variable.
	Usage string

	// Value is the underlying Value of the environment variable.
	Value Value
}

Env represents an environment variable.

func Lookup

func Lookup(name string) *Env

Lookup returns the Env struct for an environment variable name. `nil` is returned if the variable is not defined.

func (*Env) UnquoteUsage

func (e *Env) UnquoteUsage() (kind, usage string)

UnquoteUsage extracts a backtick-quoted kind from the usage string of an environment variable and returns it and the un-quoted usage. Given "a `name` to show" it returns ("name", "a name to show"). If there are no back quotes, the name is based on the type of the environment variable.

Example
package main

import (
	"fmt"
	"time"

	"gitlab.com/slxh/go/env"
)

func main() {
	_, v := env.NewValue(5 * time.Second)
	e := env.Env{
		Name:  "DURATION",
		Usage: "a `name` to show",
		Value: v,
	}

	kind, usage := e.UnquoteUsage()
	fmt.Printf("%s, %s", kind, usage)

}
Output:

name, a name to show
Example (NoBackticks)
package main

import (
	"fmt"
	"time"

	"gitlab.com/slxh/go/env"
)

func main() {
	_, v := env.NewValue(5 * time.Second)
	e := env.Env{
		Name:  "TIME_B",
		Usage: "a description without backticks",
		Value: v,
	}

	kind, usage := e.UnquoteUsage()
	fmt.Printf("%s, %s", kind, usage)

}
Output:

duration, a description without backticks

func (*Env) UsageString

func (e *Env) UsageString(prefix string) string

UsageString returns the usage string for the environment variable, along with any default values.

Example
package main

import (
	"fmt"
	"time"

	"gitlab.com/slxh/go/env"
)

func main() {
	_, v := env.NewValue(5 * time.Second)
	a := env.Env{
		Name:  "A",
		Usage: "a `name` to show",
		Value: v,
	}
	b := env.Env{
		Name:  "B",
		Usage: "a description",
		Value: v,
	}

	fmt.Println(a.UsageString("PREFIX_"))
	fmt.Println(b.UsageString("PREFIX_"))

}
Output:

  PREFIX_A name
    	a name to show (default 5s)
  PREFIX_B duration
    	a description (default 5s)

type EnvSet

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

EnvSet represents a set of defined environment variables.

func NewEnvSet

func NewEnvSet(prefix string, errorHandling ErrorHandling) *EnvSet

NewEnvSet returns an initialized EnvSet with the given prefix and ErrorHandling policy.

func (*EnvSet) Add

func (s *EnvSet) Add(name string, value Value, usage string)

Add a definition for an environment variable of the specified name, with the provided UsageString string. Any value allowed by Constraint may be given. Note that only the suffix has to be provided as name if SetPrefix is used.

func (*EnvSet) FlagUsage added in v1.2.0

func (s *EnvSet) FlagUsage(set *flag.FlagSet) func()

FlagUsage returns a function that prints the usage of both the flags in the given flag.FlagSet and the current EnvSet. It uses flag.CommandLine if the given FlagSet is nil.

func (*EnvSet) Func

func (s *EnvSet) Func(name, usage string, fn func(string) error)

Func adds a definition for an environment variable of the specified name, with the provided UsageString string. The argument `fn` should point to a function that is called every time the named environment variable is encountered. Note that only the suffix has to be provided as name if SetPrefix is used.

func (*EnvSet) Lookup

func (s *EnvSet) Lookup(name string) *Env

Lookup returns the Env struct for an environment variable name. `nil` is returned if the variable is not defined.

func (*EnvSet) Output

func (s *EnvSet) Output() io.Writer

Output returns the output that the EnvSet uses for methods like PrintDefaults.

func (*EnvSet) Parse

func (s *EnvSet) Parse() error

Parse parses the environment variables. An error is returned if environment variables contain invalid values.

Example
package main

import (
	"os"

	"gitlab.com/slxh/go/env"
)

func main() {
	// Define an env set to show the help for.
	es := env.NewEnvSet("", env.ReturnAllErrors)
	es.SetOutput(os.Stdout)
	es.Add("I", env.NewValueVar(new(int), 1), "A number")

	// Set the help environment variable to show help
	os.Setenv("HELP", "")

	// Show usage
	es.Parse()

	// Unset the environment variable for other tests
	os.Unsetenv("HELP")

}
Output:

Usage:
  I int
    	A number (default 1)

func (*EnvSet) ParseWithFlagSet

func (s *EnvSet) ParseWithFlagSet(flagSet *flag.FlagSet, arguments []string) error

ParseWithFlagSet defines the flags in the given flag set as environment variables, and parses both the environment variables and flags. See SetFlag for details on the conversion between flags and environment variables.

func (*EnvSet) Parsed

func (s *EnvSet) Parsed() bool

Parsed returns a boolean indicating if Parse() has been called.

func (*EnvSet) PrintDefaults

func (s *EnvSet) PrintDefaults()

PrintDefaults prints the UsageString string to the configured output (os.Stderr by default). Use SetOutput to change the output.

func (*EnvSet) Set

func (s *EnvSet) Set(name, value string) error

Set sets a variable to the given value.

func (*EnvSet) SetFlag

func (s *EnvSet) SetFlag(f *flag.Flag)

SetFlag sets an environment variable based on a flag.Flag. The name of the flag is converted to an environment variable by converting the characters to uppercase, and replacing dashes (-) to underscores. For example: `this-flag` is converted to `THIS_FLAG`.

func (*EnvSet) SetFlagUsage added in v1.2.0

func (s *EnvSet) SetFlagUsage(set *flag.FlagSet)

SetFlagUsage set the usage on the given flag.FlagSet to EnvSet.FlagUsage. It uses flag.CommandLine if the given FlagSet is nil.

Example
package main

import (
	"flag"
	"os"

	"gitlab.com/slxh/go/env"
)

func main() {
	// Define a flag set to show the help for.
	fs := flag.NewFlagSet("", flag.ContinueOnError)
	fs.SetOutput(os.Stdout)
	fs.Int("a", 1, "A number")

	// Define an env set to show the help for.
	es := env.NewEnvSet("", env.ReturnAllErrors)
	es.SetOutput(os.Stdout)
	es.Add("B", env.NewValueVar(new(int), 2), "Another number")

	// Override usage message
	es.SetFlagUsage(fs)

	fs.Parse([]string{"-h"})
}
Output:

Usage:
Flags:
  -a int
    	A number (default 1)

Environment variables:
  B int
    	Another number (default 2)

func (*EnvSet) SetOutput

func (s *EnvSet) SetOutput(w io.Writer)

SetOutput sets the output for functions that print, like PrintDefaults.

func (*EnvSet) Usage

func (s *EnvSet) Usage() string

Usage returns the usage string for the defined environment variables.

func (*EnvSet) Var

func (s *EnvSet) Var(v Value, name string, usage string)

Var adds a definition for an environment variable of the specified name, with the provided usage string. The type and value are contained in the first argument, of type Value. Note that only the suffix has to be provided as name if SetPrefix is used.

func (*EnvSet) Visit

func (s *EnvSet) Visit(fn func(*Env))

Visit visits all the defined environment variables in lexicographical order. The given function is called for all variables that have been set.

func (*EnvSet) VisitAll

func (s *EnvSet) VisitAll(fn func(*Env))

VisitAll visits all the defined environment variables in lexicographical order. The given function is called for all variables, including ones not set.

type ErrorHandling

type ErrorHandling int

ErrorHandling defines how EnvSet.Parse behaves when errors are encountered.

const (
	ReturnLastError  ErrorHandling = iota // Continue parsing when errors are encountered (the default).
	ReturnFirstError                      // Return the first error that is encountered.
	ReturnAllErrors                       // Return all encountered errors using [errors.Join].
)

Defined error handling flows.

type Value

type Value interface {
	// Get returns the current value.
	// It may return nil when there is no current value.
	Get() any

	// Default returns the default value as a string.
	// An empty string means there is no default value.
	Default() string

	// Set the value based on the given string.
	// An error is returned if the given string cannot be used to set the Value.
	Set(s string) error

	// String returns the string representation of the current value.
	// It may return an empty string when there is no current value.
	String() string
}

Value is the interface to the value stored in an environment variable, or flag. It satisfies both flag.Getter and flag.Value, allowed it to be used with both.

func NewFuncValue

func NewFuncValue(fn func(string) error) Value

NewFuncValue returns a Value for the given function. Note that the Value will return nil for Get, and "" for Default and String.

func NewValue

func NewValue[T Constraint](d T) (*T, Value)

NewValue creates a new Value with a default value, and returns a pointer to the value.

Example
package main

import (
	"flag"
	"fmt"
	"os"

	"gitlab.com/slxh/go/env"
)

func main() {
	// EnvSet the environment variable.
	// This is usually done outside the program.
	os.Setenv("A", "15")

	// Create a new variable
	i, v := env.NewValue(-1)

	// Register and read from environment.
	// Note that you can use `env.Var` (and `env.Parse()`) directly as well.
	es := env.NewEnvSet("", env.ReturnFirstError)
	es.SetOutput(os.Stdout)
	es.Var(v, "A", "Initial count (`number`)")

	// Override with CLI flags.
	// Note that you can use `flag.Var` (and `flag.Parse()`) directly as well.
	fs := flag.NewFlagSet("test", flag.ExitOnError)
	fs.SetOutput(os.Stdout)
	fs.Var(v, "count", "Initial count (`number`)")

	// Parse. Flags will override environment variables.
	es.Parse()
	fs.Parse(nil)

	// Print UsageString of both
	es.PrintDefaults()
	fs.PrintDefaults()

	// Get value:
	fmt.Printf("Count: %v", *i)

}
Output:

   A number
    	Initial count (number) (default -1)
  -count number
    	Initial count (number) (default -1)
Count: 15

func NewValueVar

func NewValueVar[T Constraint](p *T, d T) Value

NewValueVar returns a Value for the given pointer and default value.

func ValueFromFlag

func ValueFromFlag(f flag.Value, defValue string) Value

ValueFromFlag converts a flag.Value to a Value.

func ValueFromGetter

func ValueFromGetter(f flag.Getter, defValue string) Value

ValueFromGetter converts a flag.Getter to a Value.

Jump to

Keyboard shortcuts

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