@cryptotaxi247 / kubo / commits / 7391cfd42

fix(commands): reduce complexity w/ typed encoder

uses single flag to support state needed by PostRun supports encoding=text License: MIT Signed-off-by: hannahhoward <hannah@hannahhoward.net>

Łukasz Magiera committed Nov 9, 2018 at 15:09 UTC 7391cfd42146015859cbd13b12d96d39c9f24615
2 files changed +36 -65
core/commands/ls.go
+36 -61
@@ -3,11 +3,9 @@ package commands
3 import (
4 "fmt"
5 "io"
6 - "os"
6 "text/tabwriter"
7
8 cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
10 - e "github.com/ipfs/go-ipfs/core/commands/e"
9 iface "github.com/ipfs/go-ipfs/core/coreapi/interface"
10
11 cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid"
@@ -39,7 +37,8 @@ type LsObject struct {
37 // LsOutput is a set of printable data for directories,
38 // it can be complete or partial
39 type LsOutput struct {
42 - Objects []LsObject
40 + Objects []LsObject
41 + LastObjectHash string
42 }
43
44 const (
@@ -112,6 +111,8 @@ The JSON output contains type information.
111 ro := merkledag.NewReadOnlyDagService(ng)
112
113 stream, _ := req.Options[lsStreamOptionName].(bool)
114 + lastObjectHash := ""
115 +
116 if !stream {
117 output := make([]LsObject, len(req.Arguments))
118
@@ -144,7 +145,7 @@ The JSON output contains type information.
145 }
146 }
147
147 - return cmds.EmitOnce(res, &LsOutput{output})
148 + return cmds.EmitOnce(res, &LsOutput{output, lastObjectHash})
149 }
150
151 for i, dagnode := range dagnodes {
@@ -161,15 +162,6 @@ The JSON output contains type information.
162 }
163
164 for linkResult := range linkResults {
164 - output := make([]LsObject, len(req.Arguments))
165 -
166 - for i, path := range paths {
167 - output[i] = LsObject{
168 - Hash: path,
169 - Links: nil,
170 - }
171 - }
172 - outputLinks := make([]LsLink, 1)
165
166 if linkResult.Err != nil {
167 return linkResult.Err
@@ -179,21 +171,24 @@ The JSON output contains type information.
171 if err != nil {
172 return err
173 }
182 - outputLinks[0] = *lsLink
183 - output[i].Links = outputLinks
184 - if err = res.Emit(&LsOutput{output}); err != nil {
174 + output := []LsObject{
175 + {
176 + Hash: paths[i],
177 + Links: []LsLink{*lsLink},
178 + },
179 + }
180 + if err = res.Emit(&LsOutput{output, lastObjectHash}); err != nil {
181 return err
182 }
183 + lastObjectHash = paths[i]
184 }
185 }
186 return nil
187 },
191 - PostRun: cmds.PostRunMap{
192 - cmds.CLI: func(res cmds.Response, re cmds.ResponseEmitter) error {
193 - req := res.Request()
188 + Encoders: cmds.EncoderMap{
189 + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *LsOutput) error {
190 headers, _ := req.Options[lsHeadersOptionNameTime].(bool)
191 stream, _ := req.Options[lsStreamOptionName].(bool)
196 -
192 // in streaming mode we can't automatically align the tabs
193 // so we take a best guess
194 var minTabWidth int
@@ -204,56 +199,36 @@ The JSON output contains type information.
199 }
200
201 multipleFolders := len(req.Arguments) > 1
207 - lastDirectoryWritten := -1
208 -
209 - tw := tabwriter.NewWriter(os.Stdout, minTabWidth, 2, 1, ' ', 0)
210 - for {
211 - v, err := res.Next()
212 - if err != nil {
213 - if err == io.EOF {
214 - if multipleFolders {
215 - fmt.Fprintln(os.Stdout)
216 - }
217 - return nil
218 - }
202 + lastObjectHash := out.LastObjectHash
203
220 - return err
221 - }
204 + tw := tabwriter.NewWriter(w, minTabWidth, 2, 1, ' ', 0)
205
223 - output, ok := v.(*LsOutput)
224 - if !ok {
225 - return e.TypeErr(output, v)
226 - }
206 + for _, object := range out.Objects {
207
228 - for i, object := range output.Objects {
229 - if len(object.Links) == 0 {
230 - continue
231 - }
232 - if i > lastDirectoryWritten {
233 - if i > 0 {
234 - if multipleFolders {
235 - fmt.Fprintln(tw)
236 - }
237 - }
238 - if multipleFolders {
239 - fmt.Fprintf(tw, "%s:\n", object.Hash)
208 + if object.Hash != lastObjectHash {
209 + if multipleFolders {
210 + if lastObjectHash != "" {
211 + fmt.Fprintln(tw)
212 }
241 - if headers {
242 - fmt.Fprintln(tw, "Hash\tSize\tName")
243 - }
244 - lastDirectoryWritten = i
213 + fmt.Fprintf(tw, "%s:\n", object.Hash)
214 }
246 - for _, link := range object.Links {
247 - if link.Type == unixfs.TDirectory {
248 - link.Name += "/"
249 - }
215 + if headers {
216 + fmt.Fprintln(tw, "Hash\tSize\tName")
217 + }
218 + lastObjectHash = object.Hash
219 + }
220
251 - fmt.Fprintf(tw, "%s\t%v\t%s\n", link.Hash, link.Size, link.Name)
221 + for _, link := range object.Links {
222 + if link.Type == unixfs.TDirectory {
223 + link.Name += "/"
224 }
225 +
226 + fmt.Fprintf(tw, "%s\t%v\t%s\n", link.Hash, link.Size, link.Name)
227 }
254 - tw.Flush()
228 }
256 - },
229 + tw.Flush()
230 + return nil
231 + }),
232 },
233 Type: LsOutput{},
234 }
test/sharness/t0045-ls.sh
-4
@@ -57,7 +57,6 @@ QmaRGe7bVmVaLmxbrMiVNXqW4pRNNp3xq7hFtyRKA3mtJL 14 a
57 QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss:
58 QmQNd6ubRXaNG6Prov8o6vk3bn6eWsj9FxLGrAVDUAGkGe 139 128
59 QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN 14 a
60 -
60 EOF
61 test_cmp expected_ls actual_ls
62 '
@@ -84,7 +83,6 @@ QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss:
83 Hash Size Name
84 QmQNd6ubRXaNG6Prov8o6vk3bn6eWsj9FxLGrAVDUAGkGe 139 128
85 QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN 14 a
87 -
86 EOF
87 test_cmp expected_ls_headers actual_ls_headers
88 '
@@ -138,7 +136,6 @@ QmaRGe7bVmVaLmxbrMiVNXqW4pRNNp3xq7hFtyRKA3mtJL 14 a
136 QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss:
137 QmQNd6ubRXaNG6Prov8o6vk3bn6eWsj9FxLGrAVDUAGkGe 139 128
138 QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN 14 a
141 -
139 EOF
140 test_cmp expected_ls_stream actual_ls_stream
141 '
@@ -165,7 +162,6 @@ QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss:
162 Hash Size Name
163 QmQNd6ubRXaNG6Prov8o6vk3bn6eWsj9FxLGrAVDUAGkGe 139 128
164 QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN 14 a
168 -
165 EOF
166 test_cmp expected_ls_stream_headers actual_ls_stream_headers
167 '