Documentation ¶
Index ¶
- Variables
- func CamelRewrite(el string) string
- func PopulateDefaults(set *flag.FlagSet, resolvers ...Augmenter) error
- func SetContent(fl flag.Value, name string, value []byte) (string, error)
- func UnderscoreRewrite(el string) string
- type AssetAugmenter
- type Augmenter
- type ByteFileFlag
- type ByteFileModifier
- type Command
- type CommandAction
- type CommandDefinition
- type Commander
- type Consumer
- type ContentValue
- type EnvAugmenter
- type EnvModifier
- type EnvModifiers
- type ErrorHandler
- type Flag
- type FlagArg
- type FlagDefinition
- type FlagSet
- type GoFlag
- type GoFlagSet
- type IdentityError
- type Init
- type MapAugmenter
- type MapModifier
- type MapModifiers
- type Populator
- type Printer
- type Runner
- type StatusError
- type UsageError
- type VarMangler
- type VarRewriter
Constants ¶
This section is empty.
Variables ¶
var DefaultEnvRemap = JoinRemap("_", UnderscoreRewrite, UppercaseRewrite)
The set of remappers used to turn flags into environment variable names.
var DefaultVarMangler = []VarMangler{SkipNamespaceRemap(JoinRemap("")), SkipNamespaceRemap(JoinRemap("", CamelRewrite))}
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.
var ToCamel = regexp.MustCompile(`[^a-zA-Z0-9]`)
Regex defining which characters are considered separators when CamelRewriting.
var ToUnderscore = regexp.MustCompile(`[^a-zA-Z0-9]`)
Regex defining which characters should be replaced with _ by UnderscoreRewrite.
var UppercaseRewrite = strings.ToUpper
UppercaseRewrite is a simple VarRewriter that upper cases everything.
Functions ¶
func CamelRewrite ¶
CamelRewrite is a simple VarRewriter that turns a string like "max-network-latency" or "max_network_latency" in camel case, MaxNetworkLatency.
func PopulateDefaults ¶
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 ¶
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 ¶
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 ¶
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 CommandAction ¶
type CommandDefinition ¶
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 ¶
Consumer is any object that can take flags, and provides a common method to register flags.
type ContentValue ¶
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 ¶
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 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 ¶
GoFlag wraps a flag.Flag object from the go standard library and implements the Flag interface above.
type GoFlagSet ¶
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 ¶
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.
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 ¶
Populator is a function that given a set of Augmenters, it is capable of invoking them to assign default flag values.
func GoPopulator ¶
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 ¶
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 ¶
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 ¶
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.