Skip to content

Commit

Permalink
Merge pull request #5679 from overbool/refactor/commands/refs
Browse files Browse the repository at this point in the history
commands/refs: use new cmds
  • Loading branch information
Stebalien authored Nov 7, 2018
2 parents b622e33 + bb236cf commit 98f6b2f
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 143 deletions.
14 changes: 2 additions & 12 deletions core/commands/filestore.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
188 changes: 61 additions & 127 deletions core/commands/refs.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,33 @@
package commands

import (
"bytes"
"context"
"errors"
"fmt"
"io"
"strings"

cmds "github.com/ipfs/go-ipfs/commands"
"github.com/ipfs/go-ipfs/core"
e "github.com/ipfs/go-ipfs/core/commands/e"
core "github.com/ipfs/go-ipfs/core"
cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"

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"
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
Expand All @@ -30,25 +41,7 @@ const (
refsMaxDepthOptionName = "max-depth"
)

// KeyListTextMarshaler outputs a KeyList as plaintext, one key per line
func KeyListTextMarshaler(res cmds.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.",
Expand All @@ -74,91 +67,62 @@ 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 {
err := req.ParseBodyArgs()
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
return err
}

unique, _, err := req.Option(refsUniqueOptionName).Bool()
ctx := req.Context
n, err := cmdenv.GetNode(env)
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
return err
}

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 != "<dst>" {
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 = "<src> -> <dst>"
}

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)

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 nil
},
Marshalers: refsMarshallerMap,
Type: RefWrapper{},
Encoders: refsEncoderMap,
Type: RefWrapper{},
}

var RefsLocalCmd = &cmds.Command{
Expand All @@ -169,58 +133,30 @@ 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)

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
}
}()
},
Marshalers: refsMarshallerMap,
Type: RefWrapper{},
}

var refsMarshallerMap = cmds.MarshalerMap{
cmds.Text: func(res cmds.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
return nil
},
Encoders: refsEncoderMap,
Type: RefWrapper{},
}

func objectsForPaths(ctx context.Context, n *core.IpfsNode, paths []string) ([]ipld.Node, error) {
Expand All @@ -246,7 +182,7 @@ type RefWrapper struct {
}

type RefWriter struct {
out chan interface{}
res cmds.ResponseEmitter
DAG ipld.DAGService
Ctx context.Context

Expand All @@ -260,7 +196,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) {
Expand Down Expand Up @@ -394,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})
}
9 changes: 5 additions & 4 deletions core/commands/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ var rootSubcommands = map[string]*cmds.Command{
"pin": PinCmd,
"ping": PingCmd,
"p2p": P2PCmd,
"refs": lgc.NewCommand(RefsCmd),
"refs": RefsCmd,
"resolve": ResolveCmd,
"swarm": SwarmCmd,
"tar": TarCmd,
Expand All @@ -155,7 +155,8 @@ var RootRO = &cmds.Command{}

var CommandsDaemonROCmd = CommandsCmd(RootRO)

var RefsROCmd = &oldcmds.Command{}
// RefsROCmd is `ipfs refs` command
var RefsROCmd = &cmds.Command{}

var rootROSubcommands = map[string]*cmds.Command{
"commands": CommandsDaemonROCmd,
Expand Down Expand Up @@ -198,12 +199,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

Expand Down

0 comments on commit 98f6b2f

Please sign in to comment.