flags

package module
v0.9.0 Latest Latest
Warning

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

Go to latest
Published: Jan 2, 2023 License: BSD-3-Clause Imports: 14 Imported by: 1

README


Flags

Generate cobra commands from structs

jessevdk/go-flags and octago/sflags compliant tags.

Enhanced with advanced related CLI functionality, at minimum cost.

Github Actions (workflows) Go module version GoDoc reference Go Report Card codecov

Summary

The flags library allows to declare cobra CLI commands, flags and positional arguments from structs and field tags. It originally aimed to enhance go-flags, but ended up shifting its approach in order to leverage the widely used and battle-tested cobra CLI library. In addition, it provides other generators leveraging the carapace completion engine, thus allowing for very powerful yet simple completion and as-you-type usage generation for the commands, flags and positional arguments.

In short, the main purpose of this library is to let users focus on writing programs. It requires very little time and focus spent on declaring CLI interface specs (commands, flags, groups of flags/commands) and associated functionality (completions and validations), and then generates powerful and ready to use CLI programs.

Features

Commands, flags and positional arguments

  • Easily declare commands, flags, and positional arguments through struct tags.
  • Various ways to structure the command trees in groups (tagged, or encapsulated in structs).
  • Almost entirely retrocompatible with go-flags, with a ported and enlarged test suite.
  • Advanced and versatile positional arguments declaration, with automatic binding to cobra.Args.
  • Large array of native types supported as flags or positional arguments.
  • Easily declare validations on command flags or positional arguments, with go-validator tags.
  • Generate advanced completions with the carapace completion engine in a single call.
  • Implement completers on positional/flag types, or declare builtin completers via struct tags.
  • Generated completions include commands/flags groups, descriptions, usage strings.
  • Live validation of command-line input with completers running flags' validations.
  • All of these features, cross-platform and cross-shell, almost for free.

Documentation

  • A good way to introduce you to this library is to install and use the example application binary. This example application will give you a taste of the behavior and supported features.
  • The generation package flags has a godoc file with all the valid tags for each component (commands/groups/flags/positionals), along with some notes and advices. This is so that you can quickly get access to those from your editor when writing commands and functionality.
  • Another godoc file provides quick access to global parsing options (for global behavior, validators, etc) located in the root package of this library. Both godoc files will be merged.
  • Along with the above, the following is the table of contents of the wiki documentation:

Development

Coming from other libraries

Status

This library is currently in a pre-release candidate state, for several reasons:

  • It has not been widely tested, and some features/enhancements remain to be done.
  • There might be bugs, or behavior inconsistencies that I might have missed.
  • The codebase is not huge, but significant nonetheless. I aimed to write it as structured and cleanly as possible.

Please open a PR or an issue if you wish to bring enhancements to it. For newer features, please consider if there is a large number of people who might benefit from it, or if it has a chance of impairing on future development. If everything is fine, please propose ! Other contributions, as well as bug fixes and reviews are also welcome.

Credits

  • This library is heavily based on octago/sflags code (it is actually forked from it since most of its code was needed). The flags generation is almost entirely his, and this library would not be as nearly as powerful without it. He should also be credited for 99% of this library's 99% coverage rate. It is also the inspiration for the trajectory this project has taken, which originally would just enhance go-flags.
  • The go-flags is probably the most widely used reflection-based CLI library. While it will be hard to find a lot of similarities with this project's codebase, the internal logic for scanning arbitrary structures draws almost all of its inspiration out of this project.
  • The completion engine carapace, a fantastic library for providing cross-shell, multi-command CLI completion with hundreds of different system completers. The flags project makes use of it for generation the completers for the command structure.

Documentation

Overview

Package flags generates CLI application commands/flags by parsing structures.

Package flags is the root package of the `github.com/reeflective/flags` library.

If you are searching for the list of valid tags to use on structs for specifying commands/flags specs, check https://github.com/reeflective/flags/gen/flags/flags.go.

1) Importing the various packages -----------------------------------------------------

This file gives a list of the various global parsing options that can be passed to the `Generate()` entrypoint function in the `gen/flags` package. Below is an example of how you want to import this package and use its options:

package main

import (

"github.com/reeflective/flags/example/commands"

"github.com/reeflective/flags"
genflags "github.com/reeflective/flags/gen/flags"

"github.com/reeflective/flags/validator"
"github.com/reeflective/flags/gen/completions"

)

func main() {
    var opts []flags.OptFunc

    opts = append(opts, flags.Validator(validator.New()))

    rootData := &commands.Root{}
    rootCmd := genflags.Generate(rootData, opts...)

    comps, _ := completions.Generate(rootCmd, rootData, nil)
}

2) Global parsing options (base) ------------------------------------------------------

Most of the options below are inherited from github.com/octago/sflags, with some added.

DescTag sets custom description tag. It is "desc" by default. func DescTag(val string)

FlagTag sets custom flag tag. It is "flag" be default. func FlagTag(val string)

Prefix sets prefix that will be applied for all flags (if they are not marked as ~). func Prefix(val string)

EnvPrefix sets prefix that will be applied for all environment variables (if they are not marked as ~). func EnvPrefix(val string)

FlagDivider sets custom divider for flags. It is dash by default. e.g. "flag-name". func FlagDivider(val string)

EnvDivider sets custom divider for environment variables. It is underscore by default. e.g. "ENV_NAME". func EnvDivider(val string)

Flatten set flatten option. Set to false if you don't want anonymous structure fields to be flatten. func Flatten(val bool)

ParseAll orders the parser to generate a flag for all struct fields, even if there isn't a struct tag attached to them. This is because by default the library does not considers untagged field anymore. func ParseAll()

3) Special parsing options/functions---------------------------------------------------

ValidateFunc describes a validation func, that takes string val for flag from command line, field that's associated with this flag in structure `data`. Also works for positional arguments. Should return error if validation fails.

type ValidateFunc func(val string, field reflect.StructField, data interface{}) error

Validator sets validator function for flags. Check existing validators in flags/validator and flags/validator/govalidator packages.

func Validator(val ValidateFunc)

FlagFunc is a generic function that can be applied to each value that will end up being a flags *Flag, so that users can perform more arbitrary operations on each, such as checking for completer implementations, bind to viper configurations, etc.

type FlagFunc func(flag string, tag tag.MultiTag, val reflect.Value) error

FlagHandler sets the handler function for flags, in order to perform arbitrary operations on the value of the flag identified by the <flag> name parameter of FlagFunc.

func FlagHandler(val FlagFunc)

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrParse is a general error used to wrap more specific errors.
	ErrParse = errors.New("parse error")

	// ErrNotPointerToStruct indicates that a provided data container is not
	// a pointer to a struct. Only pointers to structs are valid data containers
	// for options.
	ErrNotPointerToStruct = errors.New("object must be a pointer to struct or interface")

	// ErrNotCommander is returned when an embedded struct is tagged as a command,
	// but does not implement even the most simple interface, Commander.
	ErrNotCommander = errors.New("provided data does not implement Commander")

	// ErrObjectIsNil is returned when the struct/object/pointer is nil.
	ErrObjectIsNil = errors.New("object cannot be nil")

	// ErrInvalidTag indicates an invalid tag or invalid use of an existing tag.
	ErrInvalidTag = errors.New("invalid tag")

	// ErrTag indicates an error while parsing flag tags.
	ErrTag = errors.New("tag error")

	// ErrShortNameTooLong indicates that a short flag name was specified,
	// longer than one character.
	ErrShortNameTooLong = errors.New("short names can only be 1 character long")

	// ErrFlagHandler indicates that the custom handler for a flag has failed.
	ErrFlagHandler = errors.New("custom handler for flag failed")

	// ErrNotValue indicates that a struct field type does not implement the
	// Value interface. This only happens when the said type is a user-defined one.
	ErrNotValue = errors.New("invalid field marked as flag")
)

MapAllowedKinds stores list of kinds allowed for map keys.

Functions

This section is empty.

Types

type BoolFlag

type BoolFlag interface {
	Value
	IsBoolFlag() bool
}

BoolFlag is an optional interface to indicate boolean flags that don't accept v value, and implicitly have v --no-<x> negation counterpart.

type Commander

type Commander interface {
	// Execute runs the command implementation.
	// The args parameter is any argument that has not been parsed
	// neither on any parent command and/or its options, or this
	// command and/or its args/options.
	Execute(args []string) (err error)
}

Commander is the simplest and smallest interface that a type must implement to be a valid, local, client command. This command can be used either in a single-run CLI app, or in a closed-loop shell.

func IsCommand

func IsCommand(val reflect.Value) (reflect.Value, bool, Commander)

IsCommand checks both tags and implementations on a pointer to a struct, initializing the value itself if it's nil (useful for callers).

type Counter

type Counter int

Counter type is useful if you want to save number by using flag multiple times in command line. It's a boolean type, so you can use it without value. If you use `struct{count Counter} and parse it with `-count=10 ... -count .. -count`, then final value of `count` will be 12. Implements Value, Getter, BoolFlag, RepeatableFlag interfaces.

func (Counter) Get

func (v Counter) Get() interface{}

Get method returns inner value for Counter.

func (Counter) IsBoolFlag

func (v Counter) IsBoolFlag() bool

IsBoolFlag returns true, because Counter might be used without value.

func (Counter) IsCumulative

func (v Counter) IsCumulative() bool

IsCumulative returns true, because Counter might be used multiple times.

func (*Counter) Set

func (v *Counter) Set(s string) error

Set method parses string from command line.

func (Counter) String

func (v Counter) String() string

String returns string representation of Counter.

func (Counter) Type

func (v Counter) Type() string

Type returns `count` for Counter, it's mostly for pflag compatibility.

type Flag

type Flag struct {
	Name       string // name as it appears on command line
	Short      string // optional short name
	EnvName    string
	Usage      string   // help message
	Value      Value    // value as set
	DefValue   []string // default value (as text); for usage message
	Hidden     bool
	Deprecated bool

	// If true, the option _must_ be specified on the command line. If the
	// option is not specified, the parser will generate an ErrRequired type
	// error.
	Required bool

	// If non empty, only a certain set of values is allowed for an option.
	Choices []string

	// The optional value of the option. The optional value is used when
	// the option flag is marked as having an OptionalArgument. This means
	// that when the flag is specified, but no option argument is given,
	// the value of the field this option represents will be set to
	// OptionalValue. This is only valid for non-boolean options.
	OptionalValue []string
}

Flag structure might be used by cli/flag libraries for their flag generation.

func ParseField

func ParseField(value reflect.Value, field reflect.StructField, optFuncs ...OptFunc) ([]*Flag, bool, error)

ParseField parses a single struct field as a list (often only made of only one) flags. This function can be used when you want to scan only some fields for which you want a flag.

func ParseStruct

func ParseStruct(cfg interface{}, optFuncs ...OptFunc) ([]*Flag, error)

ParseStruct parses structure and returns list of flags based on this structure. This list of flags can be used by generators for flag, kingpin, cobra, pflag, urfave/cli.

type FlagFunc

type FlagFunc scan.FlagFunc

FlagFunc is a generic function that can be applied to each value that will end up being a flags *Flag, so that users can perform more arbitrary operations on each, such as checking for completer implementations, bind to viper configurations, etc.

type Getter

type Getter interface {
	Value
	Get() interface{}
}

Getter is an interface that allows the contents of v Value to be retrieved. It wraps the Value interface, rather than being part of it, because it appeared after Go 1 and its compatibility rules. All Value types provided by this package satisfy the Getter interface.

type HexBytes

type HexBytes []byte

HexBytes might be used if you want to parse slice of bytes as hex string. Original `[]byte` or `[]uint8` parsed as a list of `uint8`.

type OptFunc

type OptFunc scan.OptFunc

OptFunc sets values in opts structure.

func DescTag

func DescTag(val string) OptFunc

DescTag sets custom description tag. It is "desc" by default.

func EnvDivider

func EnvDivider(val string) OptFunc

EnvDivider sets custom divider for environment variables. It is underscore by default. e.g. "ENV_NAME".

func EnvPrefix

func EnvPrefix(val string) OptFunc

EnvPrefix sets prefix that will be applied for all environment variables (if they are not marked as ~).

func FlagDivider

func FlagDivider(val string) OptFunc

FlagDivider sets custom divider for flags. It is dash by default. e.g. "flag-name".

func FlagHandler

func FlagHandler(val FlagFunc) OptFunc

FlagHandler sets the handler function for flags, in order to perform arbitrary operations on the value of the flag identified by the <flag> name parameter of FlagFunc.

func FlagTag

func FlagTag(val string) OptFunc

FlagTag sets custom flag tag. It is "flag" be default.

func Flatten

func Flatten(val bool) OptFunc

Flatten set flatten option. Set to false if you don't want anonymous structure fields to be flatten.

func ParseAll

func ParseAll() OptFunc

ParseAll orders the parser to generate a flag for all struct fields, even if there isn't a struct tag attached to them.

func Prefix

func Prefix(val string) OptFunc

Prefix sets prefix that will be applied for all flags (if they are not marked as ~).

func Validator

func Validator(val ValidateFunc) OptFunc

Validator sets validator function for flags. Check existed validators in flags/validator package.

type RepeatableFlag

type RepeatableFlag interface {
	Value
	IsCumulative() bool
}

RepeatableFlag is an optional interface for flags that can be repeated. required by kingpin.

type ValidateFunc

type ValidateFunc scan.ValidateFunc

ValidateFunc describes a validation func, that takes string val for flag from command line, field that's associated with this flag in structure cfg. Also works for positional arguments. Should return error if validation fails.

type Value

type Value interface {
	String() string
	Set(string) error

	// pflag.Flag require this
	Type() string
}

Value is the interface to the dynamic value stored in v flag. (The default value is represented as v string.)

If v Value has an IsBoolFlag() bool method returning true, the command-line parser makes --name equivalent to -name=true rather than using the next command-line argument, and adds v --no-name counterpart for negating the flag.

Directories

Path Synopsis
cmd
genvalues
This generator is for internal usage only.
This generator is for internal usage only.
gen
flags
Package flags (github.com/reeflective/flags/gen/flags) provides the entrypoints to command trees and flags generation for arbitrary structures.
Package flags (github.com/reeflective/flags/gen/flags) provides the entrypoints to command trees and flags generation for arbitrary structures.
internal
tag
govalidator
Package govalidator adds support for govalidator library.
Package govalidator adds support for govalidator library.

Jump to

Keyboard shortcuts

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