cli

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Mar 13, 2019 License: AGPL-3.0 Imports: 42 Imported by: 0

Documentation

Overview

Package cli defines types for Stratumn Node's command line interface.

It comes with only of handful of builtin commands. The bulk of commands are reflected from the API.

The main type is the CLI struct, which wraps everything needed to run the command line interface. It can, amongst other things, make suggestions for auto-completion and connect to a Stratumn node.

The CLI needs a Console and a Prompt. The console is responsible for rendering text. The Prompt is responsible for getting user input.

The Prompt is also responsible for calling the CLI's Exec method to execute a command, and the Suggest method to make suggestions for auto-completion.

The Suggest method should be given a Content which allows it to read the current text and returns a slice suggestions with the type Suggest.

BasicCmd is a type that allows creating simple commands that cover most use cases.

Index

Constants

View Source
const ConfigVersionKey = "cli.configuration_version"

ConfigVersionKey is the key of the configuration version number in the TOML file.

Variables

View Source
var (
	// ErrInvalidConfig is returned when the configuration is invalid.
	ErrInvalidConfig = errors.New("the configuration is invalid")

	// ErrPromptNotFound is returned when the requested prompt backend was
	// not found.
	ErrPromptNotFound = errors.New("the requested prompt was not found")

	// ErrDisconnected is returned when the CLI is not connected to the
	// API.
	ErrDisconnected = errors.New("the client is not connected to API")

	// ErrCmdNotFound is returned when a command was not found.
	ErrCmdNotFound = errors.New("the command was not found")

	// ErrInvalidExitCode is returned when an invalid exit code was given.
	ErrInvalidExitCode = errors.New("the exit code is invalid")

	// ErrUnsupportedReflectType is returned when a type is not currently
	// supported by reflection.
	ErrUnsupportedReflectType = errors.New("the type is not currently supported by reflection")

	// ErrReflectParse is returned when a value could not be parsed by a
	// reflector.
	ErrReflectParse = errors.New("could not parse the value")

	// ErrFieldNotFound is returned when the field of a message was not
	// found.
	ErrFieldNotFound = errors.New("the field was not found")
)
View Source
var Addr = BasicCmdWrapper{
	Cmd: BasicCmd{
		Name:  "api-address",
		Short: "Output API server address",
		Exec:  addrExec,
	},
}

Addr is a command that displays the API server's address.

View Source
var Bang = BasicCmdWrapper{
	Cmd: BasicCmd{
		Name:    "!",
		Use:     "! <Command> [args] [input]",
		Short:   "Executes external commands",
		Exec:    bangExec,
		NoFlags: true,
	},
}

Bang is a command that executes external commands.

View Source
var Connect = BasicCmdWrapper{
	Cmd: BasicCmd{
		Name:  "api-connect",
		Use:   "api-connect [Multiaddress]",
		Short: "Connect or reconnect to API server",
		Exec:  execConnect,
	},
}

Connect is a command that creates a connection to the API server.

DefReflectors are the default reflectors used by NewServerReflector.

View Source
var DefaultConfig = Config{
	ConfigVersion:     len(migrations),
	PromptBackend:     "vt100",
	EnableColorOutput: true,
	APIAddress:        "/ip4/127.0.0.1/tcp/8904",
	DialTimeout:       "30s",
	RequestTimeout:    "30s",
	EnableDebugOutput: false,
}

DefaultConfig is the default CLI configuration.

View Source
var Disconnect = BasicCmdWrapper{
	Cmd: BasicCmd{
		Name:  "api-disconnect",
		Short: "Disconnect from API server",
		Exec:  disconnectExec,
	},
}

Disconnect is a command that closes the connection to the API server.

View Source
var Echo = BasicCmdWrapper{
	Cmd: BasicCmd{
		Name:  "echo",
		Short: "Output text",
		Use:   "echo [Expressions...]",
		Flags: echoFlags,
		Exec:  echoExec,
	},
}

Echo is a command that outputs text.

View Source
var Exit = BasicCmdWrapper{
	Cmd: BasicCmd{
		Name:  "exit",
		Use:   "exit [Status]",
		Short: "Exit program",
		Exec:  exitExec,
	},
}

Exit is a command that terminates the current process.

View Source
var Help = BasicCmdWrapper{
	Cmd: BasicCmd{
		Name:  "help",
		Use:   "help [Command]",
		Short: "Get help on commands",
		Exec:  helpExec,
	},
}

Help is a command that lists all the available commands or displays help for specific command.

View Source
var Silent = BasicCmdWrapper{
	Cmd: BasicCmd{
		Name:  "silent",
		Use:   "silent [Expressions...]",
		Short: "Execute a command silently",
		Exec:  silentExec,
	},
}

Silent is a command that executes a command silently.

View Source
var StaticCmds = []Cmd{
	Addr,
	Bang,
	Connect,
	Disconnect,
	Echo,
	Exit,
	Help,
	Silent,
	Version,
}

StaticCmds is the list of builtin static CLI commands.

View Source
var Version = BasicCmdWrapper{
	Cmd: BasicCmd{
		Name:  "cli-version",
		Short: "Output program version string",
		Flags: versionFlags,
		Exec:  versionExec,
	},
}

Version is a command that displays the client version string.

Functions

func LoadConfig

func LoadConfig(set cfg.Set, filename string) error

LoadConfig loads the configuration file and applies migrations.

func NewConfigurableSet

func NewConfigurableSet() cfg.Set

NewConfigurableSet creates a new set of configurables.

func NewUseError

func NewUseError(msg string) error

NewUseError creates a new usage error.

func ReflectFieldDesc

func ReflectFieldDesc(d *desc.FieldDescriptor) string

ReflectFieldDesc returns a description a the gRPC field.

It will look for the field description extension if available.

func ReflectFieldRequired

func ReflectFieldRequired(d *desc.FieldDescriptor) bool

ReflectFieldRequired returns whether a gRPC field is required.

It will look for the field required extension if available.

func ReflectMethodDesc

func ReflectMethodDesc(d *desc.MethodDescriptor) string

ReflectMethodDesc returns a description a the gRPC method.

It will look for the method description extension if available.

func Resolver

func Resolver(c *script.Closure, sym script.SExp) (script.SExp, error)

Resolver resolves a symbol to its name unless it begins with a dollar sign.

This is convenient for shell scripting because you can do:

echo hello world

Instead of:

echo "hello world"

On the other hand you must prefix a symbol with a dollar sign to refer to it:

let str "hello world"
echo $str

func StackTrace

func StackTrace(err error) errors.StackTrace

StackTrace returns the stack trace from an error created using the github.com/pkg/errors package.

Types

type ArgReflector

type ArgReflector interface {
	Reflector

	// Parse parses the value for the field from a string.
	Parse(*desc.FieldDescriptor, string) (interface{}, error)
}

ArgReflector reflects values for a gRPC request from a command argument.

type BasicCmd

type BasicCmd struct {
	// Name is the name of the command, used to match a word to the command
	// amongst other things.
	Name string

	// Short is a short description of the command.
	Short string

	// Use is a short usage string, for example `help [command]`. If not
	// defined, the name of the command will be used.
	Use string

	// Flags can be defined to return a set of flags for the command.
	Flags func() *pflag.FlagSet

	// NoFlags disables flag parsing as well as the help flag.
	NoFlags bool

	// Exec is a function that executes the command against string
	// arguments and outputs to a writer.
	Exec func(*BasicContext) error
}

BasicCmd is designed for simple commands to just need to parse flags and output text.

type BasicCmdWrapper

type BasicCmdWrapper struct {
	Cmd BasicCmd
}

BasicCmdWrapper wraps a basic command to make it compatible with the Cmd interface. It also adds a help flag and deals with flag errors.

func (BasicCmdWrapper) Exec

func (cmd BasicCmdWrapper) Exec(ctx *script.InterpreterContext, cli CLI) (script.SExp, error)

Exec executes the basic command.

func (BasicCmdWrapper) Long

func (cmd BasicCmdWrapper) Long() string

Long returns the long description which is the short description followed by the long usage string of the command.

func (BasicCmdWrapper) LongUse

func (cmd BasicCmdWrapper) LongUse() string

LongUse returns the long usage string of the command which is the short usage string followed by the flags usage string.

func (BasicCmdWrapper) Match

func (cmd BasicCmdWrapper) Match(name string) bool

Match returns whether the string matches the command name.

func (BasicCmdWrapper) Name

func (cmd BasicCmdWrapper) Name() string

Name returns the name string.

func (BasicCmdWrapper) Short

func (cmd BasicCmdWrapper) Short() string

Short returns the short description string.

func (BasicCmdWrapper) Suggest

func (cmd BasicCmdWrapper) Suggest(c Content) []Suggest

Suggest suggests the command whenever of the command's text contains the word before the current position of cursor. It also makes suggestions for flags.

func (BasicCmdWrapper) Use

func (cmd BasicCmdWrapper) Use() string

Use returns the short usage string or the name string if not specified.

type BasicContext

type BasicContext struct {
	Ctx    context.Context
	CLI    CLI
	Writer io.Writer
	Args   []string
	Flags  *pflag.FlagSet
}

BasicContext is passed to Exec when executing a basic command.

type BasicReflector

type BasicReflector struct {
	// Zero is the zero value of the primitive type in a protocol buffer.
	Zero interface{}

	Checker ReflectChecker
	Encoder ReflectEncoder
	Decoder ReflectDecoder
}

BasicReflector is a reflector that covers most use cases.

func (BasicReflector) Flag

Flag adds a flag for the value to a flag set.

func (BasicReflector) Parse

func (r BasicReflector) Parse(d *desc.FieldDescriptor, s string) (interface{}, error)

Parse parses the value for the field from a string.

func (BasicReflector) ParseFlag

func (r BasicReflector) ParseFlag(d *desc.FieldDescriptor, f *pflag.FlagSet) (interface{}, error)

ParseFlag parses the value of the flag.

func (BasicReflector) Pretty

func (r BasicReflector) Pretty(d *desc.FieldDescriptor, v interface{}) (string, error)

Pretty returns a human friendly representation of the value.

func (BasicReflector) Supports

func (r BasicReflector) Supports(d *desc.FieldDescriptor) bool

Supports returns whether it can handle this type of field.

type CLI

type CLI interface {
	// Config returns the configuration.
	Config() Config

	// Console returns the console.
	Console() *Console

	// Commands returns all the commands.
	Commands() []Cmd

	// Address returns the address of the API server.
	Address() string

	// Connect connects to the API server.
	Connect(ctx context.Context, addr string) error

	// Disconnect closes the API client connection.
	Disconnect() error

	// Start starts the command line interface until the user kills it.
	Start(context.Context)

	// Exec executes the given input.
	Exec(ctx context.Context, in string) error

	// Run executes the given input, handling errors and cancellation
	// signals.
	Run(ctx context.Context, in string)

	// Suggest finds all command suggestions.
	Suggest(cnt Content) []Suggest

	// DidJustExecute returns true the first time it is called after a
	// command executed. This is a hack used by the VT100 prompt to hide
	// suggestions after a command was executed.
	DidJustExecute() bool
}

CLI represents a command line interface.

func New

func New(configSet cfg.ConfigSet) (CLI, error)

New create a new command line interface.

type Cmd

type Cmd interface {
	// Name returns the name of the command (used by `help command`
	// to find the command).
	Name() string

	// Short returns a short description of the command.
	Short() string

	// Long returns a long description of the command.
	Long() string

	// Use returns a short string showing how to use the command.
	Use() string

	// LongUse returns a long string showing how to use the command.
	LongUse() string

	// Suggest gives a chance for the command to add auto-complete
	// suggestions for the current content.
	Suggest(Content) []Suggest

	// Match returns whether the command can execute against the given
	// command name.
	Match(string) bool

	// Exec executes the commands.
	Exec(*script.InterpreterContext, CLI) (script.SExp, error)
}

Cmd is an interface that must be implemented by commands.

type Config

type Config struct {
	// ConfigVersion is the version of the configuration file.
	ConfigVersion int `toml:"configuration_version" comment:"The version of the configuration file."`

	// PromptBackend is the name of the prompt to use.
	PromptBackend string `toml:"prompt_backend" comment:"Which prompt backend to use (vt100, readline). VT100 is not available on Windows."`

	// EnableColorColor is whether to enable color output.
	EnableColorOutput bool `toml:"enable_color_output" comment:"Whether to display color output."`

	// APIAddress is the address of the gRPC API.
	APIAddress string `toml:"api_address" comment:"The address of the gRPC API."`

	// TLSCertificateFile is a path to a TLS certificate.
	TLSCertificateFile string `toml:"tls_certificate_file" comment:"Path to a TLS certificate."`

	// TLSServerNameOverride overrides the server name of the TLS authority.
	TLSServerNameOverride string `toml:"tls_server_name_override" comment:"Override the server name of the TLS authority (for testing only)."`

	// DialTimeout is the maximum duration allowed to dial the API.
	DialTimeout string `toml:"dial_timeout" comment:"The maximum allowed duration to dial the API."`

	// RequestTimeout is the maximum duration allowed for requests the API.
	RequestTimeout string `toml:"request_timeout" comment:"The maximum allowed duration for requests to the API."`

	// EnableDebugOutput if whether to display debug output.
	EnableDebugOutput bool `toml:"enable_debug_output" comment:"Whether to display debug output."`

	// InitScripts are the filenames of scripts that should be executed
	// after the CLI has started.
	InitScripts []string `toml:"init_scripts" comment:"Filenames of scripts that should be executed after the CLI has started."`
}

Config contains configuration options for the CLI.

type ConfigHandler

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

ConfigHandler implements cfg.Configurable for easy configuration management.

func (*ConfigHandler) Config

func (h *ConfigHandler) Config() interface{}

Config returns the current configuration or creates one with good defaults.

func (*ConfigHandler) ID

func (h *ConfigHandler) ID() string

ID returns the unique identifier of the configuration.

func (*ConfigHandler) SetConfig

func (h *ConfigHandler) SetConfig(config interface{}) error

SetConfig sets the configuration.

type Console

type Console struct {
	io.Writer
	// contains filtered or unexported fields
}

Console is a simple console with optional color output.

func NewConsole

func NewConsole(out io.Writer, color bool) *Console

NewConsole creates a new VT100 console.

func (*Console) Blue

func (c *Console) Blue()

Blue sets the text color to blue.

func (*Console) Debug

func (c *Console) Debug(v ...interface{})

Debug outputs gray text that will only be visible in debug mode.

func (*Console) Debugf

func (c *Console) Debugf(format string, v ...interface{})

Debugf outputs formatted gray text that will only be visible in debug mode.

func (*Console) Debugln

func (c *Console) Debugln(v ...interface{})

Debugln outputs a line of gray text that will only be visible in debug mode.

func (*Console) Error

func (c *Console) Error(v ...interface{})

Error outputs red text.

func (*Console) Errorf

func (c *Console) Errorf(format string, v ...interface{})

Errorf outputs formatted red text.

func (*Console) Errorln

func (c *Console) Errorln(v ...interface{})

Errorln outputs a line of red text.

func (*Console) Gray

func (c *Console) Gray()

Gray sets the text color to gray.

func (*Console) Green

func (c *Console) Green()

Green sets the text color to green.

func (*Console) Info

func (c *Console) Info(v ...interface{})

Info outputs blue text.

func (*Console) Infof

func (c *Console) Infof(format string, v ...interface{})

Infof outputs formatted blue text.

func (*Console) Infoln

func (c *Console) Infoln(v ...interface{})

Infoln outputs a line of blue text.

func (*Console) Print

func (c *Console) Print(v ...interface{})

Print outputs text.

func (*Console) Printf

func (c *Console) Printf(format string, v ...interface{})

Printf outputs formatted text.

func (*Console) Println

func (c *Console) Println(v ...interface{})

Println outputs a line of text.

func (*Console) Red

func (c *Console) Red()

Red sets the text color to red.

func (*Console) Reset

func (c *Console) Reset()

Reset resets the text color.

func (*Console) SetDebug

func (c *Console) SetDebug(debug bool)

SetDebug enables or disables debug output.

func (*Console) Success

func (c *Console) Success(v ...interface{})

Success outputs green text.

func (*Console) Successf

func (c *Console) Successf(format string, v ...interface{})

Successf outputs formatted green text.

func (*Console) Successln

func (c *Console) Successln(v ...interface{})

Successln outputs a line of green text.

func (*Console) Warning

func (c *Console) Warning(v ...interface{})

Warning outputs yellow text.

func (*Console) Warningf

func (c *Console) Warningf(format string, v ...interface{})

Warningf outputs formatted yellow text.

func (*Console) Warningln

func (c *Console) Warningln(v ...interface{})

Warningln outputs a line of yellow text.

func (*Console) Yellow

func (c *Console) Yellow()

Yellow sets the text color to yellow.

type ConsoleRPCEventListener

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

ConsoleRPCEventListener implements the EventListener interface. It connects to the RPC server's Listen endpoint and prints events to the console.

func (*ConsoleRPCEventListener) Connected

func (el *ConsoleRPCEventListener) Connected() bool

Connected returns true if the listener is connected to the event emitter and ready to receive events.

func (*ConsoleRPCEventListener) Start

Start connects to the corresponding event emitter and continuously listens for events and displays them. Start only allows a single connection to the RPC server. It will close the previous connection before starting a new one.

type Content

type Content interface {
	// TextBeforeCursor returns all the text before the cursor.
	TextBeforeCursor() string

	// GetWordBeforeCursor returns the word before the current cursor
	// position.
	GetWordBeforeCursor() string
}

Content represents console content used to find suggestions.

type EventListener

type EventListener interface {
	// Start connects to the corresponding event emitter and continuously
	// listens for events and displays them.
	// It disconnects from the event emitter when the context is cancelled.
	Start(context.Context) error

	// Connected returns true if the listener is connected to the event
	// emitter and ready to receive events.
	Connected() bool
}

EventListener is an interface that must be implemented by event listeners.

func NewConsoleClientEventListener

func NewConsoleClientEventListener(cons *Console, client pbevent.EmitterClient, sig Signaler) EventListener

NewConsoleClientEventListener creates a new ConsoleRPCEventListener for a given emitter client.

func NewConsoleRPCEventListener

func NewConsoleRPCEventListener(cons *Console, conn *grpc.ClientConn) EventListener

NewConsoleRPCEventListener creates a new ConsoleRPCEventListener connected to a given console and RPC Listen endpoint.

type FlagReflector

type FlagReflector interface {
	Reflector

	// Flag adds a flag for the value to a flag set.
	Flag(*desc.FieldDescriptor, *pflag.FlagSet)

	// ParseFlag parses the value of the flag.
	ParseFlag(*desc.FieldDescriptor, *pflag.FlagSet) (interface{}, error)
}

FlagReflector reflects values for a gRPC request from a command flag.

type ReflectChecker

type ReflectChecker func(*desc.FieldDescriptor) bool

ReflectChecker checks if a field is supported by the reflector.

type ReflectDecoder

type ReflectDecoder func(*desc.FieldDescriptor, string) (interface{}, error)

ReflectDecoder decodes a protobuf field value from a string.

type ReflectEncoder

type ReflectEncoder func(*desc.FieldDescriptor, interface{}) (string, error)

ReflectEncoder encodes a protobuf field value to a string.

type Reflector

type Reflector interface {
	// Supports returns whether it can handle this field.
	Supports(*desc.FieldDescriptor) bool
}

Reflector reflects gRPC fields.

func NewBase58Reflector

func NewBase58Reflector() Reflector

NewBase58Reflector creates a new base58 reflector.

func NewBlockchainBlocksReflector

func NewBlockchainBlocksReflector() Reflector

NewBlockchainBlocksReflector creates a reflector for blockchains blocks.

func NewBlockchainTransactionsReflector

func NewBlockchainTransactionsReflector() Reflector

NewBlockchainTransactionsReflector creates a reflector for blockchains transactions.

func NewBoolReflector

func NewBoolReflector() Reflector

NewBoolReflector creates a new bool reflector.

func NewByterateReflector

func NewByterateReflector() Reflector

NewByterateReflector creates a new byterate reflector.

func NewBytesReflector

func NewBytesReflector() Reflector

NewBytesReflector creates a new bytes reflector.

func NewBytesizeReflector

func NewBytesizeReflector() Reflector

NewBytesizeReflector creates a new bytesize reflector.

func NewDurationReflector

func NewDurationReflector() Reflector

NewDurationReflector creates a new duration reflector.

func NewEnumReflector

func NewEnumReflector() Reflector

NewEnumReflector creates a new enum reflector.

func NewInt32Reflector

func NewInt32Reflector() Reflector

NewInt32Reflector creates a new int32 reflector.

func NewInt64Reflector

func NewInt64Reflector() Reflector

NewInt64Reflector creates a new int64 reflector.

func NewMaddrReflector

func NewMaddrReflector() Reflector

NewMaddrReflector creates a new multiaddr reflector.

func NewStringReflector

func NewStringReflector() Reflector

NewStringReflector creates a new string reflector.

func NewTimeReflector

func NewTimeReflector() Reflector

NewTimeReflector creates a new duration reflector.

func NewUint32Reflector

func NewUint32Reflector() Reflector

NewUint32Reflector creates a new uint32 reflector.

func NewUint64Reflector

func NewUint64Reflector() Reflector

NewUint64Reflector creates a new uint64 reflector.

type ResponseReflector

type ResponseReflector interface {
	Reflector

	// Pretty returns a human friendly representation of the value.
	Pretty(*desc.FieldDescriptor, interface{}) (string, error)
}

ResponseReflector reflects values of a gRPC request.

type Rline

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

Rline implements a quick-and-dirty prompt using readline.

func NewRline

func NewRline(cli CLI) *Rline

NewRline creates a new readline prompt.

func (*Rline) Do

func (p *Rline) Do(line []rune, pos int) (newLine [][]rune, length int)

Do finds suggestions.

func (*Rline) GetWordBeforeCursor

func (p *Rline) GetWordBeforeCursor() string

GetWordBeforeCursor return the word before the current cursor position.

func (*Rline) Run

func (p *Rline) Run(ctx context.Context, rc io.ReadCloser)

Run launches the prompt until it is killed.

func (*Rline) TextBeforeCursor

func (p *Rline) TextBeforeCursor() string

TextBeforeCursor returns the content of the line before the the current cursor position.

type ServerReflector

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

ServerReflector reflects commands from a gRPC server.

The server must have the reflection service enabled.

Currently, it is able to reflect commands for methods that use the following field types:

  • String
  • Bool
  • Int32, Uint32, Int64, Uint64
  • Bytes
  • Enum
  • Time extension (int64 nano Unix timestamp)
  • Duration extension (int64)
  • Base58 extension (bytes)
  • Bytesize extension (uint64)
  • Byterate extension (uint64)
  • Multiaddr extension (bytes)

It also supports repeated fields for all these types.

In addition, it supports custom help strings for methods and fields using extensions.

Adding new types is trivial and missing types will be added as needed.

func NewServerReflector

func NewServerReflector(cons *Console, termWidth int, reflectors ...Reflector) ServerReflector

NewServerReflector reflects commands from a gRPC server.

When reflecting fields, the first reflector that supports it is used. This means that the more specific reflectors should be passed first.

If no reflectors are given, DefReflectors is used.

func (ServerReflector) Reflect

func (r ServerReflector) Reflect(ctx context.Context, conn *grpc.ClientConn) ([]Cmd, error)

Reflect reflects the command of a server and returns commands for them.

type ServerStream

type ServerStream interface {
	// RecvMsg receives a protobuf message.
	RecvMsg() (proto.Message, error)
}

ServerStream is an interface to receive messages from a streaming server.

type Signaler

type Signaler interface {
	// Signal sends a signal to the OS.
	Signal(os.Signal) error
}

Signaler is an interface to send signals to the OS.

type Suggest

type Suggest struct {
	// Text is the text that will replace the current word.
	Text string

	// Desc is a short description of the suggestion.
	Desc string
}

Suggest implements a suggestion.

type UseError

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

UseError represents a usage error.

Make it a pointer receiver so that errors.Cause() can be used to retrieve and modify the use string after the error is created. This is actually being done by the executor after a command if it returns a usage error.

func (*UseError) Error

func (err *UseError) Error() string

Error returns the error message.

func (*UseError) Use

func (err *UseError) Use() string

Use returns the usage message.

Directories

Path Synopsis
grpc
ext
Package mockcli is a generated GoMock package.
Package mockcli is a generated GoMock package.

Jump to

Keyboard shortcuts

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