echidna

package module
v1.1.2 Latest Latest
Warning

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

Go to latest
Published: Apr 4, 2025 License: MIT Imports: 19 Imported by: 0

README

Go Reference Go Report Card

Echidna Library for Go

background image

echidna

import "github.com/bruceesmith/echidna"

Package echidna builds upon the Github packages knadh/koanf, urfave/cli/v3, bruceesmith/sflags to make it extremely simple to use the features of these excellent packages in concert.

Every program using echidna will expose a standard set of command-line flags (--json, --log, --trace, --verbose) in addition to the standard flags provided by urfave/cli/v3 (--help and --version).

If a configuration struct is provided to Run function by Configuration, then a further command-line flag (--config) is added to provide the source(s) of values for fields in the struct.

Command-line flags bound to fields in the configuration are created by providing ConfigFlags to Run. These flags can be bound either to the root command or to one or more child commands.

Index

Variables

var (
    // BuildDate is the timestamp for when this program was compiled
    BuildDate string = `Filled in during the build`
)

func Run

func Run(ctx context.Context, command *cli.Command, options ...Option)

Run is the primary external function of this library. It augments the cli.Command with default command-line flags, hooks in handling for processing a configuration, runs the appropriate Action, calls the terminator to wait for goroutine cleanup

Example (Action)

// Include an Action function
//
var cmd = &cli.Command{
	Action: func(ctx context.Context, cmd *cli.Command) error {
		fmt.Println("hello")
		return nil
	},
	Name:    "runaction",
	Version: "1",
}
os.Args = []string{"runaction"}
Run(context.Background(), cmd)
// Output:
// hello
Output
hello

Example (Basic)

// The most basic example
//
var cmd = &cli.Command{
	Name: "runbasic",
	Action: func(ctx context.Context, cmd *cli.Command) error {
		return nil
	},
}
os.Args = []string{"runbasic", "h"}
Run(context.Background(), cmd, NoDefaultFlags())
// Output:
// NAME:
//    runbasic - A new cli application
//
// USAGE:
//    runbasic [global options] [command [command options]]
//
// COMMANDS:
//    version, v  print the version
//    help, h     Shows a list of commands or help for one command
//
// GLOBAL OPTIONS:
//    --help, -h  show help
Output
NAME:
   runbasic - A new cli application

USAGE:
   runbasic [global options] [command [command options]]

COMMANDS:
   version, v  print the version
   help, h     Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --help, -h  show help

Example (Customflag)

// Include a custom flag
//
var cmd = &cli.Command{
	Action: func(ctx context.Context, cmd *cli.Command) error {
		fmt.Println("hello", cmd.Int("i"))
		return nil
	},
	Flags: []cli.Flag{
		&cli.IntFlag{
			Name:  "i",
			Usage: "An integer",
		},
	},
	Name:    "runcustomflag",
	Version: "1",
}
os.Args = []string{"runcustomflag", "-i", "22"}
Run(context.Background(), cmd, NoDefaultFlags())
// Output:
// hello 22
Output
hello 22

Example (Flagwithdefault)

// Include a custom flag with a default value
//
var cmd = &cli.Command{
	Action: func(ctx context.Context, cmd *cli.Command) error {
		fmt.Println("hello")
		return nil
	},
	Flags: []cli.Flag{
		&cli.IntFlag{
			Name:  "i",
			Usage: "An integer",
			Value: 22,
		},
	},
	Name:    "runflagwithdefault",
	Version: "1",
}
os.Args = []string{"runflagwithdefault", "--help"}
Run(context.Background(), cmd, NoDefaultFlags())
// Output:
// NAME:
//    runflagwithdefault - A new cli application
//
// USAGE:
//    runflagwithdefault [global options] [command [command options]]
//
// VERSION:
//    1
//
// COMMANDS:
//    version, v  print the version
//    help, h     Shows a list of commands or help for one command
//
// GLOBAL OPTIONS:
//    -i int         An integer (default: 22)
//    --help, -h     show help
//    --version, -v  print the version
Output
NAME:
   runflagwithdefault - A new cli application

USAGE:
   runflagwithdefault [global options] [command [command options]]

VERSION:
   1

COMMANDS:
   version, v  print the version
   help, h     Shows a list of commands or help for one command

GLOBAL OPTIONS:
   -i int         An integer (default: 22)
   --help, -h     show help
   --version, -v  print the version

Example (Version)

// Include a Version field in the Command
//
var cmd = &cli.Command{
	Name: "runversion",
	Action: func(ctx context.Context, cmd *cli.Command) error {
		return nil
	},
	Version: "1",
}
os.Args = []string{"runversion", "h"}
Run(context.Background(), cmd, NoDefaultFlags())
// Output:
// NAME:
//    runversion - A new cli application
//
// USAGE:
//    runversion [global options] [command [command options]]
//
// VERSION:
//    1
//
// COMMANDS:
//    version, v  print the version
//    help, h     Shows a list of commands or help for one command
//
// GLOBAL OPTIONS:
//    --help, -h     show help
//    --version, -v  print the version
Output
NAME:
   runversion - A new cli application

USAGE:
   runversion [global options] [command [command options]]

VERSION:
   1

COMMANDS:
   version, v  print the version
   help, h     Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --help, -h     show help
   --version, -v  print the version

type Configurator

Configurator is the interface for a configuration struct

type Configurator interface {
    Validate() error
}

type FlagOption

FlagOption is a functional option parameter for the ConfigFlags function

type FlagOption func()

func DescTag
func DescTag(tag string) FlagOption

DescTag sets the struct tag where usage text is configured

func EnvDivider
func EnvDivider(divider string) FlagOption

EnvDivider is the character in between parts of an environment variable bound to a command line struct-bound flag

func EnvPrefix
func EnvPrefix(prefix string) FlagOption

EnvPrefix is an optional prefix for an environment variable bound to a command line struct-bound flag

func FlagDivider
func FlagDivider(divider string) FlagOption

FlagDivider is the character in between parts of a struct-bound command line flag's name

func FlagTag
func FlagTag(tag string) FlagOption

FlagTag is the struct tag used to configure struct-bound command line flags

func Flatten
func Flatten(flatten bool) FlagOption

Flatten determines the name of a command line flag bound to a an anonymous struct field

func Prefix
func Prefix(prefix string) FlagOption

Prefix is an optional prefix for the names of all struct-bound command line flags

func Validator
func Validator(val sflags.ValidateFunc) FlagOption

Validator is an optional function that will be called to to validate each struct-field bound flag

type Loader

Loader is a parameter to Configuration which determines how configuration sources are loaded into the confguration struct

type Loader struct {
    Provider func(string) koanf.Provider
    Parser   koanf.Parser
    Match    func(string) bool
}

type Option

Option is a functional parameter for Run()

type Option func() error

func ConfigFlags
func ConfigFlags(configs []Configurator, command *cli.Command, ops ...FlagOption) Option

ConfigFlags creates and configures Run to have command line flags bound to the fields of one or more parts of a configuration struct

Example (Basic Flag Override)

// Flags bound to fields in a configuration struct. The flag value
// overrides the field's value obtained from reading the  YAML
// configuration file
//
// test.yml simply contains:
// i: 33
//
var (
	cfg configExample
	cmd = &cli.Command{
		Action: func(ctx context.Context, cmd *cli.Command) error {
			fmt.Println("config is", cfg)
			return nil
		},
		Name:    "basicflagoverride",
		Version: "1",
	}
	loaders = []Loader{
		{
			Provider: func(s string) koanf.Provider {
				return file.Provider(s)
			},
			Parser: yaml.Parser(),
			Match: func(s string) bool {
				return strings.HasSuffix(s, ".yml")
			},
		},
	}
)
os.Args = []string{"basicflagoverride", "-i", "77", "--config", "testdata/test.yml"}
Run(
	context.Background(),
	cmd,
	Configuration(
		&cfg,
		loaders,
	),
	ConfigFlags(
		[]Configurator{&cfg},
		cmd,
	),
	NoDefaultFlags(),
)
// Output:
// config is {77}
Output
config is {77}

Example (Basic Help)

// Help for flags bound to fields in a configuration struct. This
// shows the flag "--i" bound to cfg.I
//
var (
	cfg configExample
	cmd = &cli.Command{
		Action: func(ctx context.Context, cmd *cli.Command) error {
			fmt.Println("config is", cfg)
			return nil
		},
		Name:    "basichelp",
		Version: "1",
	}
	loaders = []Loader{
		{
			Provider: func(s string) koanf.Provider {
				return file.Provider(s)
			},
			Parser: yaml.Parser(),
			Match: func(s string) bool {
				return strings.HasSuffix(s, ".yml")
			},
		},
	}
)
os.Args = []string{"basichelp", "--help"}
Run(
	context.Background(),
	cmd,
	Configuration(
		&cfg,
		loaders,
	),
	ConfigFlags(
		[]Configurator{&cfg},
		cmd,
	),
	NoDefaultFlags(),
)
// Output:
// NAME:
//    basichelp - A new cli application
//
// USAGE:
//    basichelp [global options] [command [command options]]
//
// VERSION:
//    1
//
// COMMANDS:
//    version, v  print the version
//    help, h     Shows a list of commands or help for one command
//
// GLOBAL OPTIONS:
//    -i value                                                         (default: 0) [$I]
//    --config string, --cfg string [ --config string, --cfg string ]  comma-separated list of path(s) to configuration file(s)
//    --help, -h                                                       show help
//    --version, -v                                                    print the version
Output
NAME:
   basichelp - A new cli application

USAGE:
   basichelp [global options] [command [command options]]

VERSION:
   1

COMMANDS:
   version, v  print the version
   help, h     Shows a list of commands or help for one command

GLOBAL OPTIONS:
   -i value                                                         (default: 0) [$I]
   --config string, --cfg string [ --config string, --cfg string ]  comma-separated list of path(s) to configuration file(s)
   --help, -h                                                       show help
   --version, -v                                                    print the version

func Configuration
func Configuration(config Configurator, loaders []Loader) Option

Configuration is an Option helper to define a configuration structure that will be populated from the sources given on a --config command-line flag

Example (Basic)

var (
	cfg configExample
	cmd = &cli.Command{
		Action: func(ctx context.Context, cmd *cli.Command) error {
			fmt.Println("config is", cfg)
			return nil
		},
		Name:    "configbasic",
		Version: "1",
	}
	loaders = []Loader{
		{
			Provider: func(s string) koanf.Provider {
				return file.Provider(s)
			},
			Parser: yaml.Parser(),
			Match: func(s string) bool {
				return strings.HasSuffix(s, ".yml")
			},
		},
	}
)
os.Args = []string{"configbasic", "--config", "testdata/test.yml"}
Run(
	context.Background(),
	cmd,
	Configuration(
		&cfg,
		loaders,
	),
	NoDefaultFlags(),
)
// Output:
// config is {33}
Output
config is {33}

func NoDefaultFlags
func NoDefaultFlags() Option

NoDefaultFlags is a convenience function which is equivalent to calling all of NoJSON, NoLog, NoTrace, and NoVerbose

func NoJSON
func NoJSON() Option

NoJSON removes the default flag --json

func NoLog
func NoLog() Option

NoLog removes the default flag --log

func NoTrace
func NoTrace() Option

NoTrace removes the default flag --trace

func NoVerbose
func NoVerbose() Option

NoVerbose removes the default flag --verbose

Generated by gomarkdoc

Documentation

Overview

Package echidna builds upon the Github packages knadh/koanf, urfave/cli/v3, bruceesmith/sflags to make it extremely simple to use the features of these excellent packages in concert.

Every program using echidna will expose a standard set of command-line flags (--json, --log, --trace, --verbose) in addition to the standard flags provided by urfave/cli/v3 (--help and --version).

If a configuration struct is provided to Run function by Configuration, then a further command-line flag (--config) is added to provide the source(s) of values for fields in the struct.

Command-line flags bound to fields in the configuration are created by providing ConfigFlags to Run. These flags can be bound either to the root command or to one or more child commands.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// BuildDate is the timestamp for when this program was compiled
	BuildDate string = `Filled in during the build`
)

Functions

func Run added in v1.0.0

func Run(ctx context.Context, command *cli.Command, options ...Option)

Run is the primary external function of this library. It augments the cli.Command with default command-line flags, hooks in handling for processing a configuration, runs the appropriate Action, calls the terminator to wait for goroutine cleanup

Example (Action)
// Include an Action function
//
var cmd = &cli.Command{
	Action: func(ctx context.Context, cmd *cli.Command) error {
		fmt.Println("hello")
		return nil
	},
	Name:    "runaction",
	Version: "1",
}
os.Args = []string{"runaction"}
Run(context.Background(), cmd)
Output:

hello
Example (Basic)
// The most basic example
//
var cmd = &cli.Command{
	Name: "runbasic",
	Action: func(ctx context.Context, cmd *cli.Command) error {
		return nil
	},
}
os.Args = []string{"runbasic", "h"}
Run(context.Background(), cmd, NoDefaultFlags())
Output:

NAME:
   runbasic - A new cli application

USAGE:
   runbasic [global options] [command [command options]]

COMMANDS:
   version, v  print the version
   help, h     Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --help, -h  show help
Example (Customflag)
// Include a custom flag
//
var cmd = &cli.Command{
	Action: func(ctx context.Context, cmd *cli.Command) error {
		fmt.Println("hello", cmd.Int("i"))
		return nil
	},
	Flags: []cli.Flag{
		&cli.IntFlag{
			Name:  "i",
			Usage: "An integer",
		},
	},
	Name:    "runcustomflag",
	Version: "1",
}
os.Args = []string{"runcustomflag", "-i", "22"}
Run(context.Background(), cmd, NoDefaultFlags())
Output:

hello 22
Example (Flagwithdefault)
// Include a custom flag with a default value
//
var cmd = &cli.Command{
	Action: func(ctx context.Context, cmd *cli.Command) error {
		fmt.Println("hello")
		return nil
	},
	Flags: []cli.Flag{
		&cli.IntFlag{
			Name:  "i",
			Usage: "An integer",
			Value: 22,
		},
	},
	Name:    "runflagwithdefault",
	Version: "1",
}
os.Args = []string{"runflagwithdefault", "--help"}
Run(context.Background(), cmd, NoDefaultFlags())
Output:

NAME:
   runflagwithdefault - A new cli application

USAGE:
   runflagwithdefault [global options] [command [command options]]

VERSION:
   1

COMMANDS:
   version, v  print the version
   help, h     Shows a list of commands or help for one command

GLOBAL OPTIONS:
   -i int         An integer (default: 22)
   --help, -h     show help
   --version, -v  print the version
Example (Version)
// Include a Version field in the Command
//
var cmd = &cli.Command{
	Name: "runversion",
	Action: func(ctx context.Context, cmd *cli.Command) error {
		return nil
	},
	Version: "1",
}
os.Args = []string{"runversion", "h"}
Run(context.Background(), cmd, NoDefaultFlags())
Output:

NAME:
   runversion - A new cli application

USAGE:
   runversion [global options] [command [command options]]

VERSION:
   1

COMMANDS:
   version, v  print the version
   help, h     Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --help, -h     show help
   --version, -v  print the version

Types

type Configurator added in v1.0.0

type Configurator interface {
	Validate() error
}

Configurator is the interface for a configuration struct

type FlagOption added in v1.0.0

type FlagOption func()

FlagOption is a functional option parameter for the ConfigFlags function

func DescTag added in v1.0.0

func DescTag(tag string) FlagOption

DescTag sets the struct tag where usage text is configured

func EnvDivider added in v1.0.0

func EnvDivider(divider string) FlagOption

EnvDivider is the character in between parts of an environment variable bound to a command line struct-bound flag

func EnvPrefix added in v1.0.0

func EnvPrefix(prefix string) FlagOption

EnvPrefix is an optional prefix for an environment variable bound to a command line struct-bound flag

func FlagDivider added in v1.0.0

func FlagDivider(divider string) FlagOption

FlagDivider is the character in between parts of a struct-bound command line flag's name

func FlagTag added in v1.0.0

func FlagTag(tag string) FlagOption

FlagTag is the struct tag used to configure struct-bound command line flags

func Flatten added in v1.0.0

func Flatten(flatten bool) FlagOption

Flatten determines the name of a command line flag bound to a an anonymous struct field

func Prefix added in v1.0.0

func Prefix(prefix string) FlagOption

Prefix is an optional prefix for the names of all struct-bound command line flags

func Validator added in v1.0.0

func Validator(val sflags.ValidateFunc) FlagOption

Validator is an optional function that will be called to to validate each struct-field bound flag

type Loader added in v1.0.0

type Loader struct {
	Provider func(string) koanf.Provider
	Parser   koanf.Parser
	Match    func(string) bool
}

Loader is a parameter to Configuration which determines how configuration sources are loaded into the confguration struct

type Option added in v1.0.0

type Option func() error

Option is a functional parameter for Run()

func ConfigFlags added in v1.0.0

func ConfigFlags(configs []Configurator, command *cli.Command, ops ...FlagOption) Option

ConfigFlags creates and configures Run to have command line flags bound to the fields of one or more parts of a configuration struct

Example (BasicFlagOverride)
// Flags bound to fields in a configuration struct. The flag value
// overrides the field's value obtained from reading the  YAML
// configuration file
//
// test.yml simply contains:
// i: 33
//
var (
	cfg configExample
	cmd = &cli.Command{
		Action: func(ctx context.Context, cmd *cli.Command) error {
			fmt.Println("config is", cfg)
			return nil
		},
		Name:    "basicflagoverride",
		Version: "1",
	}
	loaders = []Loader{
		{
			Provider: func(s string) koanf.Provider {
				return file.Provider(s)
			},
			Parser: yaml.Parser(),
			Match: func(s string) bool {
				return strings.HasSuffix(s, ".yml")
			},
		},
	}
)
os.Args = []string{"basicflagoverride", "-i", "77", "--config", "testdata/test.yml"}
Run(
	context.Background(),
	cmd,
	Configuration(
		&cfg,
		loaders,
	),
	ConfigFlags(
		[]Configurator{&cfg},
		cmd,
	),
	NoDefaultFlags(),
)
Output:

config is {77}
Example (BasicHelp)
// Help for flags bound to fields in a configuration struct. This
// shows the flag "--i" bound to cfg.I
//
var (
	cfg configExample
	cmd = &cli.Command{
		Action: func(ctx context.Context, cmd *cli.Command) error {
			fmt.Println("config is", cfg)
			return nil
		},
		Name:    "basichelp",
		Version: "1",
	}
	loaders = []Loader{
		{
			Provider: func(s string) koanf.Provider {
				return file.Provider(s)
			},
			Parser: yaml.Parser(),
			Match: func(s string) bool {
				return strings.HasSuffix(s, ".yml")
			},
		},
	}
)
os.Args = []string{"basichelp", "--help"}
Run(
	context.Background(),
	cmd,
	Configuration(
		&cfg,
		loaders,
	),
	ConfigFlags(
		[]Configurator{&cfg},
		cmd,
	),
	NoDefaultFlags(),
)
Output:

NAME:
   basichelp - A new cli application

USAGE:
   basichelp [global options] [command [command options]]

VERSION:
   1

COMMANDS:
   version, v  print the version
   help, h     Shows a list of commands or help for one command

GLOBAL OPTIONS:
   -i value                                                         (default: 0) [$I]
   --config string, --cfg string [ --config string, --cfg string ]  comma-separated list of path(s) to configuration file(s)
   --help, -h                                                       show help
   --version, -v                                                    print the version

func Configuration added in v1.0.0

func Configuration(config Configurator, loaders []Loader) Option

Configuration is an Option helper to define a configuration structure that will be populated from the sources given on a --config command-line flag

Example (Basic)
var (
	cfg configExample
	cmd = &cli.Command{
		Action: func(ctx context.Context, cmd *cli.Command) error {
			fmt.Println("config is", cfg)
			return nil
		},
		Name:    "configbasic",
		Version: "1",
	}
	loaders = []Loader{
		{
			Provider: func(s string) koanf.Provider {
				return file.Provider(s)
			},
			Parser: yaml.Parser(),
			Match: func(s string) bool {
				return strings.HasSuffix(s, ".yml")
			},
		},
	}
)
os.Args = []string{"configbasic", "--config", "testdata/test.yml"}
Run(
	context.Background(),
	cmd,
	Configuration(
		&cfg,
		loaders,
	),
	NoDefaultFlags(),
)
Output:

config is {33}

func NoDefaultFlags added in v1.0.0

func NoDefaultFlags() Option

NoDefaultFlags is a convenience function which is equivalent to calling all of NoJSON, NoLog, NoTrace, and NoVerbose

func NoJSON added in v1.0.0

func NoJSON() Option

NoJSON removes the default flag --json

func NoLog added in v1.0.0

func NoLog() Option

NoLog removes the default flag --log

func NoTrace added in v1.0.0

func NoTrace() Option

NoTrace removes the default flag --trace

func NoVerbose added in v1.0.0

func NoVerbose() Option

NoVerbose removes the default flag --verbose

Jump to

Keyboard shortcuts

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