@@ -3,6 +3,7 @@ package commands
3
3
import (
4
4
"fmt"
5
5
"io"
6
+ "os"
6
7
"text/tabwriter"
7
8
8
9
cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
@@ -38,9 +39,6 @@ type LsObject struct {
38
39
// it can be complete or partial
39
40
type LsOutput struct {
40
41
Objects []LsObject
41
- // temporary flag to help us figure out where we are in the process of ls-ing
42
- // the directory when we are streaming
43
- LastObjectHash string
44
42
}
45
43
46
44
const (
@@ -102,7 +100,6 @@ The JSON output contains type information.
102
100
if err != nil {
103
101
return err
104
102
}
105
-
106
103
dagnode , err := api .ResolveNode (req .Context , p )
107
104
if err != nil {
108
105
return err
@@ -113,7 +110,6 @@ The JSON output contains type information.
113
110
ro := merkledag .NewReadOnlyDagService (ng )
114
111
115
112
stream , _ := req .Options [lsStreamOptionName ].(bool )
116
- lastObjectHash := ""
117
113
118
114
if ! stream {
119
115
output := make ([]LsObject , len (req .Arguments ))
@@ -147,7 +143,7 @@ The JSON output contains type information.
147
143
}
148
144
}
149
145
150
- return cmds .EmitOnce (res , & LsOutput {output , lastObjectHash })
146
+ return cmds .EmitOnce (res , & LsOutput {output })
151
147
}
152
148
153
149
for i , dagnode := range dagnodes {
@@ -173,62 +169,42 @@ The JSON output contains type information.
173
169
if err != nil {
174
170
return err
175
171
}
176
- output := []LsObject {
177
- {
178
- Hash : paths [i ],
179
- Links : []LsLink {* lsLink },
180
- },
181
- }
182
- if err = res .Emit (& LsOutput {output , lastObjectHash }); err != nil {
172
+ output := []LsObject {{
173
+ Hash : paths [i ],
174
+ Links : []LsLink {* lsLink },
175
+ }}
176
+ if err = res .Emit (& LsOutput {output }); err != nil {
183
177
return err
184
178
}
185
- lastObjectHash = paths [i ]
186
179
}
187
180
}
188
181
return nil
189
182
},
190
- Encoders : cmds.EncoderMap {
191
- cmds .Text : cmds .MakeTypedEncoder (func (req * cmds.Request , w io.Writer , out * LsOutput ) error {
192
- headers , _ := req .Options [lsHeadersOptionNameTime ].(bool )
193
- stream , _ := req .Options [lsStreamOptionName ].(bool )
194
- // in streaming mode we can't automatically align the tabs
195
- // so we take a best guess
196
- var minTabWidth int
197
- if stream {
198
- minTabWidth = 10
199
- } else {
200
- minTabWidth = 1
201
- }
202
-
203
- multipleFolders := len (req .Arguments ) > 1
204
- lastObjectHash := out .LastObjectHash
205
-
206
- tw := tabwriter .NewWriter (w , minTabWidth , 2 , 1 , ' ' , 0 )
183
+ PostRun : cmds.PostRunMap {
184
+ cmds .CLI : func (res cmds.Response , re cmds.ResponseEmitter ) error {
185
+ req := res .Request ()
186
+ lastObjectHash := ""
207
187
208
- for _ , object := range out .Objects {
209
-
210
- if object .Hash != lastObjectHash {
211
- if multipleFolders {
212
- if lastObjectHash != "" {
213
- fmt .Fprintln (tw )
214
- }
215
- fmt .Fprintf (tw , "%s:\n " , object .Hash )
216
- }
217
- if headers {
218
- fmt .Fprintln (tw , "Hash\t Size\t Name" )
219
- }
220
- lastObjectHash = object .Hash
221
- }
222
-
223
- for _ , link := range object .Links {
224
- if link .Type == unixfs .TDirectory {
225
- link .Name += "/"
188
+ for {
189
+ v , err := res .Next ()
190
+ if err != nil {
191
+ if err == io .EOF {
192
+ return nil
226
193
}
227
-
228
- fmt .Fprintf (tw , "%s\t %v\t %s\n " , link .Hash , link .Size , link .Name )
194
+ return err
229
195
}
196
+ out := v .(* LsOutput )
197
+ lastObjectHash = tabularOutput (req , os .Stdout , out , lastObjectHash , false )
230
198
}
231
- tw .Flush ()
199
+ },
200
+ },
201
+ Encoders : cmds.EncoderMap {
202
+ cmds .Text : cmds .MakeTypedEncoder (func (req * cmds.Request , w io.Writer , out * LsOutput ) error {
203
+ // when streaming over HTTP using a text encoder, we cannot render breaks
204
+ // between directories because we don't know the hash of the last
205
+ // directory encoder
206
+ ignoreBreaks , _ := req .Options [lsStreamOptionName ].(bool )
207
+ tabularOutput (req , w , out , "" , ignoreBreaks )
232
208
return nil
233
209
}),
234
210
},
@@ -284,3 +260,46 @@ func makeLsLink(req *cmds.Request, dserv ipld.DAGService, resolve bool, link *ip
284
260
Type : t ,
285
261
}, nil
286
262
}
263
+
264
+ func tabularOutput (req * cmds.Request , w io.Writer , out * LsOutput , lastObjectHash string , ignoreBreaks bool ) string {
265
+ headers , _ := req .Options [lsHeadersOptionNameTime ].(bool )
266
+ stream , _ := req .Options [lsStreamOptionName ].(bool )
267
+ // in streaming mode we can't automatically align the tabs
268
+ // so we take a best guess
269
+ var minTabWidth int
270
+ if stream {
271
+ minTabWidth = 10
272
+ } else {
273
+ minTabWidth = 1
274
+ }
275
+
276
+ multipleFolders := len (req .Arguments ) > 1
277
+
278
+ tw := tabwriter .NewWriter (w , minTabWidth , 2 , 1 , ' ' , 0 )
279
+
280
+ for _ , object := range out .Objects {
281
+
282
+ if ! ignoreBreaks && object .Hash != lastObjectHash {
283
+ if multipleFolders {
284
+ if lastObjectHash != "" {
285
+ fmt .Fprintln (tw )
286
+ }
287
+ fmt .Fprintf (tw , "%s:\n " , object .Hash )
288
+ }
289
+ if headers {
290
+ fmt .Fprintln (tw , "Hash\t Size\t Name" )
291
+ }
292
+ lastObjectHash = object .Hash
293
+ }
294
+
295
+ for _ , link := range object .Links {
296
+ if link .Type == unixfs .TDirectory {
297
+ link .Name += "/"
298
+ }
299
+
300
+ fmt .Fprintf (tw , "%s\t %v\t %s\n " , link .Hash , link .Size , link .Name )
301
+ }
302
+ }
303
+ tw .Flush ()
304
+ return lastObjectHash
305
+ }
0 commit comments