mirror of
https://github.com/ipfs/kubo.git
synced 2026-03-01 06:17:56 +08:00
Merge pull request #5786 from overbool/refactor/cmds/rm-old-lib
cmds: rm old lib
This commit is contained in:
commit
496f1d1230
@ -1,68 +0,0 @@
|
||||
/*
|
||||
Package commands provides an API for defining and parsing commands.
|
||||
|
||||
Supporting nested commands, options, arguments, etc. The commands
|
||||
package also supports a collection of marshallers for presenting
|
||||
output to the user, including text, JSON, and XML marshallers.
|
||||
*/
|
||||
|
||||
package commands
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
logging "gx/ipfs/QmcuXC5cxs79ro2cUuHs4HQ2bkDLJUYokwL8aivcX6HW3C/go-log"
|
||||
cmdkit "gx/ipfs/Qmde5VP1qUkyQXKCfmEUA7bP64V2HAptbJ7phuPp7jXWwg/go-ipfs-cmdkit"
|
||||
)
|
||||
|
||||
var log = logging.Logger("command")
|
||||
|
||||
// Function is the type of function that Commands use.
|
||||
// It reads from the Request, and writes results to the Response.
|
||||
type Function func(Request, Response)
|
||||
|
||||
// Marshaler is a function that takes in a Response, and returns an io.Reader
|
||||
// (or an error on failure)
|
||||
type Marshaler func(Response) (io.Reader, error)
|
||||
|
||||
// MarshalerMap is a map of Marshaler functions, keyed by EncodingType
|
||||
// (or an error on failure)
|
||||
type MarshalerMap map[EncodingType]Marshaler
|
||||
|
||||
// Command is a runnable command, with input arguments and options (flags).
|
||||
// It can also have Subcommands, to group units of work into sets.
|
||||
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 Function
|
||||
Marshalers map[EncodingType]Marshaler
|
||||
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
|
||||
}
|
||||
|
||||
// Subcommand returns the subcommand with the given id
|
||||
func (c *Command) Subcommand(id string) *Command {
|
||||
return c.Subcommands[id]
|
||||
}
|
||||
|
||||
func ClientError(msg string) error {
|
||||
return &cmdkit.Error{Code: cmdkit.ErrClient, Message: msg}
|
||||
}
|
||||
@ -11,11 +11,13 @@ import (
|
||||
coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
|
||||
|
||||
config "gx/ipfs/QmXctaABKwgzmQgNM4bucMJf7zJnxxvhmPM1Pw95dxUfB5/go-ipfs-config"
|
||||
files "gx/ipfs/QmZMWMvWMVKCbHetJ4RgndbuEF1io2UpUxwQwtNjtYPzSC/go-ipfs-files"
|
||||
"gx/ipfs/Qma6uuSyjkecGhMFFLfzyJDPyoDtNJSHJNweDccZhaWkgU/go-ipfs-cmds"
|
||||
"gx/ipfs/Qmde5VP1qUkyQXKCfmEUA7bP64V2HAptbJ7phuPp7jXWwg/go-ipfs-cmdkit"
|
||||
logging "gx/ipfs/QmcuXC5cxs79ro2cUuHs4HQ2bkDLJUYokwL8aivcX6HW3C/go-log"
|
||||
)
|
||||
|
||||
var log = logging.Logger("command")
|
||||
|
||||
// Context represents request context
|
||||
type Context struct {
|
||||
Online bool
|
||||
ConfigRoot string
|
||||
@ -55,9 +57,9 @@ func (c *Context) GetNode() (*core.IpfsNode, error) {
|
||||
return c.node, err
|
||||
}
|
||||
|
||||
// GetApi returns CoreAPI instance backed by ipfs node.
|
||||
// GetAPI returns CoreAPI instance backed by ipfs node.
|
||||
// It may construct the node with the provided function
|
||||
func (c *Context) GetApi() (coreiface.CoreAPI, error) {
|
||||
func (c *Context) GetAPI() (coreiface.CoreAPI, error) {
|
||||
if c.api == nil {
|
||||
n, err := c.GetNode()
|
||||
if err != nil {
|
||||
@ -109,16 +111,3 @@ func (c *Context) Close() {
|
||||
c.node.Close()
|
||||
}
|
||||
}
|
||||
|
||||
// Request represents a call to a command from a consumer
|
||||
type Request interface {
|
||||
Path() []string
|
||||
Option(name string) *cmdkit.OptionValue
|
||||
Options() cmdkit.OptMap
|
||||
Arguments() []string
|
||||
StringArguments() []string
|
||||
Files() files.File
|
||||
Context() context.Context
|
||||
InvocContext() *Context
|
||||
Command() *Command
|
||||
}
|
||||
@ -1,68 +0,0 @@
|
||||
package legacy
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
oldcmds "github.com/ipfs/go-ipfs/commands"
|
||||
|
||||
"gx/ipfs/Qma6uuSyjkecGhMFFLfzyJDPyoDtNJSHJNweDccZhaWkgU/go-ipfs-cmds"
|
||||
logging "gx/ipfs/QmcuXC5cxs79ro2cUuHs4HQ2bkDLJUYokwL8aivcX6HW3C/go-log"
|
||||
)
|
||||
|
||||
var log = logging.Logger("cmds/lgc")
|
||||
|
||||
// NewCommand returns a Command from an oldcmds.Command
|
||||
func NewCommand(oldcmd *oldcmds.Command) *cmds.Command {
|
||||
if oldcmd == nil {
|
||||
return nil
|
||||
}
|
||||
var cmd *cmds.Command
|
||||
|
||||
cmd = &cmds.Command{
|
||||
Options: oldcmd.Options,
|
||||
Arguments: oldcmd.Arguments,
|
||||
Helptext: oldcmd.Helptext,
|
||||
External: oldcmd.External,
|
||||
Type: oldcmd.Type,
|
||||
|
||||
Subcommands: make(map[string]*cmds.Command),
|
||||
}
|
||||
|
||||
if oldcmd.Run != nil {
|
||||
cmd.Run = func(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment) error {
|
||||
oldReq := &requestWrapper{req, OldContext(env)}
|
||||
res := &fakeResponse{req: oldReq, re: re, wait: make(chan struct{})}
|
||||
|
||||
errCh := make(chan error)
|
||||
go res.Send(errCh)
|
||||
|
||||
oldcmd.Run(oldReq, res)
|
||||
return <-errCh
|
||||
}
|
||||
}
|
||||
|
||||
if oldcmd.PreRun != nil {
|
||||
cmd.PreRun = func(req *cmds.Request, env cmds.Environment) error {
|
||||
oldReq := &requestWrapper{req, OldContext(env)}
|
||||
return oldcmd.PreRun(oldReq)
|
||||
}
|
||||
}
|
||||
|
||||
for name, sub := range oldcmd.Subcommands {
|
||||
cmd.Subcommands[name] = NewCommand(sub)
|
||||
}
|
||||
|
||||
cmd.Encoders = make(cmds.EncoderMap)
|
||||
|
||||
for encType, m := range oldcmd.Marshalers {
|
||||
cmd.Encoders[cmds.EncodingType(encType)] = func(m oldcmds.Marshaler, encType oldcmds.EncodingType) func(req *cmds.Request) func(io.Writer) cmds.Encoder {
|
||||
return func(req *cmds.Request) func(io.Writer) cmds.Encoder {
|
||||
return func(w io.Writer) cmds.Encoder {
|
||||
return NewMarshalerEncoder(req, m, w)
|
||||
}
|
||||
}
|
||||
}(m, encType)
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
@ -1,57 +0,0 @@
|
||||
package legacy
|
||||
|
||||
import (
|
||||
"io"
|
||||
"runtime/debug"
|
||||
|
||||
"gx/ipfs/Qma6uuSyjkecGhMFFLfzyJDPyoDtNJSHJNweDccZhaWkgU/go-ipfs-cmds"
|
||||
|
||||
oldcmds "github.com/ipfs/go-ipfs/commands"
|
||||
)
|
||||
|
||||
// MarshalerEncoder implements Encoder from a Marshaler
|
||||
type MarshalerEncoder struct {
|
||||
m oldcmds.Marshaler
|
||||
w io.Writer
|
||||
req *cmds.Request
|
||||
}
|
||||
|
||||
// NewMarshalerEncoder returns a new MarshalerEncoder
|
||||
func NewMarshalerEncoder(req *cmds.Request, m oldcmds.Marshaler, w io.Writer) *MarshalerEncoder {
|
||||
me := &MarshalerEncoder{
|
||||
m: m,
|
||||
w: w,
|
||||
req: req,
|
||||
}
|
||||
|
||||
return me
|
||||
}
|
||||
|
||||
// Encode encodes v onto the io.Writer w using Marshaler m, with both m and w passed in NewMarshalerEncoder
|
||||
func (me *MarshalerEncoder) Encode(v interface{}) error {
|
||||
re, res := cmds.NewChanResponsePair(me.req)
|
||||
go re.Emit(v)
|
||||
|
||||
r, err := me.m(&responseWrapper{Response: res})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if r == nil {
|
||||
// behave like empty reader
|
||||
return nil
|
||||
}
|
||||
|
||||
_, err = io.Copy(me.w, r)
|
||||
return err
|
||||
}
|
||||
|
||||
// OldContext tries to cast the environment as a legacy command context,
|
||||
// returning nil on failure.
|
||||
func OldContext(env interface{}) *oldcmds.Context {
|
||||
ctx, ok := env.(*oldcmds.Context)
|
||||
if !ok {
|
||||
log.Errorf("OldContext: env passed is not %T but %T\n%s", ctx, env, debug.Stack())
|
||||
}
|
||||
|
||||
return ctx
|
||||
}
|
||||
@ -1,215 +0,0 @@
|
||||
package legacy
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
oldcmds "github.com/ipfs/go-ipfs/commands"
|
||||
cmds "gx/ipfs/Qma6uuSyjkecGhMFFLfzyJDPyoDtNJSHJNweDccZhaWkgU/go-ipfs-cmds"
|
||||
cmdkit "gx/ipfs/Qmde5VP1qUkyQXKCfmEUA7bP64V2HAptbJ7phuPp7jXWwg/go-ipfs-cmdkit"
|
||||
)
|
||||
|
||||
type WriteNopCloser struct {
|
||||
io.Writer
|
||||
}
|
||||
|
||||
func (wc WriteNopCloser) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestNewCommand(t *testing.T) {
|
||||
root := &cmds.Command{
|
||||
Subcommands: map[string]*cmds.Command{
|
||||
"test": NewCommand(&oldcmds.Command{
|
||||
Run: func(req oldcmds.Request, res oldcmds.Response) {
|
||||
res.SetOutput("Test.")
|
||||
},
|
||||
Marshalers: map[oldcmds.EncodingType]oldcmds.Marshaler{
|
||||
oldcmds.Text: func(res oldcmds.Response) (io.Reader, error) {
|
||||
ch, ok := res.Output().(<-chan interface{})
|
||||
if !ok {
|
||||
t.Fatalf("output is not <-chan interface{} but %T", ch)
|
||||
}
|
||||
|
||||
v := <-ch
|
||||
str, ok := v.(string)
|
||||
if !ok {
|
||||
t.Fatalf("read value is not string but %T", v)
|
||||
}
|
||||
|
||||
buf := bytes.NewBuffer(nil)
|
||||
_, err := io.WriteString(buf, str)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
return buf, nil
|
||||
},
|
||||
},
|
||||
Subcommands: map[string]*oldcmds.Command{
|
||||
"sub": &oldcmds.Command{
|
||||
Options: []cmdkit.Option{
|
||||
cmdkit.NewOption(cmdkit.String, "test", "t", "some random test flag"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
path := []string{"test"}
|
||||
req, err := cmds.NewRequest(context.TODO(), path, nil, nil, nil, root)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
buf := bytes.NewBuffer(nil)
|
||||
|
||||
// test calling "test" command
|
||||
testCmd := root.Subcommands["test"]
|
||||
|
||||
re, err := cmds.NewWriterResponseEmitter(WriteNopCloser{buf}, req)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var env oldcmds.Context
|
||||
|
||||
root.Call(req, re, &env)
|
||||
|
||||
expected := `"Test."
|
||||
`
|
||||
|
||||
if buf.String() != expected {
|
||||
t.Fatalf("expected string %#v but got %#v", expected, buf.String())
|
||||
}
|
||||
|
||||
// test getting subcommand
|
||||
subCmd := testCmd.Subcommands["sub"]
|
||||
if subCmd == nil {
|
||||
t.Fatal("got nil subcommand")
|
||||
}
|
||||
|
||||
if nOpts := len(subCmd.Options); nOpts != 1 {
|
||||
t.Fatalf("subcommand has %v options, expected 1", nOpts)
|
||||
}
|
||||
|
||||
opt := subCmd.Options[0]
|
||||
|
||||
if nNames := len(opt.Names()); nNames != 2 {
|
||||
t.Fatalf("option has %v names, expected 2", nNames)
|
||||
}
|
||||
|
||||
names := opt.Names()
|
||||
if names[0] != "test" {
|
||||
t.Fatalf("option has name %q, expected %q", names[0], "test")
|
||||
}
|
||||
|
||||
if names[1] != "t" {
|
||||
t.Fatalf("option has name %q, expected %q", names[1], "t")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPipePair(t *testing.T) {
|
||||
cmd := NewCommand(&oldcmds.Command{Type: "string"})
|
||||
|
||||
req, err := cmds.NewRequest(context.TODO(), nil, nil, nil, nil, cmd)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
r, w := io.Pipe()
|
||||
re, err := cmds.NewWriterResponseEmitter(w, req)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
res, err := cmds.NewReaderResponse(r, req)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
wait := make(chan interface{})
|
||||
|
||||
expect := "abc"
|
||||
go func() {
|
||||
err := re.Emit(expect)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = re.Close()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
close(wait)
|
||||
}()
|
||||
|
||||
v, err := res.Next()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
str, ok := v.(*string)
|
||||
if !ok {
|
||||
t.Fatalf("expected type %T but got %T", expect, v)
|
||||
}
|
||||
if *str != expect {
|
||||
t.Fatalf("expected value %#v but got %#v", expect, v)
|
||||
}
|
||||
|
||||
_, err = res.Next()
|
||||
if err != io.EOF {
|
||||
t.Fatal("expected io.EOF, got:", err)
|
||||
}
|
||||
|
||||
<-wait
|
||||
}
|
||||
|
||||
func TestChanPair(t *testing.T) {
|
||||
cmd := NewCommand(&oldcmds.Command{Type: "string"})
|
||||
|
||||
req, err := cmds.NewRequest(context.TODO(), nil, nil, nil, nil, cmd)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
re, res := cmds.NewChanResponsePair(req)
|
||||
|
||||
wait := make(chan interface{})
|
||||
|
||||
expect := "abc"
|
||||
go func() {
|
||||
err := re.Emit(expect)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = re.Close()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
close(wait)
|
||||
}()
|
||||
|
||||
v, err := res.Next()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
str, ok := v.(string)
|
||||
if !ok {
|
||||
t.Fatalf("expected type %T but got %T", expect, v)
|
||||
}
|
||||
if str != expect {
|
||||
t.Fatalf("expected value %#v but got %#v", expect, v)
|
||||
}
|
||||
|
||||
_, err = res.Next()
|
||||
if err != io.EOF {
|
||||
t.Fatal("expected io.EOF, got:", err)
|
||||
}
|
||||
|
||||
<-wait
|
||||
}
|
||||
@ -1,196 +0,0 @@
|
||||
package legacy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"reflect"
|
||||
|
||||
files "gx/ipfs/QmZMWMvWMVKCbHetJ4RgndbuEF1io2UpUxwQwtNjtYPzSC/go-ipfs-files"
|
||||
"gx/ipfs/Qma6uuSyjkecGhMFFLfzyJDPyoDtNJSHJNweDccZhaWkgU/go-ipfs-cmds"
|
||||
"gx/ipfs/Qmde5VP1qUkyQXKCfmEUA7bP64V2HAptbJ7phuPp7jXWwg/go-ipfs-cmdkit"
|
||||
|
||||
oldcmds "github.com/ipfs/go-ipfs/commands"
|
||||
)
|
||||
|
||||
// requestWrapper implements a oldcmds.Request from an Request
|
||||
type requestWrapper struct {
|
||||
req *cmds.Request
|
||||
ctx *oldcmds.Context
|
||||
}
|
||||
|
||||
func (r *requestWrapper) String() string {
|
||||
return fmt.Sprintf("{%v, %v}", r.req, r.ctx)
|
||||
}
|
||||
|
||||
func (r *requestWrapper) GoString() string {
|
||||
return fmt.Sprintf("lgc.Request{%#v, %#v}", r.req, r.ctx)
|
||||
}
|
||||
|
||||
// InvocContext retuns the invocation context of the oldcmds.Request.
|
||||
// It is faked using OldContext().
|
||||
func (r *requestWrapper) InvocContext() *oldcmds.Context {
|
||||
return r.ctx
|
||||
}
|
||||
|
||||
// SetInvocContext sets the invocation context. First the context is converted
|
||||
// to a Context using NewContext().
|
||||
func (r *requestWrapper) SetInvocContext(ctx oldcmds.Context) {
|
||||
r.ctx = &ctx
|
||||
}
|
||||
|
||||
// Command is an empty stub.
|
||||
func (r *requestWrapper) Command() *oldcmds.Command { return nil }
|
||||
|
||||
func (r *requestWrapper) Arguments() []string {
|
||||
cmdArgs := r.req.Command.Arguments
|
||||
reqArgs := r.req.Arguments
|
||||
|
||||
// TODO figure out the exaclt policy for when to use these automatically
|
||||
// TODO once that's done, change the log.Debug below to log.Error
|
||||
// read arguments from body if we don't have all of them or the command has variadic arguemnts
|
||||
if len(reqArgs) < len(cmdArgs) ||
|
||||
len(cmdArgs) > 0 && cmdArgs[len(cmdArgs)-1].Variadic {
|
||||
err := r.req.ParseBodyArgs()
|
||||
if err != nil {
|
||||
log.Debug("error reading arguments from stdin: ", err)
|
||||
}
|
||||
}
|
||||
return r.req.Arguments
|
||||
}
|
||||
|
||||
func (r *requestWrapper) Context() context.Context {
|
||||
return r.req.Context
|
||||
}
|
||||
|
||||
func (r *requestWrapper) ConvertOptions() error {
|
||||
return convertOptions(r.req)
|
||||
}
|
||||
|
||||
func (r *requestWrapper) Files() files.File {
|
||||
return r.req.Files
|
||||
}
|
||||
|
||||
func (r *requestWrapper) Option(name string) *cmdkit.OptionValue {
|
||||
var option cmdkit.Option
|
||||
|
||||
optDefs, err := r.req.Root.GetOptions(r.req.Path)
|
||||
if err != nil {
|
||||
return &cmdkit.OptionValue{}
|
||||
}
|
||||
for _, def := range optDefs {
|
||||
for _, optName := range def.Names() {
|
||||
if name == optName {
|
||||
option = def
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if option == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// try all the possible names, break if we find a value
|
||||
for _, n := range option.Names() {
|
||||
val, found := r.req.Options[n]
|
||||
if found {
|
||||
return &cmdkit.OptionValue{
|
||||
Value: val,
|
||||
ValueFound: found,
|
||||
Def: option,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &cmdkit.OptionValue{
|
||||
Value: option.Default(),
|
||||
ValueFound: false,
|
||||
Def: option,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *requestWrapper) Options() cmdkit.OptMap {
|
||||
return r.req.Options
|
||||
}
|
||||
|
||||
func (r *requestWrapper) Path() []string {
|
||||
return r.req.Path
|
||||
}
|
||||
|
||||
func (r *requestWrapper) SetArguments(args []string) {
|
||||
r.req.Arguments = args
|
||||
}
|
||||
|
||||
func (r *requestWrapper) SetFiles(f files.File) {
|
||||
r.req.Files = f
|
||||
}
|
||||
|
||||
func (r *requestWrapper) SetOption(name string, v interface{}) {
|
||||
r.req.SetOption(name, v)
|
||||
}
|
||||
|
||||
func (r *requestWrapper) SetOptions(om cmdkit.OptMap) error {
|
||||
r.req.Options = om
|
||||
return convertOptions(r.req)
|
||||
}
|
||||
|
||||
func (r *requestWrapper) Stdin() io.Reader {
|
||||
return os.Stdin
|
||||
}
|
||||
|
||||
func (r *requestWrapper) StringArguments() []string {
|
||||
return r.req.Arguments
|
||||
}
|
||||
|
||||
func (r *requestWrapper) Values() map[string]interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
// copied from go-ipfs-cmds/request.go
|
||||
func convertOptions(req *cmds.Request) error {
|
||||
optDefSlice := req.Command.Options
|
||||
|
||||
optDefs := make(map[string]cmdkit.Option)
|
||||
for _, def := range optDefSlice {
|
||||
for _, name := range def.Names() {
|
||||
optDefs[name] = def
|
||||
}
|
||||
}
|
||||
|
||||
for k, v := range req.Options {
|
||||
opt, ok := optDefs[k]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
kind := reflect.TypeOf(v).Kind()
|
||||
if kind != opt.Type() {
|
||||
if str, ok := v.(string); ok {
|
||||
val, err := opt.Parse(str)
|
||||
if err != nil {
|
||||
value := fmt.Sprintf("value %q", v)
|
||||
if len(str) == 0 {
|
||||
value = "empty value"
|
||||
}
|
||||
return fmt.Errorf("could not convert %q to type %q (for option %q)",
|
||||
value, opt.Type().String(), "-"+k)
|
||||
}
|
||||
req.Options[k] = val
|
||||
|
||||
} else {
|
||||
return fmt.Errorf("option %q should be type %q, but got type %q",
|
||||
k, opt.Type().String(), kind.String())
|
||||
}
|
||||
}
|
||||
|
||||
for _, name := range opt.Names() {
|
||||
if _, ok := req.Options[name]; name != k && ok {
|
||||
return fmt.Errorf("duplicate command options were provided (%q and %q)",
|
||||
k, name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -1,207 +0,0 @@
|
||||
package legacy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"os"
|
||||
"reflect"
|
||||
"sync"
|
||||
|
||||
"gx/ipfs/Qma6uuSyjkecGhMFFLfzyJDPyoDtNJSHJNweDccZhaWkgU/go-ipfs-cmds"
|
||||
"gx/ipfs/Qmde5VP1qUkyQXKCfmEUA7bP64V2HAptbJ7phuPp7jXWwg/go-ipfs-cmdkit"
|
||||
|
||||
oldcmds "github.com/ipfs/go-ipfs/commands"
|
||||
)
|
||||
|
||||
// responseWrapper wraps Response and implements olcdms.Response.
|
||||
// It embeds a Response so some methods are taken from that.
|
||||
type responseWrapper struct {
|
||||
cmds.Response
|
||||
|
||||
out interface{}
|
||||
}
|
||||
|
||||
// Request returns a (faked) oldcmds.Request
|
||||
func (rw *responseWrapper) Request() oldcmds.Request {
|
||||
return &requestWrapper{rw.Response.Request(), nil}
|
||||
}
|
||||
|
||||
// Output returns either a <-chan interface{} on which you can receive the
|
||||
// emitted values, or an emitted io.Reader
|
||||
func (rw *responseWrapper) Output() interface{} {
|
||||
//if not called before
|
||||
if rw.out == nil {
|
||||
// get first emitted value
|
||||
x, err := rw.Next()
|
||||
if err != nil {
|
||||
ch := make(chan interface{})
|
||||
log.Error(err)
|
||||
close(ch)
|
||||
return (<-chan interface{})(ch)
|
||||
}
|
||||
if e, ok := x.(*cmdkit.Error); ok {
|
||||
ch := make(chan interface{})
|
||||
log.Error(e)
|
||||
close(ch)
|
||||
return (<-chan interface{})(ch)
|
||||
}
|
||||
|
||||
switch v := x.(type) {
|
||||
case io.Reader:
|
||||
// if it's a reader, set it
|
||||
rw.out = v
|
||||
case cmds.Single:
|
||||
rw.out = v.Value
|
||||
default:
|
||||
// if it is something else, create a channel and copy values from next in there
|
||||
ch := make(chan interface{})
|
||||
rw.out = (<-chan interface{})(ch)
|
||||
|
||||
go func() {
|
||||
defer close(ch)
|
||||
ch <- v
|
||||
|
||||
for {
|
||||
v, err := rw.Next()
|
||||
|
||||
if err == io.EOF || err == context.Canceled {
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
ch <- v
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
// if we have it already, return existing value
|
||||
return rw.out
|
||||
}
|
||||
|
||||
// SetError is an empty stub
|
||||
func (rw *responseWrapper) SetError(error, cmdkit.ErrorType) {}
|
||||
|
||||
// SetOutput is an empty stub
|
||||
func (rw *responseWrapper) SetOutput(interface{}) {}
|
||||
|
||||
// SetLength is an empty stub
|
||||
func (rw *responseWrapper) SetLength(uint64) {}
|
||||
|
||||
// SetCloser is an empty stub
|
||||
func (rw *responseWrapper) SetCloser(io.Closer) {}
|
||||
|
||||
// Close is an empty stub
|
||||
func (rw *responseWrapper) Close() error { return nil }
|
||||
|
||||
// Marshal is an empty stub
|
||||
func (rw *responseWrapper) Marshal() (io.Reader, error) { return nil, nil }
|
||||
|
||||
// Reader is an empty stub
|
||||
func (rw *responseWrapper) Reader() (io.Reader, error) { return nil, nil }
|
||||
|
||||
// Stdout returns os.Stdout
|
||||
func (rw *responseWrapper) Stdout() io.Writer { return os.Stdout }
|
||||
|
||||
// Stderr returns os.Stderr
|
||||
func (rw *responseWrapper) Stderr() io.Writer { return os.Stderr }
|
||||
|
||||
// fakeResponse implements oldcmds.Response and takes a ResponseEmitter
|
||||
type fakeResponse struct {
|
||||
req oldcmds.Request
|
||||
re cmds.ResponseEmitter
|
||||
out interface{}
|
||||
wait chan struct{}
|
||||
once sync.Once
|
||||
}
|
||||
|
||||
// Send emits the value(s) stored in r.out on the ResponseEmitter
|
||||
func (r *fakeResponse) Send(errCh chan<- error) {
|
||||
defer close(errCh)
|
||||
|
||||
out := r.Output()
|
||||
|
||||
// don't emit nil or Single{nil}
|
||||
if out == nil || out == (cmds.Single{Value: nil}) {
|
||||
return
|
||||
}
|
||||
|
||||
errCh <- r.re.Emit(out)
|
||||
return
|
||||
}
|
||||
|
||||
// Request returns the oldcmds.Request that belongs to this Response
|
||||
func (r *fakeResponse) Request() oldcmds.Request {
|
||||
return r.req
|
||||
}
|
||||
|
||||
// SetError forwards the call to the underlying ResponseEmitter
|
||||
func (r *fakeResponse) SetError(err error, code cmdkit.ErrorType) {
|
||||
defer r.once.Do(func() { close(r.wait) })
|
||||
r.re.CloseWithError(cmdkit.Errorf(code, err.Error()))
|
||||
}
|
||||
|
||||
// Error is an empty stub
|
||||
func (r *fakeResponse) Error() *cmdkit.Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetOutput sets the output variable to the passed value
|
||||
func (r *fakeResponse) SetOutput(v interface{}) {
|
||||
t := reflect.TypeOf(v)
|
||||
_, isReader := v.(io.Reader)
|
||||
|
||||
if t != nil && t.Kind() != reflect.Chan && !isReader {
|
||||
v = cmds.Single{Value: v}
|
||||
}
|
||||
|
||||
r.out = v
|
||||
r.once.Do(func() { close(r.wait) })
|
||||
}
|
||||
|
||||
// Output returns the output variable
|
||||
func (r *fakeResponse) Output() interface{} {
|
||||
<-r.wait
|
||||
return r.out
|
||||
}
|
||||
|
||||
// SetLength forwards the call to the underlying ResponseEmitter
|
||||
func (r *fakeResponse) SetLength(l uint64) {
|
||||
r.re.SetLength(l)
|
||||
}
|
||||
|
||||
// Length is an empty stub
|
||||
func (r *fakeResponse) Length() uint64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
// Close forwards the call to the underlying ResponseEmitter
|
||||
func (r *fakeResponse) Close() error {
|
||||
return r.re.Close()
|
||||
}
|
||||
|
||||
// SetCloser is an empty stub
|
||||
func (r *fakeResponse) SetCloser(io.Closer) {}
|
||||
|
||||
// Reader is an empty stub
|
||||
func (r *fakeResponse) Reader() (io.Reader, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Marshal is an empty stub
|
||||
func (r *fakeResponse) Marshal() (io.Reader, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Stdout returns os.Stdout
|
||||
func (r *fakeResponse) Stdout() io.Writer {
|
||||
return os.Stdout
|
||||
}
|
||||
|
||||
// Stderr returns os.Stderr
|
||||
func (r *fakeResponse) Stderr() io.Writer {
|
||||
return os.Stderr
|
||||
}
|
||||
@ -1,7 +1,6 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
@ -34,22 +33,6 @@ type ReqLog struct {
|
||||
keep time.Duration
|
||||
}
|
||||
|
||||
// Add creates a ReqLogEntry from a request and adds it to the log
|
||||
func (rl *ReqLog) Add(req Request) *ReqLogEntry {
|
||||
rle := &ReqLogEntry{
|
||||
StartTime: time.Now(),
|
||||
Active: true,
|
||||
Command: strings.Join(req.Path(), "/"),
|
||||
Options: req.Options(),
|
||||
Args: req.StringArguments(),
|
||||
ID: rl.nextID,
|
||||
log: rl,
|
||||
}
|
||||
|
||||
rl.AddEntry(rle)
|
||||
return rle
|
||||
}
|
||||
|
||||
// AddEntry adds an entry to the log
|
||||
func (rl *ReqLog) AddEntry(rle *ReqLogEntry) {
|
||||
rl.lock.Lock()
|
||||
|
||||
@ -1,55 +0,0 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
cmdkit "gx/ipfs/Qmde5VP1qUkyQXKCfmEUA7bP64V2HAptbJ7phuPp7jXWwg/go-ipfs-cmdkit"
|
||||
)
|
||||
|
||||
// ErrorType signfies a category of errors
|
||||
type ErrorType uint
|
||||
|
||||
// EncodingType defines a supported encoding
|
||||
type EncodingType string
|
||||
|
||||
// Supported EncodingType constants.
|
||||
const (
|
||||
JSON = "json"
|
||||
XML = "xml"
|
||||
Protobuf = "protobuf"
|
||||
Text = "text"
|
||||
// TODO: support more encoding types
|
||||
)
|
||||
|
||||
// Response is the result of a command request. Handlers write to the response,
|
||||
// setting Error or Value. Response is returned to the client.
|
||||
type Response interface {
|
||||
Request() Request
|
||||
|
||||
// Set/Return the response Error
|
||||
SetError(err error, code cmdkit.ErrorType)
|
||||
Error() *cmdkit.Error
|
||||
|
||||
// Sets/Returns the response value
|
||||
SetOutput(interface{})
|
||||
Output() interface{}
|
||||
|
||||
// Sets/Returns the length of the output
|
||||
SetLength(uint64)
|
||||
Length() uint64
|
||||
|
||||
// underlying http connections need to be cleaned up, this is for that
|
||||
Close() error
|
||||
SetCloser(io.Closer)
|
||||
|
||||
// Marshal marshals out the response into a buffer. It uses the EncodingType
|
||||
// on the Request to chose a Marshaler (Codec).
|
||||
Marshal() (io.Reader, error)
|
||||
|
||||
// Gets a io.Reader that reads the marshalled output
|
||||
Reader() (io.Reader, error)
|
||||
|
||||
// Gets Stdout and Stderr, for writing to console without using SetOutput
|
||||
Stdout() io.Writer
|
||||
Stderr() io.Writer
|
||||
}
|
||||
@ -28,7 +28,7 @@ func GetApi(env cmds.Environment) (coreiface.CoreAPI, error) {
|
||||
return nil, fmt.Errorf("expected env to be of type %T, got %T", ctx, env)
|
||||
}
|
||||
|
||||
return ctx.GetApi()
|
||||
return ctx.GetAPI()
|
||||
}
|
||||
|
||||
// GetConfig extracts the config from the environment.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user