cmds

package module
v0.4.7 Latest Latest
Warning

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

Go to latest
Published: Oct 23, 2017 License: MIT Imports: 21 Imported by: 0

README

go-ipfs-cmds

standard-readme compliant

ipfs commands library

cmds offers tools for describing and calling commands both locally and remotely, as well as encoding, formatting and transferring the result. It is the successor of go-ipfs/commands and contains a legacy layer such that it can handle previously defined commands.

Based on go-ipfs/commands.

Documentation

https://godoc.org/github.com/ipfs/go-ipfs-cmds

Contribute

Feel free to join in. All welcome. Open an issue!

This repository falls under the IPFS Code of Conduct.

Want to hack on IPFS?

License

MIT

Documentation

Overview

Package cmds helps building both standalone and client-server applications.

Semantics

The basic building blocks are requests, commands, emitters and responses. A command consists of a description of the parameters and a function. The function is passed the request as well as an emitter as arguments. It does operations on the inputs and sends the results to the user by emitting them.

There are a number of emitters in this package and subpackages, but the user is free to create their own.

Commands

A command is a struct containing the commands help text, a description of the arguments and options, the command's processing function and a type to let the caller know what type will be emitted. Optionally one of the functions PostRun and Encoder may be defined that consumes the function's emitted values and generates a visual representation for e.g. the terminal. Encoders work on a value-by-value basis, while PostRun operates on the value stream.

Emitters

An emitter has the Emit method, that takes the command's function's output as an argument and passes it to the user.

type ResponseEmitter interface {
	io.Closer
	SetLength(length uint64)
	SetError(err interface{}, code cmdkit.ErrorType)
	Emit(value interface{}) error
}

The command's function does not know what kind of emitter it works with, so the same function may run locally or on a server, using an rpc interface. Emitters can also send errors using the SetError method.

The user-facing emitter usually is the cli emitter. Values emitter here will be printed to the terminal using either the Encoders or the PostRun function.

Responses

A response is a value that the user can read emitted values from.

type Response interface {
	Request() Request
	Error() *cmdkit.Error
	Length() uint64
	Next() (interface{}, error)
}

Responses have a method Next() that returns the next emitted value and an error value. If the last element has been received, the returned error value is io.EOF. If the application code has sent an error using SetError, the error ErrRcvdError is returned on next, indicating that the caller should call Error(). Depending on the reponse type, other errors may also occur.

Pipes

Pipes are pairs (emitter, response), such that a value emitted on the emitter can be received in the response value. Most builtin emitters are "pipe" emitters. The most prominent examples are the channel pipe and the http pipe.

The channel pipe is backed by a channel. The only error value returned by the response is io.EOF, which happens when the channel is closed.

The http pipe is backed by an http connection. The response can also return other errors, e.g. if there are errors on the network.

Examples

To get a better idea of what's going on, take a look at the examples at https://github.com/ipfs/go-ipfs-cmds/tree/master/examples.

Index

Constants

View Source
const (
	Undefined = ""

	JSON        = "json"
	XML         = "xml"
	Protobuf    = "protobuf"
	Text        = "text"
	TextNewline = "textnl"
	CLI         = "cli"
)

Supported EncodingType constants.

View Source
const DefaultOutputEncoding = JSON

Variables

View Source
var Decoders = map[EncodingType]func(w io.Reader) Decoder{
	XML: func(r io.Reader) Decoder {
		return xml.NewDecoder(r)
	},
	JSON: func(r io.Reader) Decoder {
		return json.NewDecoder(r)
	},
}
View Source
var Encoders = EncoderMap{
	XML: func(req Request) func(io.Writer) Encoder {
		return func(w io.Writer) Encoder { return xml.NewEncoder(w) }
	},
	JSON: func(req Request) func(io.Writer) Encoder {
		return func(w io.Writer) Encoder { return json.NewEncoder(w) }
	},
	Text: func(req Request) func(io.Writer) Encoder {
		return func(w io.Writer) Encoder { return TextEncoder{w: w} }
	},
	TextNewline: func(req Request) func(io.Writer) Encoder {
		return func(w io.Writer) Encoder { return TextEncoder{w: w, suffix: "\n"} }
	},
}
View Source
var ErrIncorrectType = errors.New("The command returned a value with a different type than expected")
View Source
var ErrNoFormatter = ClientError("This command cannot be formatted to plain text")
View Source
var ErrNotCallable = ClientError("This command can't be called directly. Try one of its subcommands.")

ErrNotCallable signals a command that cannot be called.

View Source
var (
	ErrRcvdError = fmt.Errorf("received command error")
)

Functions

func ClientError

func ClientError(msg string) error

func Copy

func Copy(re ResponseEmitter, res Response) error

Copy sends all values received on res to re. If res is closed, it closes re.

func EmitOnce added in v0.4.7

func EmitOnce(re ResponseEmitter, v interface{}) error

EmitOnce is a helper that emits a value wrapped in Single, to signal that this will be the only value sent.

func HandleError added in v0.4.4

func HandleError(err error, res Response, re ResponseEmitter) bool

HandleError handles the error from cmds.Response.Next(), it returns true if Next() should be called again

func MakeEncoder

func MakeEncoder(f func(Request, io.Writer, interface{}) error) func(Request) func(io.Writer) Encoder

func NewChanResponsePair

func NewChanResponsePair(req Request) (ResponseEmitter, Response)

func OldCommand

func OldCommand(cmd *Command) *oldcmds.Command

OldCommand returns an oldcmds.Command from a Command.

func OldContext

func OldContext(ctx Context) oldcmds.Context

OldContext returns an oldcmds.Context from a Context

func OldReqLog

func OldReqLog(newrl *ReqLog) *oldcmds.ReqLog

OldReqLog returns an oldcmds.ReqLog from a ReqLog

Types

type Any

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

func (*Any) Add

func (a *Any) Add(v interface{})

func (*Any) Interface

func (a *Any) Interface() interface{}

func (*Any) UnmarshalJSON

func (a *Any) UnmarshalJSON(data []byte) error

type Command

type Command struct {
	Options   []cmdkit.Option
	Arguments []cmdkit.Argument
	PreRun    func(req Request) error

	// Run is the function that processes the request to generate a response.
	// Note that when executing the command over the HTTP API you can only read
	// after writing when using multipart requests. The request body will not be
	// available for reading after the HTTP connection has been written to.
	Run      Function
	PostRun  PostRunMap
	Encoders EncoderMap
	Helptext cmdkit.HelpText

	// External denotes that a command is actually an external binary.
	// fewer checks and validations will be performed on such commands.
	External bool

	// Type describes the type of the output of the Command's Run Function.
	// In precise terms, the value of Type is an instance of the return type of
	// the Run Function.
	//
	// ie. If command Run returns &Block{}, then Command.Type == &Block{}
	Type           interface{}
	Subcommands    map[string]*Command
	OldSubcommands map[string]*oldcmds.Command
}

Command is a runnable command, with input arguments and options (flags). It can also have Subcommands, to group units of work into sets.

func NewCommand

func NewCommand(oldcmd *oldcmds.Command) *Command

NewCommand returns a Command from an oldcmds.Command

func (*Command) Call

func (c *Command) Call(req Request, re ResponseEmitter) (err error)

Call invokes the command for the given Request

func (*Command) CheckArguments

func (c *Command) CheckArguments(req Request) error

func (*Command) Get

func (c *Command) Get(path []string) (*Command, error)

Get resolves and returns the Command addressed by path

func (*Command) GetOptions

func (c *Command) GetOptions(path []string) (map[string]cmdkit.Option, error)

GetOptions returns the options in the given path of commands

func (*Command) ProcessHelp

func (c *Command) ProcessHelp()

func (*Command) Resolve

func (c *Command) Resolve(pth []string) ([]*Command, error)

Resolve returns the subcommands at the given path

func (*Command) Subcommand

func (c *Command) Subcommand(id string) *Command

Subcommand returns the subcommand with the given id

func (*Command) Walk

func (c *Command) Walk(visitor CommandVisitor)

Walks tree of all subcommands (including this one)

type CommandVisitor

type CommandVisitor func(*Command)

type Context

type Context struct {
	Online     bool
	ConfigRoot string
	ReqLog     *ReqLog

	LoadConfig func(path string) (*config.Config, error)

	ConstructNode func() (*core.IpfsNode, error)
	// contains filtered or unexported fields
}

func NewContext

func NewContext(ctx oldcmds.Context) Context

NewContext returns a Context from an oldcmds.Context

func (*Context) GetConfig

func (c *Context) GetConfig() (*config.Config, error)

GetConfig returns the config of the current Command exection context. It may load it with the providied function.

func (*Context) GetNode

func (c *Context) GetNode() (*core.IpfsNode, error)

GetNode returns the node of the current Command exection context. It may construct it with the provided function.

func (*Context) NodeWithoutConstructing

func (c *Context) NodeWithoutConstructing() *core.IpfsNode

NodeWithoutConstructing returns the underlying node variable so that clients may close it.

type Decoder

type Decoder interface {
	Decode(value interface{}) error
}

Decoder decodes values into value (which should be a pointer).

type Encoder

type Encoder interface {
	Encode(value interface{}) error
}

Encoder encodes values onto e.g. an io.Writer. Examples are json.Encoder and xml.Encoder.

type EncoderFunc added in v0.3.0

type EncoderFunc func(req Request) func(w io.Writer) Encoder

type EncoderMap added in v0.3.0

type EncoderMap map[EncodingType]EncoderFunc

type EncodingEmitter

type EncodingEmitter interface {
	ResponseEmitter

	SetEncoder(func(io.Writer) Encoder)
}

type EncodingType

type EncodingType string

EncodingType defines a supported encoding

func GetEncoding

func GetEncoding(req Request) EncodingType

GetEncoding returns the EncodingType set in a request, falling back to JSON

type Flusher

type Flusher interface {
	Flush() error
}

type Function

type Function func(Request, ResponseEmitter)

Function is the type of function that Commands use. It reads from the Request, and writes results to the ResponseEmitter.

type Head struct {
	Len uint64
	Err *cmdkit.Error
}

func (Head) Error

func (h Head) Error() *cmdkit.Error

func (Head) Length

func (h Head) Length() uint64
type Header interface {
	Head() Head
}

type MarshalerEncoder

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

MarshalerEncoder implements Encoder from a Marshaler

func NewMarshalerEncoder

func NewMarshalerEncoder(req Request, m oldcmds.Marshaler, w io.Writer) *MarshalerEncoder

NewMarshalerEncoder returns a new MarshalerEncoder

func (*MarshalerEncoder) Encode

func (me *MarshalerEncoder) Encode(v interface{}) error

Encode encodes v onto the io.Writer w using Marshaler m, with both m and w passed in NewMarshalerEncoder

type OptMap

type OptMap map[string]interface{}

type PostRunMap

PostRunMap is the map used in Command.PostRun.

type ReqLog

type ReqLog struct {
	Requests []*ReqLogEntry
	// contains filtered or unexported fields
}

func (*ReqLog) Add

func (rl *ReqLog) Add(req Request) *ReqLogEntry

func (*ReqLog) AddEntry

func (rl *ReqLog) AddEntry(rle *ReqLogEntry)

func (*ReqLog) ClearInactive

func (rl *ReqLog) ClearInactive()

func (*ReqLog) Finish

func (rl *ReqLog) Finish(rle *ReqLogEntry)

func (*ReqLog) Report

func (rl *ReqLog) Report() []*ReqLogEntry

Report generates a copy of all the entries in the requestlog

func (*ReqLog) SetKeepTime

func (rl *ReqLog) SetKeepTime(t time.Duration)

type ReqLogEntry

type ReqLogEntry struct {
	StartTime time.Time
	EndTime   time.Time
	Active    bool
	Command   string
	Options   map[string]interface{}
	Args      []string
	ID        int
}

func (*ReqLogEntry) Copy

func (r *ReqLogEntry) Copy() *ReqLogEntry

type Request

type Request interface {
	Path() []string
	Option(name string) *cmdkit.OptionValue
	Options() cmdkit.OptMap
	SetOption(name string, val interface{})
	SetOptions(opts cmdkit.OptMap) error
	Arguments() []string
	StringArguments() []string
	SetArguments([]string)
	Files() files.File
	SetFiles(files.File)
	Context() context.Context
	SetRootContext(context.Context) error
	InvocContext() *Context
	SetInvocContext(Context)
	Command() *Command
	Values() map[string]interface{}
	Stdin() io.Reader
	VarArgs(func(string) error) error

	ConvertOptions() error
}

Request represents a call to a command from a consumer

func NewEmptyRequest

func NewEmptyRequest() (Request, error)

NewEmptyRequest initializes an empty request

func NewRequest

func NewRequest(path []string, opts cmdkit.OptMap, args []string, file files.File, cmd *Command, optDefs map[string]cmdkit.Option) (Request, error)

NewRequest returns a request initialized with given arguments An non-nil error will be returned if the provided option values are invalid

func WrapOldRequest

func WrapOldRequest(r oldcmds.Request) Request

WrapOldRequest returns a faked Request from an oldcmds.Request.

type Response

type Response interface {
	Request() Request

	Error() *cmdkit.Error
	Length() uint64

	// Next returns the next emitted value.
	// The returned error can be a network or decoding error.
	// The error can also be ErrRcvdError if an error has been emitted.
	// In this case the emitted error can be accessed using the Error() method.
	Next() (interface{}, error)
	RawNext() (interface{}, error)
}

Response is the result of a command request. Response is returned to the client.

func NewReaderResponse

func NewReaderResponse(r io.Reader, encType EncodingType, req Request) Response

type ResponseEmitter

type ResponseEmitter interface {
	// closes http conn or channel
	io.Closer

	// SetLength sets the length of the output
	// err is an interface{} so we don't have to manually convert to error.
	SetLength(length uint64)

	// SetError sets the response error
	// err is an interface{} so we don't have to manually convert to error.
	SetError(err interface{}, code cmdkit.ErrorType)

	// Emit sends a value
	// if value is io.Reader we just copy that to the connection
	// other values are marshalled
	Emit(value interface{}) error
}

ResponseEmitter encodes and sends the command code's output to the client. It is all a command can write to.

func NewFlushForwarder

func NewFlushForwarder(re ResponseEmitter, f Flusher) ResponseEmitter

func NewTeeEmitter

func NewTeeEmitter(re1, re2 ResponseEmitter) ResponseEmitter

NewTeeEmitter creates a new ResponseEmitter. Writing to it will write to both the passed ResponseEmitters.

type Single added in v0.4.7

type Single struct {
	Value interface{}
}

Single can be used to signal to any ResponseEmitter that only one value will be emitted. This is important e.g. for the http.ResponseEmitter so it can set the HTTP headers appropriately.

func (Single) GoString added in v0.4.7

func (s Single) GoString() string

func (Single) String added in v0.4.7

func (s Single) String() string

type TeeError

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

func (TeeError) BothNil

func (err TeeError) BothNil() bool

func (TeeError) Error

func (err TeeError) Error() string

type TextEncoder

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

func (TextEncoder) Encode

func (e TextEncoder) Encode(v interface{}) error

type WriterResponseEmitter

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

func NewWriterResponseEmitter

func NewWriterResponseEmitter(w io.WriteCloser, req Request, enc func(Request) func(io.Writer) Encoder) *WriterResponseEmitter

func (*WriterResponseEmitter) Close

func (re *WriterResponseEmitter) Close() error

func (*WriterResponseEmitter) Emit

func (re *WriterResponseEmitter) Emit(v interface{}) error

func (*WriterResponseEmitter) Head

func (re *WriterResponseEmitter) Head() Head

func (*WriterResponseEmitter) SetEncoder added in v0.2.3

func (re *WriterResponseEmitter) SetEncoder(mkEnc func(io.Writer) Encoder)

func (*WriterResponseEmitter) SetError

func (re *WriterResponseEmitter) SetError(v interface{}, errType cmdkit.ErrorType)

func (*WriterResponseEmitter) SetLength

func (re *WriterResponseEmitter) SetLength(length uint64)

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

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