clisan

package module
v1.22.14 Latest Latest
Warning

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

Go to latest
Published: Mar 31, 2023 License: Apache-2.0 Imports: 3 Imported by: 0

README

UrfaveCliSan

instrument actions for testing purpose.

Documentation

See Documentation

Primary Usage

use Inject before app run or InjectAndRun for one shot. The example is also shown as example-InjectAndRun.

package main

var app = &cli.App{
    Commands: []cli.Command{
        {
            Name: "exec",
            Action: func(ctx *cli.Context) error {
                fmt.Printf("  Execute(%v)\n", ctx.Command.Name)
                return nil
            },
        },
    },
}

func main() {
	err := InjectAndRun(app, []string{"awesome-app", "exec"}, func(ctx *cli.Context, next ActionFunc) error {
		fmt.Printf("clisan.BeforeHook(%v)\n", ctx.Command.Name)
		err := next(ctx)
		fmt.Printf("clisan.AfterHook(%v)\n", ctx.Command.Name)
		return err
	})
	if err != nil {
		fmt.Printf("error %s", err.Error())
	}
}

The expected output:

clisan.BeforeHook(exec)
  Execute(exec)
clisan.AfterHook(exec)
Extra Options

To handle before, after functions, you have two option:

  • use clisan.WithBeforeInstrumentation or clisan.WithAfterInstrumentation
  • use clisan.WithBeforeAfterTagging([]{"$before", "$after"})

For example, to use WithBeforeAfterTagging, which is also shown as example-InjectAndRun.


func main() {
	err := InjectAndRun(&cli.App{
		Commands: []cli.Command{
			{
				Name: "exec",
				Before: func(ctx *cli.Context) error {
					fmt.Printf("  Before(%v)\n", ctx.Command.Name)
					return nil
				},
				Action: func(ctx *cli.Context) error {
					fmt.Printf("  Execute(%v)\n", ctx.Command.Name)
					return nil
				},
				After: func(ctx *cli.Context) error {
					fmt.Printf("  After(%v)\n", ctx.Command.Name)
					return nil
				},
			},
		},
	}, []string{"awesome-app", "exec"}, func(ctx *cli.Context, next ActionFunc) error {
		fmt.Printf("clisan.BeforeHook%s(%v)\n", GetTaintPosition(ctx.App), ctx.Command.Name)
		err := next(ctx)
		fmt.Printf("clisan.AfterHook%s(%v)\n", GetTaintPosition(ctx.App), ctx.Command.Name)
		return err
	}, WithBeforeAfterTagging([]string{BeforeTag, AfterTag}))
	if err != nil {
		fmt.Printf("error %s", err.Error())
	}
}

The expected output:

clisan.BeforeHook$before(exec)
  Before(exec)
clisan.AfterHook$before(exec)
clisan.BeforeHook$current(exec)
  Execute(exec)
clisan.AfterHook$current(exec)
clisan.BeforeHook$after(exec)
  After(exec)
clisan.AfterHook$after(exec)

Note, it is meaningless to use WithBeforeInstrumentation/WithAfterInstrumentation and WithBeforeAfterTagging at the same time.

Documentation

Index

Examples

Constants

View Source
const (
	AfterTag         = "$after"
	BeforeTag        = "$before"
	CurrentTag       = "$current"
	TaintPositionKey = "$taint"
)

Variables

This section is empty.

Functions

func GetTaintPosition

func GetTaintPosition(app *cli.App) string

GetTaintPosition returns the position tag of the current execution. The tag is set by WithBeforeAfterTagging.

func Inject

func Inject(app *cli.App, instrumentation InstrumentFunc, opts ...InstrumentOptions) (restore func())

Inject instrument the app. The returned function restores the original state of the app.

func InjectAndRun

func InjectAndRun(app *cli.App, arguments []string, instrumentation InstrumentFunc, opts ...InstrumentOptions) error

InjectAndRun instrument the app and runs it. The returned error is the same as the one returned by app.Run, i.e. https://pkg.golang.ir/github.com/urfave/cli/v3#App.Run.

Example

ExampleInjectAndRun is an example of how to use InjectAndRun to inject a BeforeHook and AfterHook into a cli.App and run the app.

err := InjectAndRun(&cli.App{
	Commands: []cli.Command{
		{
			Name: "exec",
			Action: func(ctx *cli.Context) error {
				fmt.Printf("  Execute(%v)\n", ctx.Command.Name)
				return nil
			},
		},
	},
}, []string{"awesome-app", "exec"}, func(ctx *cli.Context, next ActionFunc) error {
	fmt.Printf("clisan.BeforeHook(%v)\n", ctx.Command.Name)
	err := next(ctx)
	fmt.Printf("clisan.AfterHook(%v)\n", ctx.Command.Name)
	return err
})
if err != nil {
	fmt.Printf("error %s", err.Error())
}
Output:

clisan.BeforeHook(exec)
  Execute(exec)
clisan.AfterHook(exec)

Types

type ActionFunc

type ActionFunc = func(*cli.Context) error

ActionFunc is the action to execute when no subcommands are specified

type AfterFunc

type AfterFunc = func(*cli.Context) error

AfterFunc is an action to execute after any subcommands are run, but after the subcommand has finished it is run even if Action() panics

type BeforeFunc

type BeforeFunc = func(*cli.Context) error

BeforeFunc is an action to execute before any subcommands are run, but after the context is ready if a non-nil error is returned, no subcommands are run

type CommandNotFoundFunc

type CommandNotFoundFunc = func(*cli.Context, string)

CommandNotFoundFunc is executed if the proper command cannot be found

type ExitErrHandlerFunc

type ExitErrHandlerFunc func(context *cli.Context, err error)

ExitErrHandlerFunc is executed if provided in order to handle ExitError values returned by Actions and Before/After functions.

type FlagEnvHintFunc

type FlagEnvHintFunc = func(envVar, str string) string

FlagEnvHintFunc is used by the default FlagStringFunc to annotate flag help with the environment variable details.

type FlagFileHintFunc

type FlagFileHintFunc = func(file, str string) string

FlagFileHintFunc is used by the default FlagStringFunc to annotate flag help with the file details.

type FlagNamePrefixFunc

type FlagNamePrefixFunc = func(fullName, placeholder string) string

FlagNamePrefixFunc is used by the default FlagStringFunc to create prefix text for a flag's full name.

type FlagStringFunc

type FlagStringFunc = func(cli.Flag) string

FlagStringFunc is used by the help generation to display a flag, which is expected to be a single line.

type HelpPrinter

type HelpPrinter = func(w io.Writer, templ string, data interface{})

Prints help for the App or Command

type HelpPrinterCustom

type HelpPrinterCustom = func(w io.Writer, templ string, data interface{}, customFunc map[string]interface{})

Prints help for the App or Command with custom template function.

type InstrumentAfterFunc

type InstrumentAfterFunc = func(ctx *cli.Context, next AfterFunc) error

type InstrumentBeforeFunc

type InstrumentBeforeFunc = func(ctx *cli.Context, next BeforeFunc) error

type InstrumentCommandNotFoundFunc

type InstrumentCommandNotFoundFunc = func(ctx *cli.Context, command string, next CommandNotFoundFunc)

type InstrumentExitErrHandlerFunc

type InstrumentExitErrHandlerFunc = func(ctx *cli.Context, err error, next ExitErrHandlerFunc)

type InstrumentFlagEnvHintFunc

type InstrumentFlagEnvHintFunc = func(envVar, str string, next FlagEnvHintFunc) string

type InstrumentFlagFileHintFunc

type InstrumentFlagFileHintFunc = func(filePath, str string, next FlagFileHintFunc) string

type InstrumentFlagNamePrefixFunc

type InstrumentFlagNamePrefixFunc = func(fullName, placeholder string, next FlagNamePrefixFunc) string

type InstrumentFlagStringFunc

type InstrumentFlagStringFunc = func(flag cli.Flag, next FlagStringFunc) string

type InstrumentFunc

type InstrumentFunc = func(ctx *cli.Context, next ActionFunc) error

type InstrumentHelpPrinter

type InstrumentHelpPrinter = func(w io.Writer, templ string, data interface{}, next HelpPrinter)

type InstrumentHelpPrinterCustom

type InstrumentHelpPrinterCustom = func(w io.Writer, templ string, data interface{}, customFunc map[string]interface{}, next HelpPrinterCustom)

type InstrumentOnUsageErrorFunc

type InstrumentOnUsageErrorFunc = func(ctx *cli.Context, err error, isSubcommand bool, next OnUsageErrorFunc) error

type InstrumentOptions

type InstrumentOptions func(opts *instrumentState)

func WithAfterInstrumentation

func WithAfterInstrumentation(proxyAfter InstrumentAfterFunc) InstrumentOptions

func WithBeforeAfterTagging

func WithBeforeAfterTagging(tags []string) InstrumentOptions
Example

ExampleWithBeforeAfterTagging is an example of how to use WithBeforeAfterTagging to inject a BeforeHook and AfterHook into a cli.App and run the app.

err := InjectAndRun(&cli.App{
	Commands: []cli.Command{
		{
			Name: "exec",
			Before: func(ctx *cli.Context) error {
				fmt.Printf("  Before(%v)\n", ctx.Command.Name)
				return nil
			},
			Action: func(ctx *cli.Context) error {
				fmt.Printf("  Execute(%v)\n", ctx.Command.Name)
				return nil
			},
			After: func(ctx *cli.Context) error {
				fmt.Printf("  After(%v)\n", ctx.Command.Name)
				return nil
			},
		},
	},
}, []string{"awesome-app", "exec"}, func(ctx *cli.Context, next ActionFunc) error {
	fmt.Printf("clisan.BeforeHook%s(%v)\n", GetTaintPosition(ctx.App), ctx.Command.Name)
	err := next(ctx)
	fmt.Printf("clisan.AfterHook%s(%v)\n", GetTaintPosition(ctx.App), ctx.Command.Name)
	return err
}, WithBeforeAfterTagging([]string{BeforeTag, AfterTag}))
if err != nil {
	fmt.Printf("error %s", err.Error())
}
Output:

clisan.BeforeHook$before(exec)
  Before(exec)
clisan.AfterHook$before(exec)
clisan.BeforeHook$current(exec)
  Execute(exec)
clisan.AfterHook$current(exec)
clisan.BeforeHook$after(exec)
  After(exec)
clisan.AfterHook$after(exec)

func WithBeforeInstrumentation

func WithBeforeInstrumentation(proxyBefore InstrumentBeforeFunc) InstrumentOptions

func WithCommandNotFoundInstrumentation

func WithCommandNotFoundInstrumentation(proxy InstrumentCommandNotFoundFunc) InstrumentOptions

func WithExitErrHandlerInstrumentation

func WithExitErrHandlerInstrumentation(proxy InstrumentExitErrHandlerFunc) InstrumentOptions

func WithFlagEnvHintInstrumentation

func WithFlagEnvHintInstrumentation(proxy InstrumentFlagEnvHintFunc) InstrumentOptions

func WithFlagFileHintInstrumentation

func WithFlagFileHintInstrumentation(proxy InstrumentFlagFileHintFunc) InstrumentOptions

func WithFlagNamePrefixInstrumentation

func WithFlagNamePrefixInstrumentation(proxy InstrumentFlagNamePrefixFunc) InstrumentOptions

func WithFlagStringInstrumentation

func WithFlagStringInstrumentation(proxy InstrumentFlagStringFunc) InstrumentOptions

func WithHelpCustomInstrumentation

func WithHelpCustomInstrumentation(proxy InstrumentHelpPrinterCustom) InstrumentOptions

func WithHelpInstrumentation

func WithHelpInstrumentation(proxy InstrumentHelpPrinter) InstrumentOptions

func WithOnUsageErrorInstrumentation

func WithOnUsageErrorInstrumentation(proxy InstrumentOnUsageErrorFunc) InstrumentOptions

type OnUsageErrorFunc

type OnUsageErrorFunc = func(context *cli.Context, err error, isSubcommand bool) error

OnUsageErrorFunc is executed if an usage error occurs. This is useful for displaying customized usage error messages. This function is able to replace the original error messages. If this function is not set, the "Incorrect usage" is displayed and the execution is interrupted.

Jump to

Keyboard shortcuts

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