flagr

package module
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Jun 19, 2022 License: Unlicense Imports: 11 Imported by: 0

README

flagr

Go Reference Go Report Card

A wrapper around the standard flag package that provides a more ergonomic API.

Why

The flag package works well, but the API is not very ergonomic due to the language limitations at the time it was designed.

Namely there's 2 different APIs for adding flags, we have the builtin types like int and string, and for everything else we have to resort to creating implementations of flag.Value.

This isn't bad, by any means, but it has a cumbersome consequence:

type customInt [...]

n1 := flag.Int("n1", 1234, "usage")
n2 := flag.String("n2", "asd", "usage")
var myCustomInt customInt
flag.Var(&myCustomInt, "n3", "usage")
n4 := flag.Duration("n4", 5*time.Second, "usage")
n5 := flag.Bool("n5", true, "usage")

Due to the fact that we're using a custom flag.Value we have to explicitly break apart the declaration and initialization.

This isn't the end of the world, and it's pretty much the best we could do pre 1.18, as there was no way for flag.Var to return a meaningful type. Now there is.

Flagr aims to solve this by leveraging generics:

var set flagr.Set
n1 := flagr.Add(&set, "n1", flagr.Int(1234), "usage")               // n1 is *int
n2 := flagr.Add(&set, "n2", flagr.String("asd"), "usage")           // n2 is *string
n3 := flagr.Add(&set, "n3", CustomInt(42), "usage")                 // n3 is *int64
n4 := flagr.Add(&set, "n4", flagr.Duration(5*time.Second), "usage") // n4 is *time.Duration
n5 := flagr.Add(&set, "n5", flagr.Bool(true), "usage")              // n5 is *bool

// essentially a re-implementation of flagr.Int64
func CustomInt(def int64) flagr.Getter[int64] {
    // flagr.Var is a helper function that can construct a flagr.Getter (akin to flag.Getter)
    return flagr.Var(defaultValue, func(value *int64, s string) error {
        // parse
		v, err := strconv.ParseInt(s, 0, 64)
		if err != nil {
			return err
		}

        // set
		*value = v
		return nil
	})
}

func UsingSetterFrom(def int) flagr.Getter[int] {
    // Setting a flag value means 2 things, parsing it and actually setting.
    // In cases where setting is just a simple assignment (as oposed to say, slices)
    // and we already have a function that conforms to func(string)(T, error)
    // we can leverage flagr.SetterFrom.
    return flagr.Var(42, flagr.SetterFrom(strconv.Atoi))
}

flagr.Add accepts a flagr.Getter[X], so custom types are also supported like in the standard flag package:

// counts the number of times a flag was used
type Counter struct {
	value *int
	set   bool
}

func NewCounter(defaultValue int) flagr.Getter[int] {
	return &Counter{value: &defaultValue}
}

// methods that satisfy the standard Getter interface
func (f Counter) IsBoolFlag() bool { return true }
func (f *Counter) Get() any        { return f.value }
func (f *Counter) String() string  { [...] }
func (f *Counter) Set(s string) error {
	if !f.set {
		*f.value = 0
		f.set = true
	}

	*f.value++
	return nil
}

// satisfies flagr.Getter, allowing us to decouple the flag type (a struct in this case)
// from the actual data we're interested on, the count.
func (f Counter) Val() *int { return f.value }

And using it is exactly the same as we've seen before:

count := flagr.Add(&set, "c", NewCounter(2), "c") // count is a *int

Goals

Flagr aims to be just a thin wrapper around the standard flag package.

Our goal is to clean up the API, not to add new features or change existing behaviour.

Supported types

We've taken this oportunity to add in some extra goodies like builtin slice support and a few (non external) types that are useful for most go programs like url.URL and netip.Addr.

Sure this adds a little weight but shouldn't be too much of an issue in practice, we might revisit it later.

Builtin types
  • int, []int
  • int8, []int8
  • int16, []int16
  • int32, []int32
  • int64, []int64
  • uint, []uint
  • uint16, []uint16
  • uint32, []uint32
  • uint64, []uint64
  • uint8, []uint8
  • float32, []float32
  • float64, []float64
  • complex128, []complex128
  • complex64, []complex64
  • bool, []bool
  • string, []string
Time
  • time.Duration, []time.Duration
  • time.Time, []time.Time
Networking
  • netip.Addr, []netip.Addr
  • netip.AddrPort, []netip.AddrPort
  • url.URL, []url.URL

Full documentation

Go Reference

Documentation

Overview

Pakckage flagr is a thin wrapper over the standard flag package creating a generalized API for defining flags of any type.

Example (Builtins)
package main

import (
	"errors"
	"fmt"
	"net/netip"
	"os"

	"github.com/flga/flagr"
)

func main() {
	var set flagr.Set
	// Builtin types like int, float, etc.
	a := flagr.Add(&set, "a", flagr.Int(42), "usage")

	// Slices of things, every flag provided by flagr has a slice counterpart.
	b := flagr.Add(&set, "b", flagr.Ints(1, 2, 3), "usage")

	// A bool flag has the same semantics as std/flag bools.
	c := flagr.Add(&set, "c", flagr.Bool(false), "usage")

	// One of the extra types flagr provides, along with urls, times, etc.
	d := flagr.Add(&set, "d", flagr.IPAddrPort(netip.MustParseAddrPort("127.0.0.1:8080")), "usage")

	// Same as above but allows defaults to be provided as strings, delegating parsing to flagr.
	e := flagr.Add(&set, "e", flagr.MustIPAddrPort("127.0.0.1:8080"), "usage")

	args := []string{
		"-b", "5", "-b", "6",
		"-c",
		"-d", "0.0.0.0:80",
	}
	if err := set.Parse(args); err != nil {
		if errors.Is(err, flagr.ErrHelp) {
			os.Exit(0)
		}
		os.Exit(2)
	}

	fmt.Printf("a = %v and is a %T\n", *a, a)
	fmt.Printf("b = %v and is a %T\n", *b, b)
	fmt.Printf("c = %v and is a %T\n", *c, c)
	fmt.Printf("d = %v and is a %T\n", *d, d)
	fmt.Printf("e = %v and is a %T\n", *e, e)
}
Output:

a = 42 and is a *int
b = [5 6] and is a *[]int
c = true and is a *bool
d = 0.0.0.0:80 and is a *netip.AddrPort
e = 127.0.0.1:8080 and is a *netip.AddrPort
Example (CustomTypes)
package main

import (
	"errors"
	"fmt"
	"os"

	"github.com/flga/flagr"
)

func main() {
	var set flagr.Set

	// A fully custom flagr.Getter implementation.
	a := flagr.Add(&set, "a", NewFileMode(0), "usage")

	// Another fully custom implementation.
	// Notice that while the flag type is Counter, f is a *int.
	b := flagr.Add(&set, "b", NewCounter(2), "usage")

	args := []string{
		"-a", "rw",
		"-b", "-b", "-b",
	}
	if err := set.Parse(args); err != nil {
		if errors.Is(err, flagr.ErrHelp) {
			os.Exit(0)
		}
		os.Exit(2)
	}

	fmt.Printf("a = %s and is a %T\n", a.String(), a)
	fmt.Printf("b = %v and is a %T\n", *b, b)
}

var _ flagr.Getter[FileMode] = new(FileMode)

// a fully custom implementation of flagr.Getter
type FileMode byte

const (
	Read FileMode = 1 << iota
	Write
)

func NewFileMode(defaultValue FileMode) flagr.Getter[FileMode] {
	return &defaultValue
}

func (f *FileMode) Get() any {
	return f
}

func (f *FileMode) Set(s string) error {
	for _, rune := range s {
		switch rune {
		case 'r':
			*f |= Read
		case 'w':
			*f |= Write
		default:
			return fmt.Errorf("invalid file mode %q", s)
		}
	}
	return nil
}

func (f *FileMode) String() string {
	if f == nil {
		return ""
	}

	var ret string
	if *f&Read > 0 {
		ret += "r"
	}
	if *f&Write > 0 {
		ret += "w"
	}

	return ret
}

func (f *FileMode) IsBoolFlag() bool {
	return false
}

func (f *FileMode) Val() *FileMode {
	return f
}

// a fully custom implementation of flagr.Getter
type Counter struct {
	value *int
	set   bool
}

func NewCounter(defaultValue int) flagr.Getter[int] {
	return &Counter{value: &defaultValue}
}

func (f *Counter) Get() any {
	return f.value
}

func (f *Counter) Set(s string) error {
	if !f.set {
		*f.value = 0
		f.set = true
	}

	*f.value++
	return nil
}

func (f *Counter) String() string {
	if f == nil || f.value == nil {
		return ""
	}

	return fmt.Sprint(f.value)
}

func (f Counter) Val() *int {
	return f.value // this is what we care about, the wrapper struct is just an implementation constraint
}

func (f Counter) IsBoolFlag() bool {
	return true
}
Output:

a = rw and is a *flagr_test.FileMode
b = 3 and is a *int
Example (Slices)
package main

import (
	"errors"
	"fmt"
	"net/url"
	"os"
	"strconv"

	"github.com/flga/flagr"
)

func main() {
	var set flagr.Set

	// We can use flagr.Slice to create repeatable flags. Custom slice types are supported.
	type bools []bool
	a := flagr.Add[bools](&set, "a", flagr.Slice(bools{true, false, true}, strconv.ParseBool), "usage")

	// Making use of MustSlice so that we can pass default values as strings and delegate the parsing to flagr.
	// Makes it much more comfortable to use things that have to be parsed, like urls.
	b := flagr.Add[[]*url.URL](&set, "b", flagr.MustSlice([]string{"https://a.com", "https://b.com"}, url.Parse), "usage")

	// Using helper functions allows us to have cleaner signatures (type inference is still a little wonky)
	c := flagr.Add(&set, "c", Urls("https://a.com", "https://b.com"), "usage")

	args := []string{
		"-a", "-a", // std/flag bool semantics apply
		"-b", "https://c.com", "-b", "https://d.com",
	}
	if err := set.Parse(args); err != nil {
		if errors.Is(err, flagr.ErrHelp) {
			os.Exit(0)
		}
		os.Exit(2)
	}

	fmt.Printf("a = %v and is a %T\n", *a, a)
	fmt.Printf("b = %v and is a %T\n", *b, b)
	fmt.Printf("c = %v and is a %T\n", *c, c)
}

func Urls(defaults ...string) flagr.Getter[[]*url.URL] {
	return flagr.MustSlice(defaults, url.Parse)
}
Output:

a = [true true] and is a *flagr_test.bools
b = [https://c.com https://d.com] and is a *[]*url.URL
c = [https://a.com https://b.com] and is a *[]*url.URL
Example (Var)
package main

import (
	"errors"
	"fmt"
	"net/url"
	"os"
	"strconv"

	"github.com/flga/flagr"
)

func main() {
	var set flagr.Set

	// Using flagr.Var to reimplement flagr.Int64.
	a := flagr.Add(&set, "a", flagr.Var(42, func(value *int64, s string) error {
		v, err := strconv.ParseInt(s, 0, 64)
		if err != nil {
			return err
		}
		*value = v
		return nil
	}), "usage")

	// Using helper functions allows us to have cleaner signatures
	b := flagr.Add(&set, "b", CustomInt64(42), "usage")

	// Making use of flagr.SetterFrom when setting a value is just a simple assignment (like above).
	// Also, if the underlying type is a ~bool std/flag bool semantics apply.
	c := flagr.Add(&set, "c", flagr.Var(false, flagr.SetterFrom(strconv.ParseBool)), "usage")

	// Making use of MustVar so that we can pass default values as strings and delegate the parsing to flagr.
	// Makes it much more comfortable to use things that have to be parsed, like urls.
	d := flagr.Add[*url.URL](&set, "d", flagr.MustVar("http://a.com", flagr.SetterFrom(url.Parse)), "usage")

	args := []string{
		"-a", "1",
		"-c", // std/flag bool semantics apply
		"-d", "http://b.com",
	}
	if err := set.Parse(args); err != nil {
		if errors.Is(err, flagr.ErrHelp) {
			os.Exit(0)
		}
		os.Exit(2)
	}

	fmt.Printf("a = %v and is a %T\n", *a, a)
	fmt.Printf("b = %v and is a %T\n", *b, b)
	fmt.Printf("c = %v and is a %T\n", *c, c)
	fmt.Printf("d = %v and is a %T\n", *d, d)
}

// an implementation equivalent to flagr.Int64
func CustomInt64(defaultValue int64) flagr.Getter[int64] {
	return flagr.Var(defaultValue, func(value *int64, s string) error {
		v, err := strconv.ParseInt(s, 0, 64)
		if err != nil {
			return err
		}
		*value = v
		return nil
	})
}
Output:

a = 1 and is a *int64
b = 42 and is a *int64
c = true and is a *bool
d = http://b.com and is a **url.URL

Index

Examples

Constants

View Source
const (
	ContinueOnError = stdflag.ContinueOnError // Return a descriptive error.
	ExitOnError     = stdflag.ExitOnError     // Call os.Exit(2) or for -h/-help Exit(0).
	PanicOnError    = stdflag.PanicOnError    // Call panic with a descriptive error.
)

These constants cause Set.Parse to behave as described if the parse fails.

Variables

View Source
var ErrHelp = stdflag.ErrHelp

ErrHelp is the error returned if the -help or -h flag is invoked but no such flag is defined.

Functions

func Add

func Add[T any](set *Set, name string, value Getter[T], usage string) *T

Add creates a new flag on the given Set, returning the underlying value of the provided Getter.

func MustSlice

func MustSlice[T any](defaults []string, parse ValParser[T]) *slice[T, []T]

MustSlice, returns a Getter[[]T] with the given default value, but allows the default values to be provided as a strings. Unlike Slice custom slice implementations are not supported. This could change in the future.

When calling MustSlice each value will be parsed with the given Parser, any error will cause MustSlice to panic.

If the same flag is provided multiple times, the result will be accumulated in a []T.

func MustVar

func MustVar[T any](defaultValue string, setter ValSetter[T]) value[T]

MustVar, like Var, returns a Getter[T] with the given default value and Setter, but allows the default value to be provided as a string.

When calling MustVar the given setter will be used to convert the default value, into T. If it returns an error, MustVar panics.

Setter is called to parse the provided value and assign it to the underlying value.

func Slice

func Slice[T any, S ~[]T](defaultValue S, parse ValParser[T]) *slice[T, S]

Slice returns a Getter[S] with the given default value.

If the same flag is provided multiple times, the result will be accumulated in S.

The value will be initialized with a shallow copy of defaultValue.

func UnquoteUsage added in v0.2.0

func UnquoteUsage(flag *Flag) (name string, usage string)

UnquoteUsage extracts a back-quoted name from the usage string for a flag 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 an educated guess of the type of the flag's value, or the empty string if the flag is boolean.

Types

type ErrorHandling

type ErrorHandling = stdflag.ErrorHandling

ErrorHandling defines how Set.Parse behaves if the parse fails.

type Flag

type Flag = stdflag.Flag

A Flag represents the state of a flag.

type Getter

type Getter[T any] interface {
	stdflag.Getter
	IsBoolFlag() bool
	Val() *T
}

Getter is any type that satisfies flag.Getter and provides a new method Val() that returns a pointer to the actual value of type.

This allows constructing a flag.Getter such that its type and the type of its value can (but don't need too) be diferent.

In scenarios where the implementation is simple both types should be the same, such as custom builtin type, for example.

In scenarios where the implementation is complex, we might want to use different types.

Let's consider a Getter implementation that counts the times a flag has been provided.

It could be described as a simple integer, but this is insufficient for a correct implementation given that we would need to know, somehow, if the current value is the default value and we should reset it, or if we can just increment the count.

Since we need to keep track of that extra state, we'd need to use a struct to implement Getter, but because the type that implements a Getter and the type that a Getter returns as its value need not be the same, we can define a struct MyCounter that implements a Getter[int], which is the actual value the caller is interested in. The fact that we had to use a struct is an implementation detail.

You can look at the CustomTypes example for a concrete implementation.

func Bool

func Bool(defaultValue bool) Getter[bool]

Bool returns a Getter that can parse values of type bool.

func Bools

func Bools(defaults ...bool) Getter[[]bool]

Bools returns a Getter that can parse and accumulate values of type bool.

func Complex128

func Complex128(defaultValue complex128) Getter[complex128]

Complex128 returns a Getter that can parse values of type complex128.

func Complex128s

func Complex128s(defaults ...complex128) Getter[[]complex128]

Complex128s returns a Getter that can parse and accumulate values of type complex128.

func Complex64

func Complex64(defaultValue complex64) Getter[complex64]

Complex64 returns a Getter that can parse values of type complex64.

func Complex64s

func Complex64s(defaults ...complex64) Getter[[]complex64]

Complex64s returns a Getter that can parse and accumulate values of type complex64.

func Duration

func Duration(defaultValue time.Duration) Getter[time.Duration]

Duration returns a Getter that can parse values of type time.Duration.

func Durations

func Durations(defaults ...time.Duration) Getter[[]time.Duration]

Durations returns a Getter that can parse and accumulate values of type time.Duration.

func Float32

func Float32(defaultValue float32) Getter[float32]

Float32 returns a Getter that can parse values of type float32.

func Float32s

func Float32s(defaults ...float32) Getter[[]float32]

Float32s returns a Getter that can parse and accumulate values of type float32.

func Float64

func Float64(defaultValue float64) Getter[float64]

Float64 returns a Getter that can parse values of type float64.

func Float64s

func Float64s(defaults ...float64) Getter[[]float64]

Float64s returns a Getter that can parse and accumulate values of type float64.

func IPAddr

func IPAddr(defaultValue netip.Addr) Getter[netip.Addr]

IPAddr returns a Getter that can parse values of type netip.Addr.

func IPAddrPort

func IPAddrPort(defaultValue netip.AddrPort) Getter[netip.AddrPort]

IPAddrPort returns a Getter that can parse values of type netip.AddrPort.

func IPAddrPorts

func IPAddrPorts(defaults ...netip.AddrPort) Getter[[]netip.AddrPort]

IPAddrPorts returns a Getter that can parse and accumulate values of type netip.AddrPort.

func IPAddrs

func IPAddrs(defaults ...netip.Addr) Getter[[]netip.Addr]

IPAddrs returns a Getter that can parse and accumulate values of type netip.Addr.

func Int

func Int(defaultValue int) Getter[int]

Int returns a Getter that can parse values of type int.

func Int16

func Int16(defaultValue int16) Getter[int16]

Int16 returns a Getter that can parse values of type int16.

func Int16s

func Int16s(defaults ...int16) Getter[[]int16]

Int16s returns a Getter that can parse and accumulate values of type int16.

func Int32

func Int32(defaultValue int32) Getter[int32]

Int32 returns a Getter that can parse values of type int32.

func Int32s

func Int32s(defaults ...int32) Getter[[]int32]

Int32s returns a Getter that can parse and accumulate values of type int32.

func Int64

func Int64(defaultValue int64) Getter[int64]

Int64 returns a Getter that can parse values of type int64.

func Int64s

func Int64s(defaults ...int64) Getter[[]int64]

Int64s returns a Getter that can parse and accumulate values of type int64.

func Int8

func Int8(defaultValue int8) Getter[int8]

Int8 returns a Getter that can parse values of type int8.

func Int8s

func Int8s(defaults ...int8) Getter[[]int8]

Int8s returns a Getter that can parse and accumulate values of type int8.

func Ints

func Ints(defaults ...int) Getter[[]int]

Ints returns a Getter that can parse and accumulate values of type int.

func MustIPAddr

func MustIPAddr(defaultValue string) Getter[netip.Addr]

MustIPAddr, like IPAddr, returns a Getter that can parse values of type netip.Addr, but allowing the default value to be provided as a string. It panics if the given string cannot be parsed as netip.Addr.

func MustIPAddrPort

func MustIPAddrPort(defaultValue string) Getter[netip.AddrPort]

MustIPAddrPort, like IPAddrPort, returns a Getter that can parse values of type netip.AddrPort, but allowing the default value to be provided as a string. It panics if the given string cannot be parsed as netip.AddrPort.

func MustIPAddrPorts

func MustIPAddrPorts(defaults ...string) Getter[[]netip.AddrPort]

MustIPAddrPorts, like IPAddrPorts, returns a Getter that can parse values of type netip.AddrPort and accumulate them, but allowing the default values to be provided as strings. It panics if any given string cannot be parsed as netip.AddrPort.

func MustIPAddrs

func MustIPAddrs(defaults ...string) Getter[[]netip.Addr]

MustIPAddrs, like IPAddrs, returns a Getter that can parse values of type netip.Addr and accumulate them, but allowing the default values to be provided as strings. It panics if any given string cannot be parsed as netip.Addr.

func MustTime

func MustTime(layout string, defaultValue string) Getter[time.Time]

MustTime, like Time, returns a Getter that can parse values of type time.Time, but allowing the default value to be provided as a string. It panics if the given string cannot be parsed as time.Time.

func MustTimes

func MustTimes(layout string, defaults ...string) Getter[[]time.Time]

MustTimes, like Times, returns a Getter that can parse values of type time.Time and accumulate them, but allowing the default values to be provided as strings. It panics if any given string cannot be parsed as time.Time.

func MustURL

func MustURL(defaultValue string) Getter[*url.URL]

MustURL, like URL, returns a Getter that can parse values of type *url.URL, but allowing the default value to be provided as a string. It panics if the given string cannot be parsed as *url.URL.

func MustURLs

func MustURLs(defaults ...string) Getter[[]*url.URL]

MustURLs, like URLs, returns a Getter that can parse values of type *url.URL and accumulate them, but allowing the default values to be provided as strings. It panics if any given string cannot be parsed as *url.URL.

func String

func String(defaultValue string) Getter[string]

String returns a Getter that can parse values of type string.

func Strings

func Strings(defaults ...string) Getter[[]string]

Strings returns a Getter that can parse and accumulate values of type string.

func Time

func Time(layout string, defaultValue time.Time) Getter[time.Time]

Time returns a Getter that can parse values of type time.Time.

func Times

func Times(layout string, defaults ...time.Time) Getter[[]time.Time]

Times returns a Getter that can parse and accumulate values of type time.Time.

func URL

func URL(defaultValue *url.URL) Getter[*url.URL]

URL returns a Getter that can parse values of type *url.URL.

func URLs

func URLs(defaults ...*url.URL) Getter[[]*url.URL]

URLs returns a Getter that can parse and accumulate values of type *url.URL.

func Uint

func Uint(defaultValue uint) Getter[uint]

Uint returns a Getter that can parse values of type uint.

func Uint16

func Uint16(defaultValue uint16) Getter[uint16]

Uint16 returns a Getter that can parse values of type uint16.

func Uint16s

func Uint16s(defaults ...uint16) Getter[[]uint16]

Uint16s returns a Getter that can parse and accumulate values of type uint16.

func Uint32

func Uint32(defaultValue uint32) Getter[uint32]

Uint32 returns a Getter that can parse values of type uint32.

func Uint32s

func Uint32s(defaults ...uint32) Getter[[]uint32]

Uint32s returns a Getter that can parse and accumulate values of type uint32.

func Uint64

func Uint64(defaultValue uint64) Getter[uint64]

Uint64 returns a Getter that can parse values of type uint64.

func Uint64s

func Uint64s(defaults ...uint64) Getter[[]uint64]

Uint64s returns a Getter that can parse and accumulate values of type uint64.

func Uint8

func Uint8(defaultValue uint8) Getter[uint8]

Uint8 returns a Getter that can parse values of type uint8.

func Uint8s

func Uint8s(defaults ...uint8) Getter[[]uint8]

Uint8s returns a Getter that can parse and accumulate values of type uint8.

func Uints

func Uints(defaults ...uint) Getter[[]uint]

Uints returns a Getter that can parse and accumulate values of type uint.

func Var

func Var[T any](val T, setter ValSetter[T]) Getter[T]

Var returns a Getter[T] with the given default value and Setter.

Setter is called to parse the provided value and assign it to the underlying value.

type Parser

type Parser func(*Set) error

Parser is any function that can set flag values, these are optionally used in Parse to populate values from different sources (such as environment values).

type Set

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

A Set represents a set of defined flags. The zero value of a Set has no name and has ContinueOnError error handling.

Flag names must be unique within a Set. An attempt to define a flag whose name is already in use will cause a panic.

func NewSet

func NewSet(name string, errorHandling ErrorHandling) *Set

NewSet returns a new, empty flag set with the specified name and error handling property. If the name is not empty, it will be printed in the default usage message and in error messages.

func (*Set) Arg

func (set *Set) Arg(i int) string

Arg returns the i'th argument. Arg(0) is the first remaining argument after flags have been processed. Arg returns an empty string if the requested element does not exist.

func (*Set) Args

func (set *Set) Args() []string

Args returns the non-flag arguments.

func (*Set) ErrorHandling

func (set *Set) ErrorHandling() ErrorHandling

ErrorHandling returns the error handling behavior of the flag set.

func (*Set) Init

func (set *Set) Init(name string, errorHandling ErrorHandling)

Init sets the name and error handling property for a flag set. By default, the zero Set uses an empty name and the ContinueOnError error handling policy.

func (*Set) Lookup

func (set *Set) Lookup(name string) *Flag

Lookup returns the Flag structure of the named flag, returning nil if none exists.

func (*Set) NArg

func (set *Set) NArg() int

NArg is the number of arguments remaining after flags have been processed.

func (*Set) NFlag

func (set *Set) NFlag() int

NFlag returns the number of flags that have been set.

func (*Set) Name

func (set *Set) Name() string

Name returns the name of the flag set.

func (*Set) Output

func (set *Set) Output() io.Writer

Output returns the destination for usage and error messages. os.Stderr is returned if output was not set or was set to nil.

func (*Set) Parse

func (set *Set) Parse(arguments []string, extraParsers ...Parser) error

Parse parses flag definitions from the argument list, which should not include the command name. Must be called after all flags in the Set are defined and before flags are accessed by the program. The return value will be ErrHelp if -help or -h were set but not defined.

After parsing the program arguments, it will call each extraParser, in the order they were provided. If any parser fails Parse will return an error. Extra parsers are only allowed to set flags that have not been set previously, either by the program arguments or any other parser that was called before.

This enables you to create a cascade of configuration sources with the precedence you want.

In this example, we call Parse in such way that flags have priority over everything, any flag that was not set explicitly may be set by the env parser, any flag that was not set either by the program arguments or the env parser may be set by the config file parser. If you switch the order of env.Parser() and file.Parser() precedence will change accordingly.

set.Parse(
	args,          // has precedence over env and cfg file
	env.Parser(),  // has precedence over cfg file
	file.Parser(), // can only set flags that were not set previously
)

func (*Set) Parsed

func (set *Set) Parsed() bool

Parsed reports whether set.Parse has been called.

func (*Set) PrintDefaults

func (set *Set) PrintDefaults()

PrintDefaults prints, to standard error unless configured otherwise, the default values of all defined command-line flags in the set. See the documentation for the global function PrintDefaults for more information.

func (*Set) PrintValues added in v0.3.0

func (set *Set) PrintValues()

PrintValues works like PrintDefaults, but it prints the current value for every flag, annotated with the source of the value.

It is meant as a debugging utility to troubleshoot value propagation when using multiple sources for flag values (such as environment and config files).

func (*Set) Set

func (set *Set) Set(src Source, name, value string) error

Set sets the value of the named flag, annotating it with the given source.

func (*Set) SetOutput

func (set *Set) SetOutput(output io.Writer)

SetOutput sets the destination for usage and error messages. If output is nil, os.Stderr is used.

func (*Set) SetUsage added in v0.2.0

func (set *Set) SetUsage(usage func())

SetUsage overrides the Set's usage func.

func (*Set) Usage added in v0.2.0

func (set *Set) Usage()

Usage invokes the usage function provided with SetUsage.

func (*Set) Visit

func (set *Set) Visit(fn func(*Flag) error) error

Visit visits the flags in lexicographical order, calling fn for each. It visits only those flags that have been set. It will stop walking if the fn returns an error.

func (*Set) VisitAll

func (set *Set) VisitAll(fn func(*Flag) error) error

VisitAll visits the flags in lexicographical order, calling fn for each. It visits all flags, even those not set. It will stop walking if the fn returns an error.

func (*Set) VisitRemaining added in v0.3.0

func (set *Set) VisitRemaining(fn func(*Flag) error) error

VisitRemaining visits the flags in lexicographical order, calling fn for each. It visits only those flags that have not yet been set. It will stop walking if the fn returns an error.

type Source added in v0.3.0

type Source string

Source identifies who set the value for a given flag. Used for dumping the current config with source information.

const (
	SourceDefaultVal Source = "default"
	SourceFlags      Source = "flags"
)

List of standard sources, other packages may define their own.

type ValParser added in v0.3.0

type ValParser[T any] func(string) (T, error)

ValParser is a func that parses a string into T.

type ValSetter added in v0.3.0

type ValSetter[T any] func(*T, string) error

ValSetter is a function that can, given a string, construct a meaningful value and assign it to *T.

func SetterFrom

func SetterFrom[T any](parser ValParser[T]) ValSetter[T]

Setter from returns a Setter that assigns into *T the result of Parser[T].

Directories

Path Synopsis
Package env provides a flagr.Parser that is able to read environment variables (and .env files) and set the appropriate flags.
Package env provides a flagr.Parser that is able to read environment variables (and .env files) and set the appropriate flags.
Package file provides a flagr.Parser that is able to read config files and set the appropriate flags.
Package file provides a flagr.Parser that is able to read config files and set the appropriate flags.
internal

Jump to

Keyboard shortcuts

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