diff --git a/core/commands/ls.go b/core/commands/ls.go index 36bbc4ab63b8..3087307e8c8e 100644 --- a/core/commands/ls.go +++ b/core/commands/ls.go @@ -6,8 +6,7 @@ import ( "io" "text/tabwriter" - cmds "github.com/ipfs/go-ipfs/commands" - 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" cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid" @@ -18,7 +17,8 @@ import ( blockservice "gx/ipfs/QmWfhv1D18DRSiSm73r4QGcByspzPtxxRTcmHW3axFXZo8/go-blockservice" merkledag "gx/ipfs/QmY8BMUSpCwNiTmFhACmC9Bt1qT63cHP35AoQAus4x14qH/go-merkledag" ipld "gx/ipfs/QmdDXJs4axxefSPgK6Y1QhpJWKuDPnGJiqgq4uncb4rFHL/go-ipld-format" - "gx/ipfs/Qmde5VP1qUkyQXKCfmEUA7bP64V2HAptbJ7phuPp7jXWwg/go-ipfs-cmdkit" + cmds "gx/ipfs/QmdTmGruUz23vgzym3uWpnAEQdGdGifQqBvP8UXSRjG8gZ/go-ipfs-cmds" + cmdkit "gx/ipfs/Qmde5VP1qUkyQXKCfmEUA7bP64V2HAptbJ7phuPp7jXWwg/go-ipfs-cmdkit" ) type LsLink struct { @@ -61,30 +61,18 @@ The JSON output contains type information. cmdkit.BoolOption(lsHeadersOptionNameTime, "v", "Print table headers (Hash, Size, Name)."), cmdkit.BoolOption(lsResolveTypeOptionName, "Resolve linked objects to find out their types.").WithDefault(true), }, - Run: func(req cmds.Request, res cmds.Response) { - nd, err := req.InvocContext().GetNode() + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { + nd, 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 } - // get options early -> exit early in case of error - if _, _, err := req.Option(lsHeadersOptionNameTime).Bool(); err != nil { - res.SetError(err, cmdkit.ErrNormal) - return - } - - resolve, _, err := req.Option(lsResolveTypeOptionName).Bool() - if err != nil { - res.SetError(err, cmdkit.ErrNormal) - return - } + resolve, _ := req.Options[lsResolveTypeOptionName].(bool) dserv := nd.DAG if !resolve { @@ -93,43 +81,39 @@ The JSON output contains type information. dserv = merkledag.NewDAGService(bserv) } - paths := req.Arguments() + paths := req.Arguments var dagnodes []ipld.Node for _, fpath := range paths { p, err := iface.ParsePath(fpath) if err != nil { - res.SetError(err, cmdkit.ErrNormal) - return + return err } - dagnode, err := api.ResolveNode(req.Context(), p) + dagnode, err := api.ResolveNode(req.Context, p) if err != nil { - res.SetError(err, cmdkit.ErrNormal) - return + return err } dagnodes = append(dagnodes, dagnode) } - output := make([]LsObject, len(req.Arguments())) - ng := merkledag.NewSession(req.Context(), nd.DAG) + output := make([]LsObject, len(req.Arguments)) + ng := merkledag.NewSession(req.Context, nd.DAG) ro := merkledag.NewReadOnlyDagService(ng) for i, dagnode := range dagnodes { dir, err := uio.NewDirectoryFromNode(ro, dagnode) if err != nil && err != uio.ErrNotADir { - res.SetError(fmt.Errorf("the data in %s (at %q) is not a UnixFS directory: %s", dagnode.Cid(), paths[i], err), cmdkit.ErrNormal) - return + return fmt.Errorf("the data in %s (at %q) is not a UnixFS directory: %s", dagnode.Cid(), paths[i], err) } var links []*ipld.Link if dir == nil { links = dagnode.Links() } else { - links, err = dir.Links(req.Context()) + links, err = dir.Links(req.Context) if err != nil { - res.SetError(err, cmdkit.ErrNormal) - return + return err } } @@ -146,20 +130,18 @@ The JSON output contains type information. // No need to check with raw leaves t = unixfs.TFile case cid.DagProtobuf: - linkNode, err := link.GetNode(req.Context(), dserv) + linkNode, err := link.GetNode(req.Context, dserv) if err == ipld.ErrNotFound && !resolve { // not an error linkNode = nil } else if err != nil { - res.SetError(err, cmdkit.ErrNormal) - return + return err } if pn, ok := linkNode.(*merkledag.ProtoNode); ok { d, err := unixfs.FSNodeFromBytes(pn.Data()) if err != nil { - res.SetError(err, cmdkit.ErrNormal) - return + return err } t = d.Type() } @@ -173,45 +155,37 @@ The JSON output contains type information. } } - res.SetOutput(&LsOutput{output}) + return res.Emit(&LsOutput{output}) }, - Marshalers: cmds.MarshalerMap{ - cmds.Text: func(res cmds.Response) (io.Reader, error) { - - v, err := unwrapOutput(res.Output()) - if err != nil { - return nil, err - } - - headers, _, _ := res.Request().Option(lsHeadersOptionNameTime).Bool() - output, ok := v.(*LsOutput) - if !ok { - return nil, e.TypeErr(output, v) - } + Encoders: cmds.EncoderMap{ + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *LsOutput) error { + headers, _ := req.Options[lsHeadersOptionNameTime].(bool) buf := new(bytes.Buffer) - w := tabwriter.NewWriter(buf, 1, 2, 1, ' ', 0) - for _, object := range output.Objects { - if len(output.Objects) > 1 { - fmt.Fprintf(w, "%s:\n", object.Hash) + tw := tabwriter.NewWriter(buf, 1, 2, 1, ' ', 0) + for _, object := range out.Objects { + if len(out.Objects) > 1 { + fmt.Fprintf(tw, "%s:\n", object.Hash) } if headers { - fmt.Fprintln(w, "Hash\tSize\tName") + fmt.Fprintln(tw, "Hash\tSize\tName") } for _, link := range object.Links { if link.Type == unixfs.TDirectory { link.Name += "/" } - fmt.Fprintf(w, "%s\t%v\t%s\n", link.Hash, link.Size, link.Name) + fmt.Fprintf(tw, "%s\t%v\t%s\n", link.Hash, link.Size, link.Name) } - if len(output.Objects) > 1 { - fmt.Fprintln(w) + if len(out.Objects) > 1 { + fmt.Fprintln(tw) } } - w.Flush() + tw.Flush() + + fmt.Fprint(w, buf) - return buf, nil - }, + return nil + }), }, Type: LsOutput{}, } diff --git a/core/commands/root.go b/core/commands/root.go index ceb8436e2dec..b2ebf07d4a2d 100644 --- a/core/commands/root.go +++ b/core/commands/root.go @@ -131,7 +131,7 @@ var rootSubcommands = map[string]*cmds.Command{ "id": IDCmd, "key": KeyCmd, "log": lgc.NewCommand(LogCmd), - "ls": lgc.NewCommand(LsCmd), + "ls": LsCmd, "mount": lgc.NewCommand(MountCmd), "name": name.NameCmd, "object": ocmd.ObjectCmd, @@ -168,7 +168,7 @@ var rootROSubcommands = map[string]*cmds.Command{ }, "get": GetCmd, "dns": lgc.NewCommand(DNSCmd), - "ls": lgc.NewCommand(LsCmd), + "ls": LsCmd, "name": &cmds.Command{ Subcommands: map[string]*cmds.Command{ "resolve": name.IpnsCmd,