kflags

package
v0.0.0-...-66343a0 Latest Latest
Warning

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

Go to latest
Published: May 14, 2024 License: BSD-3-Clause, BSD-3-Clause Imports: 10 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

The set of remappers used to turn flags into environment variable names.

By default, the map augmenter looks up the literal flag name and a camel case version of it.

For example, if the 'retry-number' flag is to be filled, 'retry-number' and 'RetryNumber' are both looked up in the supplied map.

View Source
var ToCamel = regexp.MustCompile(`[^a-zA-Z0-9]`)

Regex defining which characters are considered separators when CamelRewriting.

View Source
var ToUnderscore = regexp.MustCompile(`[^a-zA-Z0-9]`)

Regex defining which characters should be replaced with _ by UnderscoreRewrite.

View Source
var UppercaseRewrite = strings.ToUpper

UppercaseRewrite is a simple VarRewriter that upper cases everything.

Functions

func CamelRewrite

func CamelRewrite(el string) string

CamelRewrite is a simple VarRewriter that turns a string like "max-network-latency" or "max_network_latency" in camel case, MaxNetworkLatency.

func PopulateDefaults

func PopulateDefaults(set *flag.FlagSet, resolvers ...Augmenter) error

PopulateDefaults will provide the defaults of your flags.

It should be called before `flag.Parse()` to provide defaults to your flags.

If you don't use FlagSet explicitly, you can just pass flag.CommandLine.

For example, an application reading flags from the environment may use:

var server = flag.String("server", "127.0.0.1", "server to connect to")
func main(...) {
  kflags.PopulateDefaults(flag.CommandLine, kflags.NewEnvAugmenter())
  [...]

  flag.Parse()

func SetContent

func SetContent(fl flag.Value, name string, value []byte) (string, error)

SetContent is a utility function Augmenters can use to set the value of a flag.

Let's say you have a flag that takes the path of a file, to load it. At run time, the value of the flag is the content of the file, rather than its path.

SetContent will check to see if the flag implements the ContentValue interface, and set the content as necessary.

The first string returned provides a suitable default value to show the user.

func UnderscoreRewrite

func UnderscoreRewrite(el string) string

UnderscoreRewrite is a simple VarRewriter that turns unknown chars into _.

It simply replaces all invalid characters (defined by the ToUnderscore regexp) with underscores.

Types

type AssetAugmenter

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

func NewAssetAugmenter

func NewAssetAugmenter(log logger.Logger, forns string, assets map[string][]byte) *AssetAugmenter

NewAssetAugmenter creates a new AssetAugmenter.

An asset-resolver looks up configuration flags in a built in dict where the key is the name of a file, and the value is what should be passed to the flag. Extensions of the key are ignored.

For example, let's say you have a dict containing:

"/etc/astore/astore-server.flag.txt": "127.0.0.1"

Now let's say you have a binary that takes a --astore-server or -astore-server flag.

When invoked, the returned AssetAugmenter will set the default value of --astore-server to 127.0.0.1.

This is extremely powerful when combined to a library to embed files at build time, like the go_embed_data target of bazel.

func (*AssetAugmenter) Done

func (ar *AssetAugmenter) Done() error

Done implements the Done interface of Augmenter.

func (*AssetAugmenter) VisitCommand

func (ar *AssetAugmenter) VisitCommand(ns string, command Command) (bool, error)

VisitCommand implements the VisitCommand interface of Augmenter. In AssetAugmenter, it is a noop.

func (*AssetAugmenter) VisitFlag

func (ar *AssetAugmenter) VisitFlag(reqns string, fl Flag) (bool, error)

VisitFlag implements the VisitFlag interface of Augmenter.

If the namespace matches the one configured with the constructor, VisitFlag will look for an asset named after the flag name.

If one is found, the content of the flag is set to that of the asset.

type Augmenter

type Augmenter interface {
	// VisitCommand is used to ask the Augmenter to configure a command.
	//
	// namespace is a string that identifies the parent command this command is defined on.
	// It is generally a string like "enkit.astore" identifying the "astore" subcommand of "enkit".
	//
	// Note that the caller will immediately call VisitFlag and other VisitCommand after this
	// command returns, without waiting for Done().
	VisitCommand(namespace string, command Command) (bool, error)

	// VisitFlag is used to ask the Augmenter to configure a flag.
	//
	// namespace is a string that identifies the command the flag is defined on.
	// It is generally a string like "enkit.astore" identifying the "astore" subcommand of "enkit".
	VisitFlag(namespace string, flag Flag) (bool, error)

	// Waits for all the visit details to be filled in.
	//
	// After Done() is invoked, the caller can assume that the flags and commands will no longer
	// be touched by the augmenter.
	Done() error
}

An Augmenter is an object capable of providing default flag values, disable, add or modify sub commands of a generic CLI.

Typically, it is invoked by a library that iterates over the flags of a command, and the existing commands defined.

VisitFlag is invoked for each flag, with the method implementation allowed to call arbitrary methods on the flag.

VisitCommands is invoked for each sub-command, with the method implementation allowed to call arbitrary methods on the command.

At the end of the walk, Done is called.

The user of Augmenter must assume that any of the pointers passed to the agumenter may be used until the point that Done() is invoked.

Some resolvers may, for example, accumulate all the required flags to determine the value to lookup in a database with a single query.

Concurrent access to the flag or command by the resolver is not allowed. The resolver must ensure that access to a given flag object is serialized.

type ByteFileFlag

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

func NewByteFileFlag

func NewByteFileFlag(destination *[]byte, defaultFile string, mods ...ByteFileModifier) *ByteFileFlag

NewByteFileFlag creates a flag that reads a file into a byte array.

The flag value specified by the user on the command line is a path, a string. But the result of storing a value in the flag is that a file is read from disk, and stored in the specified array.

destination is the target byte array. defaultFile is the path of the default file to read. Empty means no file.

Note that due to how the flag library works in golang, if a default file is specified, the library will attempt to load it as soon as the flag is defined.

The ByteFileFlag object implements both the flag.Value and pflag.Value interface, so it should be usable directly both as a golang flag, and as a pflag.

func (*ByteFileFlag) Error

func (bf *ByteFileFlag) Error() error

func (*ByteFileFlag) Get

func (bf *ByteFileFlag) Get() interface{}

func (*ByteFileFlag) Set

func (bf *ByteFileFlag) Set(value string) error

func (*ByteFileFlag) SetContent

func (bf *ByteFileFlag) SetContent(name string, content []byte) error

func (*ByteFileFlag) String

func (bf *ByteFileFlag) String() string

func (*ByteFileFlag) Type

func (bf *ByteFileFlag) Type() string

type ByteFileModifier

type ByteFileModifier func(*ByteFileFlag)

func WithError

func WithError(err *error) ByteFileModifier

func WithFilename

func WithFilename(filename *string) ByteFileModifier

type Command

type Command interface {
	Name() string
	Hide(bool)
}

Command represents a command line command.

type CommandAction

type CommandAction func(flags []FlagArg, args []string) error

type CommandDefinition

type CommandDefinition struct {
	Name    string
	Use     string
	Short   string
	Long    string
	Example string

	Aliases []string
}

type Commander

type Commander interface {
	Command
	AddCommand(def CommandDefinition, fl []FlagDefinition, action CommandAction) error
}

Commander is a Command that is capable of having subcommands.

type Consumer

type Consumer interface {
	Register(fs FlagSet, prefix string)
}

Consumer is any object that can take flags, and provides a common method to register flags.

type ContentValue

type ContentValue interface {
	SetContent(origin string, content []byte) error
}

All flags have an associated Value: a boolean, a string, an integer, ...

This is implemented by creating an object satisfying the flag.Value or pflag.Value interface, capable of converting a string passed via flags (--int-value="31") into the actualy target type.

Normally, the string passed on the command line is directly converted into the target type. Eg, in the example above, the string "31" is converted into the integer 31, and stored into the pointer supplied via IntVar.

This library defines flags that do not convert directly into the target type. For example, the ByteFile type creates a parameter that contains the path of a file name, but actually stores the byte content of the file.

Any flag that provides a level of indirection should implement the ContentValue interface. In this case:

  • the normal Set(string) would be used to set the value of the flag, which represents the pointer, where to read the real value.
  • the new SetContent(string) would be used to set the content of the flag, the value that the flag would store in the target destination.

type EnvAugmenter

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

func NewEnvAugmenter

func NewEnvAugmenter(mods ...EnvModifier) *EnvAugmenter

NewEnvAugmenter creates a new EnvAugmenter.

An EnvAugmenter is an object capable of looking up environment variables to pre-populate flag defaults, or change the behavior of your CLI.

The supplied prefix and EnvModifier determine how the lookup is performed.

For example, let's say your CLI expects a flag named 'path', and a prefix of 'en' was set, without using WithMangler.

The DefaultEnvRemap will be used to determine that a variable named EN_PATH needs to be looked up in the environment.

func (*EnvAugmenter) Done

func (ar *EnvAugmenter) Done() error

Done implements the Done interface of Augmenter. For the EnvAugmenter, it is a noop.

func (*EnvAugmenter) VisitCommand

func (er *EnvAugmenter) VisitCommand(reqns string, command Command) (bool, error)

VisitCommand implements the VisitCommand interface of Augmenter. For the EnvAugmenter, it is a noop.

func (*EnvAugmenter) VisitFlag

func (er *EnvAugmenter) VisitFlag(reqns string, fl Flag) (bool, error)

VisitFlag implements the VisitFlag interface of Augmenter.

VisitFlag looks for an environment variable named after the configured prefix, the requested namespace (reqns) and the flag name.

The exact name of the environment variable is determined by the VarMangler passed using WithMangler to the constructor.

The default VarMangler is DefaultEnvRemap.

type EnvModifier

type EnvModifier func(e *EnvAugmenter)

func WithEnvMangler

func WithEnvMangler(m VarMangler) EnvModifier

WithEnvMangler specifies the VarMangler to turn the name of a flag into an the name of an environment variable.

func WithPrefixes

func WithPrefixes(prefix ...string) EnvModifier

WithPrefixes prepends the specified prefixes to the looked up environment variables.

For example, if VarMangler would normally look up the environment variable ENKIT_KFLAGS_DNS, WithPrefixes("PROD", "AMERICA") would look up PROD_AMERICA_ENKIT_KFLAGS_DNS.

type EnvModifiers

type EnvModifiers []EnvModifier

func (EnvModifiers) Apply

func (ems EnvModifiers) Apply(e *EnvAugmenter)

type ErrorHandler

type ErrorHandler func(err error) error

An ErrorHandler takes an error as input, transforms it, and returns an error as output.

This can be used, for example, to improve the readability of an error, ignore it, or turn a low level error into a higher level error (eg, "cannot open file" -> "credentials missing").

For each error, all error handlers configured are executed in the order they were originally supplied, each taking as input the output of the previous handler.

For an example, look for HandleIdentityError.

type Flag

type Flag interface {
	// Returns the name of the flag.
	Name() string
	// Sets the value of the flag.
	Set(string) error
	// Sets the content of the flag (for those flags that support it,
	// see the description of the ContentValue interface for more details)
	SetContent(string, []byte) error
}

Flag represents a command line flag.

type FlagArg

type FlagArg struct {
	*FlagDefinition
	flag.Value
}

type FlagDefinition

type FlagDefinition struct {
	Name    string
	Help    string
	Default string
}

type FlagSet

type FlagSet interface {
	BoolVar(p *bool, name string, value bool, usage string)
	DurationVar(p *time.Duration, name string, value time.Duration, usage string)
	StringVar(p *string, name string, value string, usage string)
	StringArrayVar(p *[]string, name string, value []string, usage string)
	ByteFileVar(p *[]byte, name string, defaultFile string, usage string, mods ...ByteFileModifier)
	IntVar(p *int, name string, value int, usage string)
}

FlagSet interface provides an abstraction over a cobra or golang flag set, adding features from this library.

Functions using this FlagSet interface can accept both a flag.FlagSet (from the standard golang library) and a pflag.FlagSet (from the spf13 pflag library), using the wrappers provided here and kcobra.

Use this interface only when you are writing code that a) does not need any fancy pflag feature - and could work either way with flag or pflag - and/or b) relies on features of this library.

type GoFlag

type GoFlag struct {
	*flag.Flag
}

GoFlag wraps a flag.Flag object from the go standard library and implements the Flag interface above.

func (*GoFlag) Name

func (gf *GoFlag) Name() string

func (*GoFlag) Set

func (gf *GoFlag) Set(value string) error

func (*GoFlag) SetContent

func (gf *GoFlag) SetContent(name string, data []byte) error

type GoFlagSet

type GoFlagSet struct {
	*flag.FlagSet
}

GoFlagSet wraps a flag.FlagSet from the go standard library and completes the implementation of the FlagSet interface in this module.

For example, to use the default "flag" library FlagSet:

var set kflags.FlagSet
set = &kflags.GoFlagSet{FlagSet: flag.CommandLine}

func (*GoFlagSet) ByteFileVar

func (fs *GoFlagSet) ByteFileVar(p *[]byte, name string, defaultFile string, usage string, mods ...ByteFileModifier)

func (*GoFlagSet) StringArrayVar

func (fs *GoFlagSet) StringArrayVar(p *[]string, name string, value []string, usage string)

type IdentityError

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

IdentityError is an error that indicates that there was some problem loading or using the identity and credentials of the user.

It doesn't really belong to kflags, except it's a common error returned by cli commands, and requires some special handling.

func NewIdentityError

func NewIdentityError(err error) *IdentityError

func (*IdentityError) Unwrap

func (ie *IdentityError) Unwrap() error

type Init

type Init func() error

An initialization function capable of preparing internal objects once flags have been parsed.

type MapAugmenter

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

func NewMapAugmenter

func NewMapAugmenter(args map[string]string, mods ...MapModifier) *MapAugmenter

NewMapAugmenter returns an augmenter capable of looking up flags in a map.

For example, supply a map like map["retry-number"] = "3", and the flag "retry-number" will be set to the value of 3 depending on the VarMangler configured.

func (*MapAugmenter) Done

func (ar *MapAugmenter) Done() error

Done implements the Done interface of Augmenter.

func (*MapAugmenter) VisitCommand

func (ma *MapAugmenter) VisitCommand(ns string, command Command) (bool, error)

VisitCommand implements the VisitCommand interface of Augmenter. In AssetAugmenter, it is a noop.

func (*MapAugmenter) VisitFlag

func (ma *MapAugmenter) VisitFlag(reqns string, fl Flag) (bool, error)

VisitFlag implements the VisitFlag interface of Augmenter.

type MapModifier

type MapModifier func(e *MapAugmenter)

func WithMapMangler

func WithMapMangler(m ...VarMangler) MapModifier

WithMapMangler sets the list of manglers to use to lookup the parameters in the map.

type MapModifiers

type MapModifiers []MapModifier

func (MapModifiers) Apply

func (ems MapModifiers) Apply(e *MapAugmenter)

type Populator

type Populator func(resolvers ...Augmenter) error

Populator is a function that given a set of Augmenters, it is capable of invoking them to assign default flag values.

func GoPopulator

func GoPopulator(set *flag.FlagSet) Populator

GoPopulator returns a Populator capable of walking all the flags in the specified set, and assign defaults to those flags.

type Printer

type Printer func(format string, v ...interface{})

Printer is a function capable of printing Printf like strings.

type Runner

type Runner func(FlagSet, Printer, Init)

Runner is a function capable of parsing argv according to the supplied FlagSet, log problems using the supplied Printer, initialize internal object with the parsed flags by invoking Init, and finally running the program.

type StatusError

type StatusError struct {
	Code int
	// contains filtered or unexported fields
}

Wrap errors in a StatusError to indicate a different exit value to be returned if the error causes the program to exit.

func NewStatusError

func NewStatusError(code int, err error) *StatusError

func NewStatusErrorf

func NewStatusErrorf(code int, f string, args ...interface{}) *StatusError

func (*StatusError) Unwrap

func (se *StatusError) Unwrap() error

type UsageError

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

Wrap errors in an UsageError to indicate that the problem has been caused by incorrect flags by the user, and as such, the help screen should be printed.

func NewUsageError

func NewUsageError(err error) *UsageError

func NewUsageErrorf

func NewUsageErrorf(f string, args ...interface{}) *UsageError

func (*UsageError) Unwrap

func (ue *UsageError) Unwrap() error

type VarMangler

type VarMangler func(components ...string) string

An VarMangler is a function capable of turning a set of strings in the name of a variable.

Normally, VarMangler is called with a prefix configured with a function like NewEnvAugmenter, the namespace, and the flag name. It is possible that multiple namespaces may be passed.

If the empty string is returned, the variable is not looked up. This can be used to prevent some variables from being looked up in the environment, for example.

func JoinRemap

func JoinRemap(separator string, rewriter ...VarRewriter) VarMangler

JoinRemap returns a VarMangler that joins each element after passing it through the specified rewriters.

A nil rewriter is accepted, and performs no operation.

func PrefixRemap

func PrefixRemap(mangler VarMangler, prefix ...string) VarMangler

PrefixRemap returns a VarMangler that always prepends the specified prefixes.

func SkipNamespaceRemap

func SkipNamespaceRemap(mangler VarMangler) VarMangler

SkipNamespaceRemap returns a VarMangler that ignores the namespace fragment.

type VarRewriter

type VarRewriter func(string) string

A VarRewriter is just like a VarMangler, but does not merge the strings together, and works on an element at a time.

Some VarManglers can combine multiple VarRewriters together.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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