From b7563768a88016445194c6ba56180278f1979a0e Mon Sep 17 00:00:00 2001 From: hannahhoward Date: Wed, 14 Nov 2018 17:00:26 -0800 Subject: [PATCH] One more attempt, this time w/ no extra data License: MIT Signed-off-by: hannahhoward --- core/commands/ls.go | 111 +++++++++++++++++++++++++++----------------- 1 file changed, 68 insertions(+), 43 deletions(-) diff --git a/core/commands/ls.go b/core/commands/ls.go index a369c9b5341..e55f36ea21a 100644 --- a/core/commands/ls.go +++ b/core/commands/ls.go @@ -3,6 +3,7 @@ package commands import ( "fmt" "io" + "os" "text/tabwriter" cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv" @@ -38,9 +39,6 @@ type LsObject struct { // it can be complete or partial type LsOutput struct { Objects []LsObject - // temporary flag to help us figure out where we are in the process of ls-ing - // the directory when we are streaming - LastObjectHash string } const ( @@ -113,7 +111,6 @@ The JSON output contains type information. ro := merkledag.NewReadOnlyDagService(ng) stream, _ := req.Options[lsStreamOptionName].(bool) - lastObjectHash := "" if !stream { output := make([]LsObject, len(req.Arguments)) @@ -147,7 +144,7 @@ The JSON output contains type information. } } - return cmds.EmitOnce(res, &LsOutput{output, lastObjectHash}) + return cmds.EmitOnce(res, &LsOutput{output}) } for i, dagnode := range dagnodes { @@ -179,56 +176,41 @@ The JSON output contains type information. Links: []LsLink{*lsLink}, }, } - if err = res.Emit(&LsOutput{output, lastObjectHash}); err != nil { + if err = res.Emit(&LsOutput{output}); err != nil { return err } - lastObjectHash = paths[i] } } return nil }, - Encoders: cmds.EncoderMap{ - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *LsOutput) error { - headers, _ := req.Options[lsHeadersOptionNameTime].(bool) + PostRun: cmds.PostRunMap{ + cmds.CLI: func(res cmds.Response, re cmds.ResponseEmitter) error { + req := res.Request() stream, _ := req.Options[lsStreamOptionName].(bool) - // in streaming mode we can't automatically align the tabs - // so we take a best guess - var minTabWidth int - if stream { - minTabWidth = 10 - } else { - minTabWidth = 1 - } - - multipleFolders := len(req.Arguments) > 1 - lastObjectHash := out.LastObjectHash - - tw := tabwriter.NewWriter(w, minTabWidth, 2, 1, ' ', 0) - - for _, object := range out.Objects { - - if object.Hash != lastObjectHash { - if multipleFolders { - if lastObjectHash != "" { - fmt.Fprintln(tw) - } - fmt.Fprintf(tw, "%s:\n", object.Hash) - } - if headers { - fmt.Fprintln(tw, "Hash\tSize\tName") - } - lastObjectHash = object.Hash - } + lastObjectHash := "" - for _, link := range object.Links { - if link.Type == unixfs.TDirectory { - link.Name += "/" + for { + v, err := res.Next() + if err != nil { + if err == io.EOF { + return nil } - fmt.Fprintf(tw, "%s\t%v\t%s\n", link.Hash, link.Size, link.Name) + return err + } + out := v.(*LsOutput) + if stream { + lastObjectHash = tabularOutput(req, os.Stdout, out, lastObjectHash, false) + } else { + re.Emit(out) } } - tw.Flush() + }, + }, + Encoders: cmds.EncoderMap{ + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *LsOutput) error { + stream, _ := req.Options[lsStreamOptionName].(bool) + tabularOutput(req, w, out, "", stream) return nil }), }, @@ -284,3 +266,46 @@ func makeLsLink(req *cmds.Request, dserv ipld.DAGService, resolve bool, link *ip Type: t, }, nil } + +func tabularOutput(req *cmds.Request, w io.Writer, out *LsOutput, lastObjectHash string, ignoreBreaks bool) string { + headers, _ := req.Options[lsHeadersOptionNameTime].(bool) + stream, _ := req.Options[lsStreamOptionName].(bool) + // in streaming mode we can't automatically align the tabs + // so we take a best guess + var minTabWidth int + if stream { + minTabWidth = 10 + } else { + minTabWidth = 1 + } + + multipleFolders := len(req.Arguments) > 1 + + tw := tabwriter.NewWriter(w, minTabWidth, 2, 1, ' ', 0) + + for _, object := range out.Objects { + + if !ignoreBreaks && object.Hash != lastObjectHash { + if multipleFolders { + if lastObjectHash != "" { + fmt.Fprintln(tw) + } + fmt.Fprintf(tw, "%s:\n", object.Hash) + } + if headers { + fmt.Fprintln(tw, "Hash\tSize\tName") + } + lastObjectHash = object.Hash + } + + for _, link := range object.Links { + if link.Type == unixfs.TDirectory { + link.Name += "/" + } + + fmt.Fprintf(tw, "%s\t%v\t%s\n", link.Hash, link.Size, link.Name) + } + } + tw.Flush() + return lastObjectHash +}