From 204a53247c2b880ef378a1ecd43c20ab3b44026a Mon Sep 17 00:00:00 2001 From: Overbool Date: Sat, 27 Oct 2018 20:55:03 +0800 Subject: [PATCH 1/4] commands/refs: use new cmds License: MIT Signed-off-by: Overbool --- core/commands/refs.go | 110 ++++++++++++++++++++---------------------- core/commands/root.go | 8 +-- 2 files changed, 56 insertions(+), 62 deletions(-) diff --git a/core/commands/refs.go b/core/commands/refs.go index 5f5260be5b8..928f74fbc82 100644 --- a/core/commands/refs.go +++ b/core/commands/refs.go @@ -4,16 +4,19 @@ import ( "bytes" "context" "errors" + "fmt" "io" "strings" - cmds "github.com/ipfs/go-ipfs/commands" - "github.com/ipfs/go-ipfs/core" + oldcmds "github.com/ipfs/go-ipfs/commands" + core "github.com/ipfs/go-ipfs/core" + cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv" e "github.com/ipfs/go-ipfs/core/commands/e" cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" path "gx/ipfs/QmRG3XuGwT7GYuAqgWDJBKTzdaHMwAnc1x7J2KHEXNHxzG/go-path" ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format" + cmds "gx/ipfs/QmSXUokcP4TJpFfqozT69AVAYRtzXVMUjzQVkYX41R9Svs/go-ipfs-cmds" cmdkit "gx/ipfs/Qmde5VP1qUkyQXKCfmEUA7bP64V2HAptbJ7phuPp7jXWwg/go-ipfs-cmdkit" ) @@ -31,7 +34,7 @@ const ( ) // KeyListTextMarshaler outputs a KeyList as plaintext, one key per line -func KeyListTextMarshaler(res cmds.Response) (io.Reader, error) { +func KeyListTextMarshaler(res oldcmds.Response) (io.Reader, error) { out, err := unwrapOutput(res.Output()) if err != nil { return nil, err @@ -74,65 +77,37 @@ NOTE: List all references recursively by using the flag '-r'. cmdkit.BoolOption(refsRecursiveOptionName, "r", "Recursively list links of child nodes."), cmdkit.IntOption(refsMaxDepthOptionName, "Only for recursive refs, limits fetch and listing to the given depth").WithDefault(-1), }, - Run: func(req cmds.Request, res cmds.Response) { - ctx := req.Context() - n, err := req.InvocContext().GetNode() + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { + ctx := req.Context + n, err := cmdenv.GetNode(env) if err != nil { - res.SetError(err, cmdkit.ErrNormal) - return + return err } - unique, _, err := req.Option(refsUniqueOptionName).Bool() - if err != nil { - res.SetError(err, cmdkit.ErrNormal) - return - } - - recursive, _, err := req.Option(refsRecursiveOptionName).Bool() - if err != nil { - res.SetError(err, cmdkit.ErrNormal) - return - } - - maxDepth, _, err := req.Option(refsMaxDepthOptionName).Int() - if err != nil { - res.SetError(err, cmdkit.ErrNormal) - return - } + unique, _ := req.Options[refsUniqueOptionName].(bool) + recursive, _ := req.Options[refsRecursiveOptionName].(bool) + maxDepth, _ := req.Options[refsMaxDepthOptionName].(int) + edges, _ := req.Options[refsEdgesOptionName].(bool) + format, _ := req.Options[refsFormatOptionName].(string) if !recursive { maxDepth = 1 // write only direct refs } - format, _, err := req.Option(refsFormatOptionName).String() - if err != nil { - res.SetError(err, cmdkit.ErrNormal) - return - } - - edges, _, err := req.Option(refsEdgesOptionName).Bool() - if err != nil { - res.SetError(err, cmdkit.ErrNormal) - return - } if edges { if format != "" { - res.SetError(errors.New("using format argument with edges is not allowed"), - cmdkit.ErrClient) - return + return errors.New("using format argument with edges is not allowed") } format = " -> " } - objs, err := objectsForPaths(ctx, n, req.Arguments()) + objs, err := objectsForPaths(ctx, n, req.Arguments) if err != nil { - res.SetError(err, cmdkit.ErrNormal) - return + return err } out := make(chan interface{}) - res.SetOutput((<-chan interface{})(out)) go func() { defer close(out) @@ -156,9 +131,20 @@ NOTE: List all references recursively by using the flag '-r'. } } }() + + return res.Emit(out) + }, + Encoders: cmds.EncoderMap{ + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *RefWrapper) error { + if out.Err != "" { + return fmt.Errorf(out.Err) + } + fmt.Fprintln(w, out.Ref) + + return nil + }), }, - Marshalers: refsMarshallerMap, - Type: RefWrapper{}, + Type: RefWrapper{}, } var RefsLocalCmd = &cmds.Command{ @@ -169,23 +155,20 @@ Displays the hashes of all local objects. `, }, - Run: func(req cmds.Request, res cmds.Response) { - ctx := req.Context() - n, err := req.InvocContext().GetNode() + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { + ctx := req.Context + n, err := cmdenv.GetNode(env) if err != nil { - res.SetError(err, cmdkit.ErrNormal) - return + return err } // todo: make async allKeys, err := n.Blockstore.AllKeysChan(ctx) if err != nil { - res.SetError(err, cmdkit.ErrNormal) - return + return err } out := make(chan interface{}) - res.SetOutput((<-chan interface{})(out)) go func() { defer close(out) @@ -193,18 +176,29 @@ Displays the hashes of all local objects. for k := range allKeys { select { case out <- &RefWrapper{Ref: k.String()}: - case <-req.Context().Done(): + case <-req.Context.Done(): return } } }() + + return res.Emit(out) + }, + Encoders: cmds.EncoderMap{ + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *RefWrapper) error { + if out.Err != "" { + return fmt.Errorf(out.Err) + } + fmt.Fprintln(w, out.Ref) + + return nil + }), }, - Marshalers: refsMarshallerMap, - Type: RefWrapper{}, + Type: RefWrapper{}, } -var refsMarshallerMap = cmds.MarshalerMap{ - cmds.Text: func(res cmds.Response) (io.Reader, error) { +var refsMarshallerMap = oldcmds.MarshalerMap{ + cmds.Text: func(res oldcmds.Response) (io.Reader, error) { v, err := unwrapOutput(res.Output()) if err != nil { return nil, err diff --git a/core/commands/root.go b/core/commands/root.go index 654b0b7279e..4c0834e9d03 100644 --- a/core/commands/root.go +++ b/core/commands/root.go @@ -138,7 +138,7 @@ var rootSubcommands = map[string]*cmds.Command{ "pin": lgc.NewCommand(PinCmd), "ping": PingCmd, "p2p": P2PCmd, - "refs": lgc.NewCommand(RefsCmd), + "refs": RefsCmd, "resolve": ResolveCmd, "swarm": SwarmCmd, "tar": TarCmd, @@ -155,7 +155,7 @@ var RootRO = &cmds.Command{} var CommandsDaemonROCmd = CommandsCmd(RootRO) -var RefsROCmd = &oldcmds.Command{} +var RefsROCmd = &cmds.Command{} var rootROSubcommands = map[string]*cmds.Command{ "commands": CommandsDaemonROCmd, @@ -198,12 +198,12 @@ func init() { // sanitize readonly refs command *RefsROCmd = *RefsCmd - RefsROCmd.Subcommands = map[string]*oldcmds.Command{} + RefsROCmd.Subcommands = map[string]*cmds.Command{} // this was in the big map definition above before, // but if we leave it there lgc.NewCommand will be executed // before the value is updated (:/sanitize readonly refs command/) - rootROSubcommands["refs"] = lgc.NewCommand(RefsROCmd) + rootROSubcommands["refs"] = RefsROCmd Root.Subcommands = rootSubcommands From bd5be7efc8f76d3f1bfe2496c84944d019e25006 Mon Sep 17 00:00:00 2001 From: Overbool Date: Sat, 27 Oct 2018 22:52:24 +0800 Subject: [PATCH 2/4] commands/refs: drop goroutine License: MIT Signed-off-by: Overbool --- core/commands/refs.go | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/core/commands/refs.go b/core/commands/refs.go index 928f74fbc82..5a85bed1f95 100644 --- a/core/commands/refs.go +++ b/core/commands/refs.go @@ -168,21 +168,14 @@ Displays the hashes of all local objects. return err } - out := make(chan interface{}) - - go func() { - defer close(out) - - for k := range allKeys { - select { - case out <- &RefWrapper{Ref: k.String()}: - case <-req.Context.Done(): - return - } + for k := range allKeys { + err := res.Emit(&RefWrapper{Ref: k.String()}) + if err != nil { + return err } - }() + } - return res.Emit(out) + return nil }, Encoders: cmds.EncoderMap{ cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *RefWrapper) error { From 30c6dd9bc1073734ea5925bca607907cc545aa14 Mon Sep 17 00:00:00 2001 From: Overbool Date: Tue, 6 Nov 2018 10:51:59 +0800 Subject: [PATCH 3/4] cmds/refs: remove redundant func License: MIT Signed-off-by: Overbool --- core/commands/filestore.go | 14 +----- core/commands/refs.go | 88 ++++++++++---------------------------- core/commands/root.go | 1 + 3 files changed, 25 insertions(+), 78 deletions(-) diff --git a/core/commands/filestore.go b/core/commands/filestore.go index 70c02a3a41e..798b0ec8e1d 100644 --- a/core/commands/filestore.go +++ b/core/commands/filestore.go @@ -203,18 +203,8 @@ var dupsFileStore = &cmds.Command{ return nil }, - Encoders: cmds.EncoderMap{ - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *RefWrapper) error { - if out.Err != "" { - return fmt.Errorf(out.Err) - } - - fmt.Fprintln(w, out.Ref) - - return nil - }), - }, - Type: RefWrapper{}, + Encoders: refsEncoderMap, + Type: RefWrapper{}, } func getFilestore(env cmds.Environment) (*core.IpfsNode, *filestore.Filestore, error) { diff --git a/core/commands/refs.go b/core/commands/refs.go index 5a85bed1f95..ad9eab43cec 100644 --- a/core/commands/refs.go +++ b/core/commands/refs.go @@ -1,25 +1,33 @@ package commands import ( - "bytes" "context" "errors" "fmt" "io" "strings" - oldcmds "github.com/ipfs/go-ipfs/commands" core "github.com/ipfs/go-ipfs/core" cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv" - e "github.com/ipfs/go-ipfs/core/commands/e" cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" path "gx/ipfs/QmRG3XuGwT7GYuAqgWDJBKTzdaHMwAnc1x7J2KHEXNHxzG/go-path" + cmds "gx/ipfs/Qma6uuSyjkecGhMFFLfzyJDPyoDtNJSHJNweDccZhaWkgU/go-ipfs-cmds" ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format" - cmds "gx/ipfs/QmSXUokcP4TJpFfqozT69AVAYRtzXVMUjzQVkYX41R9Svs/go-ipfs-cmds" cmdkit "gx/ipfs/Qmde5VP1qUkyQXKCfmEUA7bP64V2HAptbJ7phuPp7jXWwg/go-ipfs-cmdkit" ) +var refsEncoderMap = cmds.EncoderMap{ + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *RefWrapper) error { + if out.Err != "" { + return fmt.Errorf(out.Err) + } + fmt.Fprintln(w, out.Ref) + + return nil + }), +} + // KeyList is a general type for outputting lists of keys type KeyList struct { Keys []cid.Cid @@ -33,25 +41,7 @@ const ( refsMaxDepthOptionName = "max-depth" ) -// KeyListTextMarshaler outputs a KeyList as plaintext, one key per line -func KeyListTextMarshaler(res oldcmds.Response) (io.Reader, error) { - out, err := unwrapOutput(res.Output()) - if err != nil { - return nil, err - } - - output, ok := out.(*KeyList) - if !ok { - return nil, e.TypeErr(output, out) - } - - buf := new(bytes.Buffer) - for _, key := range output.Keys { - buf.WriteString(key.String() + "\n") - } - return buf, nil -} - +// RefsCmd is the `ipfs refs` command var RefsCmd = &cmds.Command{ Helptext: cmdkit.HelpText{ Tagline: "List links (references) from an object.", @@ -78,6 +68,11 @@ NOTE: List all references recursively by using the flag '-r'. cmdkit.IntOption(refsMaxDepthOptionName, "Only for recursive refs, limits fetch and listing to the given depth").WithDefault(-1), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { + err := req.ParseBodyArgs() + if err != nil { + return err + } + ctx := req.Context n, err := cmdenv.GetNode(env) if err != nil { @@ -134,17 +129,8 @@ NOTE: List all references recursively by using the flag '-r'. return res.Emit(out) }, - Encoders: cmds.EncoderMap{ - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *RefWrapper) error { - if out.Err != "" { - return fmt.Errorf(out.Err) - } - fmt.Fprintln(w, out.Ref) - - return nil - }), - }, - Type: RefWrapper{}, + Encoders: refsEncoderMap, + Type: RefWrapper{}, } var RefsLocalCmd = &cmds.Command{ @@ -177,37 +163,8 @@ Displays the hashes of all local objects. return nil }, - Encoders: cmds.EncoderMap{ - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *RefWrapper) error { - if out.Err != "" { - return fmt.Errorf(out.Err) - } - fmt.Fprintln(w, out.Ref) - - return nil - }), - }, - Type: RefWrapper{}, -} - -var refsMarshallerMap = oldcmds.MarshalerMap{ - cmds.Text: func(res oldcmds.Response) (io.Reader, error) { - v, err := unwrapOutput(res.Output()) - if err != nil { - return nil, err - } - - obj, ok := v.(*RefWrapper) - if !ok { - return nil, e.TypeErr(obj, v) - } - - if obj.Err != "" { - return nil, errors.New(obj.Err) - } - - return strings.NewReader(obj.Ref + "\n"), nil - }, + Encoders: refsEncoderMap, + Type: RefWrapper{}, } func objectsForPaths(ctx context.Context, n *core.IpfsNode, paths []string) ([]ipld.Node, error) { @@ -247,7 +204,6 @@ type RefWriter struct { // WriteRefs writes refs of the given object to the underlying writer. func (rw *RefWriter) WriteRefs(n ipld.Node) (int, error) { return rw.writeRefsRecursive(n, 0) - } func (rw *RefWriter) writeRefsRecursive(n ipld.Node, depth int) (int, error) { diff --git a/core/commands/root.go b/core/commands/root.go index 4c0834e9d03..62f2edfabcc 100644 --- a/core/commands/root.go +++ b/core/commands/root.go @@ -155,6 +155,7 @@ var RootRO = &cmds.Command{} var CommandsDaemonROCmd = CommandsCmd(RootRO) +// RefsROCmd is `ipfs refs` command var RefsROCmd = &cmds.Command{} var rootROSubcommands = map[string]*cmds.Command{ From bb236cf5ad189859a3fdda0f8fa8240daafdde37 Mon Sep 17 00:00:00 2001 From: Overbool Date: Wed, 7 Nov 2018 16:58:36 +0800 Subject: [PATCH 4/4] cmds/refs: use emit directly License: MIT Signed-off-by: Overbool --- core/commands/refs.go | 41 ++++++++++++++++------------------------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/core/commands/refs.go b/core/commands/refs.go index ad9eab43cec..710679b6fe0 100644 --- a/core/commands/refs.go +++ b/core/commands/refs.go @@ -102,32 +102,24 @@ NOTE: List all references recursively by using the flag '-r'. return err } - out := make(chan interface{}) - - go func() { - defer close(out) - - rw := RefWriter{ - out: out, - DAG: n.DAG, - Ctx: ctx, - Unique: unique, - PrintFmt: format, - MaxDepth: maxDepth, - } + rw := RefWriter{ + res: res, + DAG: n.DAG, + Ctx: ctx, + Unique: unique, + PrintFmt: format, + MaxDepth: maxDepth, + } - for _, o := range objs { - if _, err := rw.WriteRefs(o); err != nil { - select { - case out <- &RefWrapper{Err: err.Error()}: - case <-ctx.Done(): - } - return + for _, o := range objs { + if _, err := rw.WriteRefs(o); err != nil { + if err := res.Emit(&RefWrapper{Err: err.Error()}); err != nil { + return err } } - }() + } - return res.Emit(out) + return nil }, Encoders: refsEncoderMap, Type: RefWrapper{}, @@ -190,7 +182,7 @@ type RefWrapper struct { } type RefWriter struct { - out chan interface{} + res cmds.ResponseEmitter DAG ipld.DAGService Ctx context.Context @@ -337,6 +329,5 @@ func (rw *RefWriter) WriteEdge(from, to cid.Cid, linkname string) error { s += to.String() } - rw.out <- &RefWrapper{Ref: s} - return nil + return rw.res.Emit(&RefWrapper{Ref: s}) }