From 6fc049b59f4989e88bf059dac5fb39d8fd6282ab Mon Sep 17 00:00:00 2001 From: Overbool Date: Sat, 27 Oct 2018 12:26:17 +0800 Subject: [PATCH] commands/pin: use new cmds lib License: MIT Signed-off-by: Overbool --- core/commands/pin.go | 293 +++++++++++++++--------------------------- core/commands/root.go | 2 +- 2 files changed, 105 insertions(+), 190 deletions(-) diff --git a/core/commands/pin.go b/core/commands/pin.go index 8169b7cce..7f43b31e8 100644 --- a/core/commands/pin.go +++ b/core/commands/pin.go @@ -1,20 +1,19 @@ package commands import ( - "bytes" "context" "fmt" "io" "time" - cmds "github.com/ipfs/go-ipfs/commands" core "github.com/ipfs/go-ipfs/core" - e "github.com/ipfs/go-ipfs/core/commands/e" + cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv" iface "github.com/ipfs/go-ipfs/core/coreapi/interface" options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" corerepo "github.com/ipfs/go-ipfs/core/corerepo" pin "github.com/ipfs/go-ipfs/pin" + cmds "gx/ipfs/QmSXUokcP4TJpFfqozT69AVAYRtzXVMUjzQVkYX41R9Svs/go-ipfs-cmds" offline "gx/ipfs/QmPpnbwgAuvhUkA9jGooR88ZwZtTUHXXvoQNKdjZC6nYku/go-ipfs-exchange-offline" cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" bserv "gx/ipfs/QmVPeMNK9DfGLXDZzs2W4RoFWC9Zq1EnLGmLXtYtWrNdcW/go-blockservice" @@ -65,43 +64,36 @@ var addPinCmd = &cmds.Command{ cmdkit.BoolOption(pinProgressOptionName, "Show progress"), }, Type: AddPinOutput{}, - Run: func(req cmds.Request, res cmds.Response) { - n, err := req.InvocContext().GetNode() + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { + n, err := cmdenv.GetNode(env) if err != nil { - res.SetError(err, cmdkit.ErrNormal) - return + return err } - api, err := req.InvocContext().GetApi() + api, err := cmdenv.GetApi(env) if err != nil { - res.SetError(err, cmdkit.ErrNormal) - return + return err } defer n.Blockstore.PinLock().Unlock() // set recursive flag - recursive, _, err := req.Option(pinRecursiveOptionName).Bool() - if err != nil { - res.SetError(err, cmdkit.ErrNormal) - return - } - showProgress, _, _ := req.Option(pinProgressOptionName).Bool() + recursive, _ := req.Options[pinRecursiveOptionName].(bool) + showProgress, _ := req.Options[pinProgressOptionName].(bool) if !showProgress { - added, err := corerepo.Pin(n, api, req.Context(), req.Arguments(), recursive) + added, err := corerepo.Pin(n, api, req.Context, req.Arguments, recursive) if err != nil { - res.SetError(err, cmdkit.ErrNormal) - return + return err } - res.SetOutput(&AddPinOutput{Pins: cidsToStrings(added)}) - return + return res.Emit(&AddPinOutput{Pins: cidsToStrings(added)}) } out := make(chan interface{}) - res.SetOutput((<-chan interface{})(out)) + res.Emit(out) + v := new(dag.ProgressTracker) - ctx := v.DeriveContext(req.Context()) + ctx := v.DeriveContext(req.Context) type pinResult struct { pins []cid.Cid @@ -109,7 +101,7 @@ var addPinCmd = &cmds.Command{ } ch := make(chan pinResult, 1) go func() { - added, err := corerepo.Pin(n, api, ctx, req.Arguments(), recursive) + added, err := corerepo.Pin(n, api, ctx, req.Arguments, recursive) ch <- pinResult{pins: added, err: err} }() @@ -120,63 +112,49 @@ var addPinCmd = &cmds.Command{ select { case val := <-ch: if val.err != nil { - res.SetError(val.err, cmdkit.ErrNormal) - return + return val.err } if pv := v.Value(); pv != 0 { out <- &AddPinOutput{Progress: v.Value()} } out <- &AddPinOutput{Pins: cidsToStrings(val.pins)} - return + return nil case <-ticker.C: out <- &AddPinOutput{Progress: v.Value()} case <-ctx.Done(): log.Error(ctx.Err()) - res.SetError(ctx.Err(), cmdkit.ErrNormal) - return + return ctx.Err() } } - }, - Marshalers: cmds.MarshalerMap{ - cmds.Text: func(res cmds.Response) (io.Reader, error) { - v, err := unwrapOutput(res.Output()) - if err != nil { - return nil, err - } + return nil + }, + Encoders: cmds.EncoderMap{ + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *AddPinOutput) error { var added []string - switch out := v.(type) { - case *AddPinOutput: - if out.Pins != nil { - added = out.Pins - } else { - // this can only happen if the progress option is set - fmt.Fprintf(res.Stderr(), "Fetched/Processed %d nodes\r", out.Progress) - } - - if res.Error() != nil { - return nil, res.Error() - } - default: - return nil, e.TypeErr(out, v) + if out.Pins != nil { + added = out.Pins + } else { + // this can only happen if the progress option is set + return fmt.Errorf("Fetched/Processed %d nodes\r", out.Progress) } var pintype string - rec, found, _ := res.Request().Option("recursive").Bool() + rec, found := req.Options["recursive"].(bool) if rec || !found { pintype = "recursively" } else { pintype = "directly" } - buf := new(bytes.Buffer) for _, k := range added { - fmt.Fprintf(buf, "pinned %s %s\n", k, pintype) + fmt.Fprintf(w, "pinned %s %s\n", k, pintype) } - return buf, nil - }, + + return nil + }), }, } @@ -196,52 +174,34 @@ collected if needed. (By default, recursively. Use -r=false for direct pins.) cmdkit.BoolOption(pinRecursiveOptionName, "r", "Recursively unpin the object linked to by the specified object(s).").WithDefault(true), }, Type: PinOutput{}, - Run: func(req cmds.Request, res cmds.Response) { - n, err := req.InvocContext().GetNode() + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { + n, err := cmdenv.GetNode(env) if err != nil { - res.SetError(err, cmdkit.ErrNormal) - return + return err } - api, err := req.InvocContext().GetApi() + api, err := cmdenv.GetApi(env) if err != nil { - res.SetError(err, cmdkit.ErrNormal) - return + return err } // set recursive flag - recursive, _, err := req.Option(pinRecursiveOptionName).Bool() + recursive, _ := req.Options[pinRecursiveOptionName].(bool) + + removed, err := corerepo.Unpin(n, api, req.Context, req.Arguments, recursive) if err != nil { - res.SetError(err, cmdkit.ErrNormal) - return + return err } - removed, err := corerepo.Unpin(n, api, req.Context(), req.Arguments(), recursive) - if err != nil { - res.SetError(err, cmdkit.ErrNormal) - return - } - - res.SetOutput(&PinOutput{cidsToStrings(removed)}) + return res.Emit(&PinOutput{cidsToStrings(removed)}) }, - Marshalers: cmds.MarshalerMap{ - cmds.Text: func(res cmds.Response) (io.Reader, error) { - v, err := unwrapOutput(res.Output()) - if err != nil { - return nil, err + Encoders: cmds.EncoderMap{ + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *PinOutput) error { + for _, k := range out.Pins { + fmt.Fprintf(w, "unpinned %s\n", k) } - - added, ok := v.(*PinOutput) - if !ok { - return nil, e.TypeErr(added, v) - } - - buf := new(bytes.Buffer) - for _, k := range added.Pins { - fmt.Fprintf(buf, "unpinned %s\n", k) - } - return buf, nil - }, + return nil + }), }, } @@ -301,74 +261,58 @@ Example: cmdkit.StringOption(pinTypeOptionName, "t", "The type of pinned keys to list. Can be \"direct\", \"indirect\", \"recursive\", or \"all\".").WithDefault("all"), cmdkit.BoolOption(pinQuietOptionName, "q", "Write just hashes of objects."), }, - Run: func(req cmds.Request, res cmds.Response) { - n, err := req.InvocContext().GetNode() + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { + n, err := cmdenv.GetNode(env) if err != nil { - res.SetError(err, cmdkit.ErrNormal) - return + return err } - api, err := req.InvocContext().GetApi() + api, err := cmdenv.GetApi(env) if err != nil { - res.SetError(err, cmdkit.ErrNormal) - return + return err } - typeStr, _, err := req.Option(pinTypeOptionName).String() + typeStr, _ := req.Options[pinTypeOptionName].(string) if err != nil { - res.SetError(err, cmdkit.ErrNormal) - return + return err } switch typeStr { case "all", "direct", "indirect", "recursive": default: err = fmt.Errorf("invalid type '%s', must be one of {direct, indirect, recursive, all}", typeStr) - res.SetError(err, cmdkit.ErrClient) - return + return err } var keys map[string]RefKeyObject - if len(req.Arguments()) > 0 { - keys, err = pinLsKeys(req.Context(), req.Arguments(), typeStr, n, api) + if len(req.Arguments) > 0 { + keys, err = pinLsKeys(req.Context, req.Arguments, typeStr, n, api) } else { - keys, err = pinLsAll(req.Context(), typeStr, n) + keys, err = pinLsAll(req.Context, typeStr, n) } if err != nil { - res.SetError(err, cmdkit.ErrNormal) + return err } else { - res.SetOutput(&RefKeyList{Keys: keys}) + return res.Emit(&RefKeyList{Keys: keys}) } }, Type: RefKeyList{}, - Marshalers: cmds.MarshalerMap{ - cmds.Text: func(res cmds.Response) (io.Reader, error) { - v, err := unwrapOutput(res.Output()) - if err != nil { - return nil, err - } + Encoders: cmds.EncoderMap{ + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *RefKeyList) error { + quiet, _ := req.Options[pinQuietOptionName].(bool) - quiet, _, err := res.Request().Option(pinQuietOptionName).Bool() - if err != nil { - return nil, err - } - - keys, ok := v.(*RefKeyList) - if !ok { - return nil, e.TypeErr(keys, v) - } - out := new(bytes.Buffer) - for k, v := range keys.Keys { + for k, v := range out.Keys { if quiet { - fmt.Fprintf(out, "%s\n", k) + fmt.Fprintf(w, "%s\n", k) } else { - fmt.Fprintf(out, "%s %s\n", k, v.Type) + fmt.Fprintf(w, "%s %s\n", k, v.Type) } } - return out, nil - }, + + return nil + }), }, } @@ -394,54 +338,36 @@ new pin and removing the old one. cmdkit.BoolOption(pinUnpinOptionName, "Remove the old pin.").WithDefault(true), }, Type: PinOutput{}, - Run: func(req cmds.Request, res cmds.Response) { - api, err := req.InvocContext().GetApi() + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { + api, err := cmdenv.GetApi(env) if err != nil { - res.SetError(err, cmdkit.ErrNormal) - return + return err } - unpin, _, err := req.Option(pinUnpinOptionName).Bool() + unpin, _ := req.Options[pinUnpinOptionName].(bool) + + from, err := iface.ParsePath(req.Arguments[0]) if err != nil { - res.SetError(err, cmdkit.ErrNormal) - return + return err } - from, err := iface.ParsePath(req.Arguments()[0]) + to, err := iface.ParsePath(req.Arguments[1]) if err != nil { - res.SetError(err, cmdkit.ErrNormal) - return + return err } - to, err := iface.ParsePath(req.Arguments()[1]) + err = api.Pin().Update(req.Context, from, to, options.Pin.Unpin(unpin)) if err != nil { - res.SetError(err, cmdkit.ErrNormal) - return + return err } - err = api.Pin().Update(req.Context(), from, to, options.Pin.Unpin(unpin)) - if err != nil { - res.SetError(err, cmdkit.ErrNormal) - return - } - - res.SetOutput(&PinOutput{Pins: []string{from.String(), to.String()}}) + return res.Emit(&PinOutput{Pins: []string{from.String(), to.String()}}) }, - Marshalers: cmds.MarshalerMap{ - cmds.Text: func(res cmds.Response) (io.Reader, error) { - v, err := unwrapOutput(res.Output()) - if err != nil { - return nil, err - } - added, ok := v.(*PinOutput) - if !ok { - return nil, e.TypeErr(added, v) - } - - buf := new(bytes.Buffer) - fmt.Fprintf(buf, "updated %s to %s\n", added.Pins[0], added.Pins[1]) - return buf, nil - }, + Encoders: cmds.EncoderMap{ + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *PinOutput) error { + fmt.Fprintf(w, "updated %s to %s\n", out.Pins[0], out.Pins[1]) + return nil + }), }, } @@ -457,51 +383,40 @@ var verifyPinCmd = &cmds.Command{ cmdkit.BoolOption(pinVerboseOptionName, "Also write the hashes of non-broken pins."), cmdkit.BoolOption(pinQuietOptionName, "q", "Write just hashes of broken pins."), }, - Run: func(req cmds.Request, res cmds.Response) { - n, err := req.InvocContext().GetNode() + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { + n, err := cmdenv.GetNode(env) if err != nil { - res.SetError(err, cmdkit.ErrNormal) - return + return err } - verbose, _, _ := res.Request().Option(pinVerboseOptionName).Bool() - quiet, _, _ := res.Request().Option(pinQuietOptionName).Bool() + verbose, _ := req.Options[pinVerboseOptionName].(bool) + quiet, _ := req.Options[pinQuietOptionName].(bool) if verbose && quiet { - res.SetError(fmt.Errorf("the --verbose and --quiet options can not be used at the same time"), cmdkit.ErrNormal) + return fmt.Errorf("the --verbose and --quiet options can not be used at the same time") } opts := pinVerifyOpts{ explain: !quiet, includeOk: verbose, } - out := pinVerify(req.Context(), n, opts) + out := pinVerify(req.Context, n, opts) - res.SetOutput(out) + return res.Emit(out) }, Type: PinVerifyRes{}, - Marshalers: cmds.MarshalerMap{ - cmds.Text: func(res cmds.Response) (io.Reader, error) { - quiet, _, _ := res.Request().Option(pinQuietOptionName).Bool() + Encoders: cmds.EncoderMap{ + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *PinVerifyRes) error { + quiet, _ := req.Options[pinQuietOptionName].(bool) - out, err := unwrapOutput(res.Output()) - if err != nil { - return nil, err - } - r, ok := out.(*PinVerifyRes) - if !ok { - return nil, e.TypeErr(r, out) - } - - buf := &bytes.Buffer{} - if quiet && !r.Ok { - fmt.Fprintf(buf, "%s\n", r.Cid) + if quiet && !out.Ok { + fmt.Fprintf(w, "%s\n", out.Cid) } else if !quiet { - r.Format(buf) + out.Format(w) } - return buf, nil - }, + return nil + }), }, } diff --git a/core/commands/root.go b/core/commands/root.go index b3a54a249..fae0e5e3a 100644 --- a/core/commands/root.go +++ b/core/commands/root.go @@ -135,7 +135,7 @@ var rootSubcommands = map[string]*cmds.Command{ "mount": MountCmd, "name": name.NameCmd, "object": ocmd.ObjectCmd, - "pin": lgc.NewCommand(PinCmd), + "pin": PinCmd, "ping": PingCmd, "p2p": P2PCmd, "refs": lgc.NewCommand(RefsCmd),