Skip to content

Commit 5672ae6

Browse files
committed
fix(commands): Refactor to use a PostRun
Removes flags on LSOutput License: MIT Signed-off-by: hannahhoward <[email protected]>
1 parent ef6e9cf commit 5672ae6

File tree

1 file changed

+66
-62
lines changed

1 file changed

+66
-62
lines changed

core/commands/ls.go

Lines changed: 66 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package commands
33
import (
44
"fmt"
55
"io"
6+
"os"
67
"text/tabwriter"
78

89
cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
@@ -29,20 +30,16 @@ type LsLink struct {
2930
}
3031

3132
// LsObject is an element of LsOutput
32-
// It can represent a whole directory, a directory header, one or more links,
33-
// Or a the end of a directory
33+
// It can represent all or part of a directory
3434
type LsObject struct {
35-
Hash string
36-
Links []LsLink
37-
HasHeader bool
38-
HasLinks bool
39-
HasFooter bool
35+
Hash string
36+
Links []LsLink
4037
}
4138

42-
// LsOutput is a set of printable data for directories
39+
// LsOutput is a set of printable data for directories,
40+
// it can be complete or partial
4341
type LsOutput struct {
44-
MultipleFolders bool
45-
Objects []LsObject
42+
Objects []LsObject
4643
}
4744

4845
const (
@@ -114,10 +111,10 @@ The JSON output contains type information.
114111
ng := merkledag.NewSession(req.Context, nd.DAG)
115112
ro := merkledag.NewReadOnlyDagService(ng)
116113

114+
output := make([]LsObject, len(req.Arguments))
115+
117116
stream, _ := req.Options[lsStreamOptionName].(bool)
118-
multipleFolders := len(req.Arguments) > 1
119117
if !stream {
120-
output := make([]LsObject, len(req.Arguments))
121118

122119
for i, dagnode := range dagnodes {
123120
dir, err := uio.NewDirectoryFromNode(ro, dagnode)
@@ -142,10 +139,21 @@ The JSON output contains type information.
142139
}
143140
outputLinks[j] = *lsLink
144141
}
145-
output[i] = newFullDirectoryLsObject(paths[i], outputLinks)
142+
output[i] = LsObject{
143+
Hash: paths[i],
144+
Links: outputLinks,
145+
}
146146
}
147147

148-
return cmds.EmitOnce(res, &LsOutput{multipleFolders, output})
148+
return cmds.EmitOnce(res, &LsOutput{output})
149+
}
150+
151+
outputLinks := make([]LsLink, 1)
152+
for i, path := range paths {
153+
output[i] = LsObject{
154+
Hash: path,
155+
Links: nil,
156+
}
149157
}
150158

151159
for i, dagnode := range dagnodes {
@@ -161,13 +169,8 @@ The JSON output contains type information.
161169
linkResults = dir.EnumLinksAsync(req.Context)
162170
}
163171

164-
output := make([]LsObject, 1)
165-
outputLinks := make([]LsLink, 1)
172+
output[i].Links = outputLinks
166173

167-
output[0] = newDirectoryHeaderLsObject(paths[i])
168-
if err = res.Emit(&LsOutput{multipleFolders, output}); err != nil {
169-
return nil
170-
}
171174
for linkResult := range linkResults {
172175
if linkResult.Err != nil {
173176
return linkResult.Err
@@ -178,37 +181,57 @@ The JSON output contains type information.
178181
return err
179182
}
180183
outputLinks[0] = *lsLink
181-
output[0] = newDirectoryLinksLsObject(outputLinks)
182-
if err = res.Emit(&LsOutput{multipleFolders, output}); err != nil {
184+
if err = res.Emit(&LsOutput{output}); err != nil {
183185
return err
184186
}
185187
}
186-
output[0] = newDirectoryFooterLsObject()
187-
if err = res.Emit(&LsOutput{multipleFolders, output}); err != nil {
188-
return err
189-
}
188+
output[i].Links = nil
190189
}
191190
return nil
192191
},
193-
Encoders: cmds.EncoderMap{
194-
cmds.Text: cmds.MakeEncoder(func(req *cmds.Request, w io.Writer, v interface{}) error {
192+
PostRun: cmds.PostRunMap{
193+
cmds.CLI: func(res cmds.Response, re cmds.ResponseEmitter) error {
194+
req := res.Request()
195195
headers, _ := req.Options[lsHeadersOptionNameTime].(bool)
196-
output, ok := v.(*LsOutput)
197-
if !ok {
198-
return e.TypeErr(output, v)
199-
}
196+
multipleFolders := len(req.Arguments) > 1
197+
lastDirectoryWritten := -1
198+
tw := tabwriter.NewWriter(os.Stdout, 1, 2, 1, ' ', 0)
199+
for {
200+
v, err := res.Next()
201+
if err != nil {
202+
if err == io.EOF {
203+
if multipleFolders {
204+
fmt.Fprintln(os.Stdout)
205+
}
206+
return nil
207+
}
208+
209+
return err
210+
}
211+
212+
output, ok := v.(*LsOutput)
213+
if !ok {
214+
return e.TypeErr(output, v)
215+
}
200216

201-
tw := tabwriter.NewWriter(w, 1, 2, 1, ' ', 0)
202-
for _, object := range output.Objects {
203-
if object.HasHeader {
204-
if output.MultipleFolders {
205-
fmt.Fprintf(tw, "%s:\n", object.Hash)
217+
for i, object := range output.Objects {
218+
if len(object.Links) == 0 {
219+
continue
206220
}
207-
if headers {
208-
fmt.Fprintln(tw, "Hash\tSize\tName")
221+
if i > lastDirectoryWritten {
222+
if i > 0 {
223+
if multipleFolders {
224+
fmt.Fprintln(tw)
225+
}
226+
}
227+
if multipleFolders {
228+
fmt.Fprintf(tw, "%s:\n", object.Hash)
229+
}
230+
if headers {
231+
fmt.Fprintln(tw, "Hash\tSize\tName")
232+
}
233+
lastDirectoryWritten = i
209234
}
210-
}
211-
if object.HasLinks {
212235
for _, link := range object.Links {
213236
if link.Type == unixfs.TDirectory {
214237
link.Name += "/"
@@ -217,15 +240,9 @@ The JSON output contains type information.
217240
fmt.Fprintf(tw, "%s\t%v\t%s\n", link.Hash, link.Size, link.Name)
218241
}
219242
}
220-
if object.HasFooter {
221-
if output.MultipleFolders {
222-
fmt.Fprintln(tw)
223-
}
224-
}
243+
tw.Flush()
225244
}
226-
tw.Flush()
227-
return nil
228-
}),
245+
},
229246
},
230247
Type: LsOutput{},
231248
}
@@ -248,19 +265,6 @@ func makeDagNodeLinkResults(req *cmds.Request, dagnode ipld.Node) <-chan unixfs.
248265
return linkResults
249266
}
250267

251-
func newFullDirectoryLsObject(hash string, links []LsLink) LsObject {
252-
return LsObject{hash, links, true, true, true}
253-
}
254-
func newDirectoryHeaderLsObject(hash string) LsObject {
255-
return LsObject{hash, nil, true, false, false}
256-
}
257-
func newDirectoryLinksLsObject(links []LsLink) LsObject {
258-
return LsObject{"", links, false, true, false}
259-
}
260-
func newDirectoryFooterLsObject() LsObject {
261-
return LsObject{"", nil, false, false, true}
262-
}
263-
264268
func makeLsLink(req *cmds.Request, dserv ipld.DAGService, resolve bool, link *ipld.Link) (*LsLink, error) {
265269
t := unixfspb.Data_DataType(-1)
266270

0 commit comments

Comments
 (0)