app

package
v1.0.3 Latest Latest
Warning

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

Go to latest
Published: Jan 4, 2023 License: MIT Imports: 18 Imported by: 0

Documentation

Overview

Package app makes easier defining - in a structured way - a command line application with cobra.Command objects.

Inputs of commands are bound to flags and args using the bflags package.

type InputSample struct {
	MyValue string `cmd:"arg" json:"my_value"`
}
func execSample(ctx *app.CmdCtx, in *InputSample) (*OutputSample, error) {
	out := &OutputSample{Out: "done"}
	fmt.Println("executing sample", "ctx", ctx != nil, "in", in, "-> out", out)
	return out, nil
}

func ExampleCommand() {

	spec := app.NewSpec(
		[]*app.CmdCategory{
			{Name: "base", Title: "start working and configure"},
			{Name: "tools", Title: "pre built tools"},
			{Name: "others", Title: "others", Default: true},
		},
	&app.Cmd{
		Use:   "cli ",
		Short: "Sample Client",
		Long: "A command line tool",
		PersistentPreRunE:  app.CobraFn(initializeSample),
		PersistentPostRunE: app.CobraFn(cleanup),
		SilenceErrors:      true,
		SubCommands: []*app.Cmd{
			{
				Use:      "sample test ",
				Short:    "sample <arg>",
				Category: "tools",
				Example:  "smaple the_fox ",
				RunE:     app.RunFn(execSample),
				Input:    &InputSample{MyValue: "xyz"},
			},
		},
	})
	a, err := app.NewApp(spec, nil)
	if err != nil {
		fmt.Println("error", err)
		return
	}

	root, err := a.Cobra()
	if err != nil {
		fmt.Println("error", err)
		return
	}
	os.Args = append([]string{""}, "sample")
	err = root.Execute()
	if err != nil {
		fmt.Println("error", err)
		return
	}

	a, _ = app.NewApp(spec, nil)
	root, _ = a.Cobra()
	os.Args = append([]string{""}, "sample", "my_fox")
	err = root.Execute()
	if err != nil {
		fmt.Println("error", err)
		return
	}

	// Output:
	// initializeSample
	// executing sample ctx true in &{xyz} -> out &{done}
	// cleanup
	// initializeSample
	// executing sample ctx true in &{my_fox} -> out &{done}
	// cleanup
}

Index

Constants

View Source
const (
	CtxCmd           = "cmd"
	CtxResult        = "result"
	CtxAddResultFn   = "add-result-fn"
	CtxPrintResultFn = "print-result-fn"
	CtxGetResultFn   = "get-result-fn"
	CmdValidate      = "$cmd-validate"
)
View Source
const SpecKey = "$spec"

SpecKey is the context key for the spec

Variables

This section is empty.

Functions

func AddTemplateFunc

func AddTemplateFunc(name string, tmplFunc interface{})

AddTemplateFunc adds a template function that's available to Usage and Help template generation. Also adds the function to the cobra template functions.

func NewSpec

func NewSpec(categories []*CmdCategory, cmdRoot *Cmd) *spec

func SpecOf

func SpecOf(cmd *cobra.Command) *spec

Types

type AddResultFn

type AddResultFn func(key string, out interface{}, err error)

AddResultFn and PrintResultFn are function for results book keeping

type App

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

func NewApp

func NewApp(spec *spec, rtSpec *Runtime) (*App, error)

func NewAppFromSpec

func NewAppFromSpec(jsonSpec string, rtSpec *Runtime) (*App, error)

func (*App) Cobra

func (a *App) Cobra() (*cobra.Command, error)

func (*App) Command

func (a *App) Command(path ...string) (*Cmd, error)

func (*App) NewCobra added in v1.0.3

func (a *App) NewCobra() (*cobra.Command, error)

func (*App) SetCommandEnd

func (a *App) SetCommandEnd(cmdEnd CommandEnd)

func (*App) SetCommandStart

func (a *App) SetCommandStart(cmdStart CommandStart)

func (*App) SetMonitorResults

func (a *App) SetMonitorResults(b bool)

func (*App) Spec

func (a *App) Spec() *spec

func (*App) WithCustomFlags

func (a *App) WithCustomFlags(custom bflags.Flagger) *App

func (*App) WithFlagsChecker

func (a *App) WithFlagsChecker(flagsChecker CobraFunction) *App

type Cmd

type Cmd struct {
	Use                        string            `json:"use"`
	Aliases                    []string          `json:"aliases,omitempty"`
	SuggestFor                 []string          `json:"suggest_for,omitempty"`
	Short                      string            `json:"short"`
	Long                       mstring           `json:"long"`
	Category                   string            `json:"category"`
	Example                    mstring           `json:"example"`
	ValidArgs                  []string          `json:"valid_args,omitempty"`
	Args                       string            `json:"args,omitempty"`
	ArgsValidator              ValidatorCtor     `json:"-"` // additional validator
	ArgAliases                 []string          `json:"arg_aliases,omitempty"`
	BashCompletionFunction     string            `json:"bash_completion_function,omitempty"`
	Deprecated                 string            `json:"deprecated,omitempty"`
	Hidden                     bool              `json:"hidden,omitempty"`
	Annotations                map[string]string `json:"annotations,omitempty"`
	Version                    string            `json:"version,omitempty"`
	PersistentPreRunE          CobraFunc         `json:"persistent_pre_run_e,omitempty"`
	PreRunE                    CobraFunc         `json:"pre_run_e,omitempty"`
	RunE                       RunFunc           `json:"run_e"`
	PostRunE                   CobraFunc         `json:"post_run_e,omitempty"`
	PersistentPostRunE         CobraFunc         `json:"persistent_post_run_e,omitempty"`
	SilenceErrors              bool              `json:"silence_errors,omitempty"`
	SilenceUsage               bool              `json:"silence_usage,omitempty"`
	DisableFlagParsing         bool              `json:"disable_flag_parsing,omitempty"`
	DisableAutoGenTag          bool              `json:"disable_auto_gen_tag,omitempty"`
	DisableFlagsInUseLine      bool              `json:"disable_flags_in_use_line,omitempty"`
	DisableSuggestions         bool              `json:"disable_suggestions,omitempty"`
	SuggestionsMinimumDistance int               `json:"suggestions_minimum_distance,omitempty"`
	TraverseChildren           bool              `json:"traverse_children,omitempty"`
	InputCtor                  string            `json:"input_ctor"`             // name of input in app's map
	Input                      CmdInput          `json:"input,omitempty"`        // json of input or input object
	SubCommands                []*Cmd            `json:"sub_commands,omitempty"` // sub commands
	// contains filtered or unexported fields
}

func (*Cmd) MarshalJSON added in v1.0.3

func (c *Cmd) MarshalJSON() ([]byte, error)

func (*Cmd) Name

func (c *Cmd) Name() string

func (*Cmd) Sub

func (c *Cmd) Sub(path []string) (*Cmd, error)

func (*Cmd) ToCobra

func (c *Cmd) ToCobra(parent *cobra.Command, f bflags.Flagger) (*cobra.Command, error)

func (*Cmd) UpdateExamples

func (c *Cmd) UpdateExamples(upd func(s string) string)

type CmdCategories

type CmdCategories []*CmdCategory

func NewCategories

func NewCategories(categories []*CmdCategory, cmdRoot *cobra.Command) CmdCategories

func (CmdCategories) GetCategories

func (c CmdCategories) GetCategories() []*CmdCategory

type CmdCategory

type CmdCategory struct {
	Name    string           `json:"name"`    // the key name of this category to be used in command
	Title   string           `json:"title"`   // title of the group that will be displayed in help
	Default bool             `json:"default"` // true to have the category be the default where commands with no category are
	Cmds    []*cobra.Command `json:"-"`
}

type CmdCtx

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

CmdCtx implements a simple map to get/set objects by name

func NewCmdCtx

func NewCmdCtx() *CmdCtx

func (*CmdCtx) Get

func (c *CmdCtx) Get(k string) (interface{}, bool)

func (*CmdCtx) Set

func (c *CmdCtx) Set(k string, v interface{})

type CmdFlag

type CmdFlag interface {
	Value() interface{}
	CmdPath() string
	FlagName() string
	Arg() bool
}

type CmdInput

type CmdInput interface{}

type CmdResult

type CmdResult struct {
	Key    string      `json:"key"`
	Result interface{} `json:"result,omitempty"`
	Error  string      `json:"error,omitempty"`
}

func (*CmdResult) String

func (r *CmdResult) String() string

type CmdSampler

type CmdSampler interface {
	ValidateInputSamples() error
	ValidateExamples() error
}

func NewCmdSampler

func NewCmdSampler(app *App, printer SamplePrinter, validator CmdValidator) CmdSampler

type CmdValidator

type CmdValidator interface {

	// InputSamples provides samples of the given interface for the given command
	InputSamples(cmdPath []string, in interface{}) []*InputSample

	// Validate validates values received from a command line execution.
	// The function is called only if the input is not rejected by cobra.
	//
	// cmdPath: the command 'path'
	// val: one of the InputSample that was produced by InputSamples
	// in: the 'input' value for the command defined in the spec and altered
	//     by the command line execution
	Validate(cmdPath []string, val *InputSample, in interface{}) error

	// ValidateError validates the error received for the given input sample is
	// legitimate
	ValidateError(cmdPath []string, val *InputSample, err error) error
}

type CobraFunc

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

func CobraFn

func CobraFn(fn CobraFunction) CobraFunc

func CobraFnWithName

func CobraFnWithName(name string) CobraFunc

func (*CobraFunc) MarshalText

func (c *CobraFunc) MarshalText() ([]byte, error)

MarshalText implements custom marshaling using the string representation.

func (*CobraFunc) String added in v1.0.3

func (c *CobraFunc) String() string

func (*CobraFunc) UnmarshalText

func (c *CobraFunc) UnmarshalText(text []byte) error

UnmarshalText implements custom unmarshaling from the string representation.

type CobraFunction

type CobraFunction func(cmd *cobra.Command, args []string) error

type CommandEnd

type CommandEnd func(cmd *cobra.Command, out interface{}, err error)

type CommandStart

type CommandStart func(cmd *cobra.Command, flagsAndArgs map[string]string, in interface{})

type Ctor

type Ctor func() interface{}

Ctor is the type of function creating an 'input' parameter for a command The returned value will be initialized with the default values found in the App spec.

type FlagsDictionary

type FlagsDictionary interface {
	String() string
	Validate(root *cobra.Command) error
}

FlagsDictionary enables normalization of flag names vs the type they represent.

Constructing the flags dictionary has to happen after flags have been bound to the commands input via `bflags.Bind`. In the case of an app, this might be done after having called the Cobra func: ```

    a, _ := app.NewApp(spec, nil)
    root, err := a.Cobra()
	   ..

``` Steps: - construct an new FlagsDictionary passing a [possibly nil] validator - call Validate(root):

  • if no validator was provided this just loads the dictionary
  • otherwise it calls the validator for each type found in flags values

- call String() to have a json of the dictionary (for 'manual' inspection).

func NewFlagDictionary

func NewFlagDictionary(v FlagsValidator, withArgs bool) FlagsDictionary

type FlagsValidator

type FlagsValidator interface {
	Validate(t reflect.Type, flags []CmdFlag) error
}

type InputSample

type InputSample struct {
	ExpectFail      bool
	ExpectedFailure string
	Input           interface{}
	// contains filtered or unexported fields
}

type JCmd added in v1.0.3

type JCmd struct {
	Use                        string            `json:"use"`
	Aliases                    []string          `json:"aliases,omitempty"`
	SuggestFor                 []string          `json:"suggest_for,omitempty"`
	Short                      string            `json:"short"`
	Long                       mstring           `json:"long,omitempty"`
	Category                   string            `json:"category,omitempty"`
	Example                    mstring           `json:"example,omitempty"`
	ValidArgs                  []string          `json:"valid_args,omitempty"`
	Args                       string            `json:"args,omitempty"`
	ArgsValidator              ValidatorCtor     `json:"-"` // additional validator
	ArgAliases                 []string          `json:"arg_aliases,omitempty"`
	BashCompletionFunction     string            `json:"bash_completion_function,omitempty"`
	Deprecated                 string            `json:"deprecated,omitempty"`
	Hidden                     bool              `json:"hidden,omitempty"`
	Annotations                map[string]string `json:"annotations,omitempty"`
	Version                    string            `json:"version,omitempty"`
	PersistentPreRunE          string            `json:"persistent_pre_run_e,omitempty"`
	PreRunE                    string            `json:"pre_run_e,omitempty"`
	RunE                       string            `json:"run_e,omitempty"`
	PostRunE                   string            `json:"post_run_e,omitempty"`
	PersistentPostRunE         string            `json:"persistent_post_run_e,omitempty"`
	SilenceErrors              bool              `json:"silence_errors,omitempty"`
	SilenceUsage               bool              `json:"silence_usage,omitempty"`
	DisableFlagParsing         bool              `json:"disable_flag_parsing,omitempty"`
	DisableAutoGenTag          bool              `json:"disable_auto_gen_tag,omitempty"`
	DisableFlagsInUseLine      bool              `json:"disable_flags_in_use_line,omitempty"`
	DisableSuggestions         bool              `json:"disable_suggestions,omitempty"`
	SuggestionsMinimumDistance int               `json:"suggestions_minimum_distance,omitempty"`
	TraverseChildren           bool              `json:"traverse_children,omitempty"`
	InputCtor                  string            `json:"input_ctor,omitempty"`   // name of input in app's map
	Input                      CmdInput          `json:"input,omitempty"`        // json of input or input object
	SubCommands                []*Cmd            `json:"sub_commands,omitempty"` // sub commands
	// contains filtered or unexported fields
}

type PrintResultFn

type PrintResultFn func(results []*CmdResult)

type RunFunc

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

func RunFn

func RunFn(fn Runfn) RunFunc

func RunFnWithName

func RunFnWithName(name string) RunFunc

func (RunFunc) Func

func (c RunFunc) Func() Runfn

func (RunFunc) IsNil

func (c RunFunc) IsNil() bool

func (*RunFunc) MarshalText

func (c *RunFunc) MarshalText() ([]byte, error)

MarshalText implements custom marshaling using the string representation.

func (*RunFunc) String added in v1.0.3

func (c *RunFunc) String() string

func (*RunFunc) UnmarshalText

func (c *RunFunc) UnmarshalText(text []byte) error

UnmarshalText implements custom unmarshaling from the string representation.

type Runfn

type Runfn interface{}

Runfn is the type of function that a command shall execute at runtime. These functions are expected to conform to the following prototype:

func(ctx *CmdCtx, in interface{}) (interface{}, error)

- At least one input parameter:

  • first of type *CmdCtx
  • optionally a second parameter that is the input of the command

- 2 output parameters, the last one being an error

type Runtime

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

func RtFunctions

func RtFunctions(
	cobraFns map[string]CobraFunction,
	inputs map[string]Ctor,
	runFns map[string]Runfn) (*Runtime, error)

type SamplePrinter

type SamplePrinter interface {
	// Print receives a command line sample iff the execution failed as expected
	// by the sample.ExpectRun field.
	// cmdPath: path to the command
	// sample: the sample that was used or nil (if no flags were used).
	// cmdLine: the command line
	Print(cmdPath []string, sample *InputSample, cmdLine string)

	// Example receives an echo of the example command line before sending it to
	// the cobra Execute function (except the first call that just reports the
	// number of examples found)
	Example(cmdLine string)

	// ExamplesSummary receives the count of commands with a run method, the
	// number of them with an example, the number of examples
	ExamplesSummary(withRun, withEx, exCount int) error
}

type ValidatorCtor

type ValidatorCtor func(c *cobra.Command) func(c *cobra.Command, args []string) error

ValidatorCtor is a constructor validator

Directories

Path Synopsis
Gen provides a rudimentary code generator for app.
Gen provides a rudimentary code generator for app.

Jump to

Keyboard shortcuts

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