@cryptotaxi247 / kubo / commits / df58a2d61

commands/object: fix object diff option error

License: MIT Signed-off-by: Overbool <overbool.xu@gmail.com>

Overbool committed Oct 27, 2018 at 10:03 UTC df58a2d617b27fa103259db5772c5c40cf00fa31
4 files changed +208 -331
core/commands/object/diff.go
+29 -39
@@ -1,11 +1,10 @@
1 package objectcmd
2
3 import (
4 - "bytes"
4 "fmt"
5 "io"
6
8 - e "github.com/ipfs/go-ipfs/core/commands/e"
7 + cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
8 coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
9 "github.com/ipfs/go-ipfs/dagutils"
10
@@ -13,6 +12,10 @@ import (
12 cmdkit "gx/ipfs/Qmde5VP1qUkyQXKCfmEUA7bP64V2HAptbJ7phuPp7jXWwg/go-ipfs-cmdkit"
13 )
14
15 +const (
16 + verboseOptionName = "verbose"
17 +)
18 +
19 type Changes struct {
20 Changes []*dagutils.Change
21 }
@@ -49,34 +52,30 @@ Example:
52 cmdkit.StringArg("obj_b", true, false, "Object to diff."),
53 },
54 Options: []cmdkit.Option{
52 - cmdkit.BoolOption("verbose", "v", "Print extra information."),
55 + cmdkit.BoolOption(verboseOptionName, "v", "Print extra information."),
56 },
54 - Run: func(req cmds.Request, res cmds.Response) {
55 - api, err := req.InvocContext().GetApi()
57 + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
58 + api, err := cmdenv.GetApi(env)
59 if err != nil {
57 - res.SetError(err, cmdkit.ErrNormal)
58 - return
60 + return err
61 }
62
61 - a := req.Arguments()[0]
62 - b := req.Arguments()[1]
63 + a := req.Arguments[0]
64 + b := req.Arguments[1]
65
66 pa, err := coreiface.ParsePath(a)
67 if err != nil {
66 - res.SetError(err, cmdkit.ErrNormal)
67 - return
68 + return err
69 }
70
71 pb, err := coreiface.ParsePath(b)
72 if err != nil {
72 - res.SetError(err, cmdkit.ErrNormal)
73 - return
73 + return err
74 }
75
76 - changes, err := api.Object().Diff(req.Context(), pa, pb)
76 + changes, err := api.Object().Diff(req.Context, pa, pb)
77 if err != nil {
78 - res.SetError(err, cmdkit.ErrNormal)
79 - return
78 + return err
79 }
80
81 out := make([]*dagutils.Change, len(changes))
@@ -95,45 +94,36 @@ Example:
94 }
95 }
96
98 - res.SetOutput(&Changes{out})
97 + return res.Emit(&Changes{out})
98 },
99 Type: Changes{},
101 - Marshalers: cmds.MarshalerMap{
102 - cmds.Text: func(res cmds.Response) (io.Reader, error) {
103 - v, err := unwrapOutput(res.Output())
104 - if err != nil {
105 - return nil, err
106 - }
100 + Encoders: cmds.EncoderMap{
101 + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *Changes) error {
102 + verbose, _ := req.Options[verboseOptionName].(bool)
103
108 - verbose, _, _ := res.Request().Option("v").Bool()
109 - changes, ok := v.(*Changes)
110 - if !ok {
111 - return nil, e.TypeErr(changes, v)
112 - }
113 -
114 - buf := new(bytes.Buffer)
115 - for _, change := range changes.Changes {
104 + for _, change := range out.Changes {
105 if verbose {
106 switch change.Type {
107 case dagutils.Add:
119 - fmt.Fprintf(buf, "Added new link %q pointing to %s.\n", change.Path, change.After)
108 + fmt.Fprintf(w, "Added new link %q pointing to %s.\n", change.Path, change.After)
109 case dagutils.Mod:
121 - fmt.Fprintf(buf, "Changed %q from %s to %s.\n", change.Path, change.Before, change.After)
110 + fmt.Fprintf(w, "Changed %q from %s to %s.\n", change.Path, change.Before, change.After)
111 case dagutils.Remove:
123 - fmt.Fprintf(buf, "Removed link %q (was %s).\n", change.Path, change.Before)
112 + fmt.Fprintf(w, "Removed link %q (was %s).\n", change.Path, change.Before)
113 }
114 } else {
115 switch change.Type {
116 case dagutils.Add:
128 - fmt.Fprintf(buf, "+ %s %q\n", change.After, change.Path)
117 + fmt.Fprintf(w, "+ %s %q\n", change.After, change.Path)
118 case dagutils.Mod:
130 - fmt.Fprintf(buf, "~ %s %s %q\n", change.Before, change.After, change.Path)
119 + fmt.Fprintf(w, "~ %s %s %q\n", change.Before, change.After, change.Path)
120 case dagutils.Remove:
132 - fmt.Fprintf(buf, "- %s %q\n", change.Before, change.Path)
121 + fmt.Fprintf(w, "- %s %q\n", change.Before, change.Path)
122 }
123 }
124 }
136 - return buf, nil
137 - },
125 +
126 + return nil
127 + }),
128 },
129 }
core/commands/object/object.go
+122 -218
@@ -1,18 +1,14 @@
1 package objectcmd
2
3 import (
4 - "bytes"
4 "encoding/base64"
5 "errors"
6 "fmt"
7 "io"
8 "io/ioutil"
10 - "strings"
9 "text/tabwriter"
10
13 - oldcmds "github.com/ipfs/go-ipfs/commands"
14 - lgc "github.com/ipfs/go-ipfs/commands/legacy"
15 - e "github.com/ipfs/go-ipfs/core/commands/e"
11 + cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
12 coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
13 "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
14
@@ -23,8 +19,6 @@ import (
19 cmdkit "gx/ipfs/Qmde5VP1qUkyQXKCfmEUA7bP64V2HAptbJ7phuPp7jXWwg/go-ipfs-cmdkit"
20 )
21
26 -const inputLimit = 2 << 20
27 -
22 type Node struct {
23 Links []Link
24 Data string
@@ -51,18 +45,18 @@ directly.`,
45 },
46
47 Subcommands: map[string]*cmds.Command{
54 - "data": lgc.NewCommand(ObjectDataCmd),
55 - "diff": lgc.NewCommand(ObjectDiffCmd),
56 - "get": lgc.NewCommand(ObjectGetCmd),
57 - "links": lgc.NewCommand(ObjectLinksCmd),
58 - "new": lgc.NewCommand(ObjectNewCmd),
48 + "data": ObjectDataCmd,
49 + "diff": ObjectDiffCmd,
50 + "get": ObjectGetCmd,
51 + "links": ObjectLinksCmd,
52 + "new": ObjectNewCmd,
53 "patch": ObjectPatchCmd,
60 - "put": lgc.NewCommand(ObjectPutCmd),
61 - "stat": lgc.NewCommand(ObjectStatCmd),
54 + "put": ObjectPutCmd,
55 + "stat": ObjectStatCmd,
56 },
57 }
58
65 -var ObjectDataCmd = &oldcmds.Command{
59 +var ObjectDataCmd = &cmds.Command{
60 Helptext: cmdkit.HelpText{
61 Tagline: "Output the raw bytes of an IPFS object.",
62 ShortDescription: `
@@ -81,30 +75,27 @@ is the raw data of the object.
75 Arguments: []cmdkit.Argument{
76 cmdkit.StringArg("key", true, false, "Key of the object to retrieve, in base58-encoded multihash format.").EnableStdin(),
77 },
84 - Run: func(req oldcmds.Request, res oldcmds.Response) {
85 - api, err := req.InvocContext().GetApi()
78 + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
79 + api, err := cmdenv.GetApi(env)
80 if err != nil {
87 - res.SetError(err, cmdkit.ErrNormal)
88 - return
81 + return err
82 }
83
91 - path, err := coreiface.ParsePath(req.Arguments()[0])
84 + path, err := coreiface.ParsePath(req.Arguments[0])
85 if err != nil {
93 - res.SetError(err, cmdkit.ErrNormal)
94 - return
86 + return err
87 }
88
97 - data, err := api.Object().Data(req.Context(), path)
89 + data, err := api.Object().Data(req.Context, path)
90 if err != nil {
99 - res.SetError(err, cmdkit.ErrNormal)
100 - return
91 + return err
92 }
93
103 - res.SetOutput(data)
94 + return res.Emit(data)
95 },
96 }
97
107 -var ObjectLinksCmd = &oldcmds.Command{
98 +var ObjectLinksCmd = &cmds.Command{
99 Helptext: cmdkit.HelpText{
100 Tagline: "Output the links pointed to by the specified object.",
101 ShortDescription: `
@@ -120,35 +111,25 @@ multihash.
111 Options: []cmdkit.Option{
112 cmdkit.BoolOption("headers", "v", "Print table headers (Hash, Size, Name)."),
113 },
123 - Run: func(req oldcmds.Request, res oldcmds.Response) {
124 - api, err := req.InvocContext().GetApi()
114 + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
115 + api, err := cmdenv.GetApi(env)
116 if err != nil {
126 - res.SetError(err, cmdkit.ErrNormal)
127 - return
128 - }
129 -
130 - // get options early -> exit early in case of error
131 - if _, _, err := req.Option("headers").Bool(); err != nil {
132 - res.SetError(err, cmdkit.ErrNormal)
133 - return
117 + return err
118 }
119
136 - path, err := coreiface.ParsePath(req.Arguments()[0])
120 + path, err := coreiface.ParsePath(req.Arguments[0])
121 if err != nil {
138 - res.SetError(err, cmdkit.ErrNormal)
139 - return
122 + return err
123 }
124
142 - rp, err := api.ResolvePath(req.Context(), path)
125 + rp, err := api.ResolvePath(req.Context, path)
126 if err != nil {
144 - res.SetError(err, cmdkit.ErrNormal)
145 - return
127 + return err
128 }
129
148 - links, err := api.Object().Links(req.Context(), rp)
130 + links, err := api.Object().Links(req.Context, rp)
131 if err != nil {
150 - res.SetError(err, cmdkit.ErrNormal)
151 - return
132 + return err
133 }
134
135 outLinks := make([]Link, len(links))
@@ -165,37 +146,27 @@ multihash.
146 Links: outLinks,
147 }
148
168 - res.SetOutput(out)
149 + return res.Emit(out)
150 },
170 - Marshalers: oldcmds.MarshalerMap{
171 - oldcmds.Text: func(res oldcmds.Response) (io.Reader, error) {
172 - v, err := unwrapOutput(res.Output())
173 - if err != nil {
174 - return nil, err
175 - }
176 -
177 - object, ok := v.(*Object)
178 - if !ok {
179 - return nil, e.TypeErr(object, v)
180 - }
181 -
182 - buf := new(bytes.Buffer)
183 - w := tabwriter.NewWriter(buf, 1, 2, 1, ' ', 0)
184 - headers, _, _ := res.Request().Option("headers").Bool()
151 + Encoders: cmds.EncoderMap{
152 + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *Object) error {
153 + tw := tabwriter.NewWriter(w, 1, 2, 1, ' ', 0)
154 + headers, _ := req.Options["headers"].(bool)
155 if headers {
186 - fmt.Fprintln(w, "Hash\tSize\tName")
156 + fmt.Fprintln(tw, "Hash\tSize\tName")
157 }
188 - for _, link := range object.Links {
189 - fmt.Fprintf(w, "%s\t%v\t%s\n", link.Hash, link.Size, link.Name)
158 + for _, link := range out.Links {
159 + fmt.Fprintf(tw, "%s\t%v\t%s\n", link.Hash, link.Size, link.Name)
160 }
191 - w.Flush()
192 - return buf, nil
193 - },
161 + tw.Flush()
162 +
163 + return nil
164 + }),
165 },
166 Type: &Object{},
167 }
168
198 -var ObjectGetCmd = &oldcmds.Command{
169 +var ObjectGetCmd = &cmds.Command{
170 Helptext: cmdkit.HelpText{
171 Tagline: "Get and serialize the DAG node named by <key>.",
172 ShortDescription: `
@@ -229,47 +200,40 @@ Supported values are:
200 Options: []cmdkit.Option{
201 cmdkit.StringOption("data-encoding", "Encoding type of the data field, either \"text\" or \"base64\".").WithDefault("text"),
202 },
232 - Run: func(req oldcmds.Request, res oldcmds.Response) {
233 - api, err := req.InvocContext().GetApi()
203 + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
204 + api, err := cmdenv.GetApi(env)
205 if err != nil {
235 - res.SetError(err, cmdkit.ErrNormal)
236 - return
206 + return err
207 }
208
239 - path, err := coreiface.ParsePath(req.Arguments()[0])
209 + path, err := coreiface.ParsePath(req.Arguments[0])
210 if err != nil {
241 - res.SetError(err, cmdkit.ErrNormal)
242 - return
211 + return err
212 }
213
245 - datafieldenc, _, err := req.Option("data-encoding").String()
214 + datafieldenc, _ := req.Options["data-encoding"].(string)
215 if err != nil {
247 - res.SetError(err, cmdkit.ErrNormal)
248 - return
216 + return err
217 }
218
251 - nd, err := api.Object().Get(req.Context(), path)
219 + nd, err := api.Object().Get(req.Context, path)
220 if err != nil {
253 - res.SetError(err, cmdkit.ErrNormal)
254 - return
221 + return err
222 }
223
257 - r, err := api.Object().Data(req.Context(), path)
224 + r, err := api.Object().Data(req.Context, path)
225 if err != nil {
259 - res.SetError(err, cmdkit.ErrNormal)
260 - return
226 + return err
227 }
228
229 data, err := ioutil.ReadAll(r)
230 if err != nil {
265 - res.SetError(err, cmdkit.ErrNormal)
266 - return
231 + return err
232 }
233
234 out, err := encodeData(data, datafieldenc)
235 if err != nil {
271 - res.SetError(err, cmdkit.ErrNormal)
272 - return
236 + return err
237 }
238
239 node := &Node{
@@ -285,37 +249,29 @@ Supported values are:
249 }
250 }
251
288 - res.SetOutput(node)
252 + return res.Emit(node)
253 },
254 Type: Node{},
291 - Marshalers: oldcmds.MarshalerMap{
292 - oldcmds.Protobuf: func(res oldcmds.Response) (io.Reader, error) {
293 - v, err := unwrapOutput(res.Output())
294 - if err != nil {
295 - return nil, err
296 - }
297 -
298 - node, ok := v.(*Node)
299 - if !ok {
300 - return nil, e.TypeErr(node, v)
301 - }
302 -
255 + Encoders: cmds.EncoderMap{
256 + cmds.Protobuf: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *Node) error {
257 // deserialize the Data field as text as this was the standard behaviour
304 - object, err := deserializeNode(node, "text")
258 + object, err := deserializeNode(out, "text")
259 if err != nil {
306 - return nil, err
260 + return nil
261 }
262
263 marshaled, err := object.Marshal()
264 if err != nil {
311 - return nil, err
265 + return err
266 }
313 - return bytes.NewReader(marshaled), nil
314 - },
267 + fmt.Fprint(w, marshaled)
268 +
269 + return nil
270 + }),
271 },
272 }
273
318 -var ObjectStatCmd = &oldcmds.Command{
274 +var ObjectStatCmd = &cmds.Command{
275 Helptext: cmdkit.HelpText{
276 Tagline: "Get stats for the DAG node named by <key>.",
277 ShortDescription: `
@@ -333,23 +289,20 @@ var ObjectStatCmd = &oldcmds.Command{
289 Arguments: []cmdkit.Argument{
290 cmdkit.StringArg("key", true, false, "Key of the object to retrieve, in base58-encoded multihash format.").EnableStdin(),
291 },
336 - Run: func(req oldcmds.Request, res oldcmds.Response) {
337 - api, err := req.InvocContext().GetApi()
292 + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
293 + api, err := cmdenv.GetApi(env)
294 if err != nil {
339 - res.SetError(err, cmdkit.ErrNormal)
340 - return
295 + return err
296 }
297
343 - path, err := coreiface.ParsePath(req.Arguments()[0])
298 + path, err := coreiface.ParsePath(req.Arguments[0])
299 if err != nil {
345 - res.SetError(err, cmdkit.ErrNormal)
346 - return
300 + return err
301 }
302
349 - ns, err := api.Object().Stat(req.Context(), path)
303 + ns, err := api.Object().Stat(req.Context, path)
304 if err != nil {
351 - res.SetError(err, cmdkit.ErrNormal)
352 - return
305 + return err
306 }
307
308 oldStat := &ipld.NodeStat{
@@ -361,37 +314,26 @@ var ObjectStatCmd = &oldcmds.Command{
314 CumulativeSize: ns.CumulativeSize,
315 }
316
364 - res.SetOutput(oldStat)
317 + return res.Emit(oldStat)
318 },
319 Type: ipld.NodeStat{},
367 - Marshalers: oldcmds.MarshalerMap{
368 - oldcmds.Text: func(res oldcmds.Response) (io.Reader, error) {
369 - v, err := unwrapOutput(res.Output())
370 - if err != nil {
371 - return nil, err
372 - }
373 -
374 - ns, ok := v.(*ipld.NodeStat)
375 - if !ok {
376 - return nil, e.TypeErr(ns, v)
320 + Encoders: cmds.EncoderMap{
321 + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *ipld.NodeStat) error {
322 + fw := func(s string, n int) {
323 + fmt.Fprintf(w, "%s: %d\n", s, n)
324 }
378 -
379 - buf := new(bytes.Buffer)
380 - w := func(s string, n int) {
381 - fmt.Fprintf(buf, "%s: %d\n", s, n)
382 - }
383 - w("NumLinks", ns.NumLinks)
384 - w("BlockSize", ns.BlockSize)
385 - w("LinksSize", ns.LinksSize)
386 - w("DataSize", ns.DataSize)
387 - w("CumulativeSize", ns.CumulativeSize)
388 -
389 - return buf, nil
390 - },
325 + fw("NumLinks", out.NumLinks)
326 + fw("BlockSize", out.BlockSize)
327 + fw("LinksSize", out.LinksSize)
328 + fw("DataSize", out.DataSize)
329 + fw("CumulativeSize", out.CumulativeSize)
330 +
331 + return nil
332 + }),
333 },
334 }
335
394 -var ObjectPutCmd = &oldcmds.Command{
336 +var ObjectPutCmd = &cmds.Command{
337 Helptext: cmdkit.HelpText{
338 Tagline: "Store input as a DAG object, print its key.",
339 ShortDescription: `
@@ -438,73 +380,60 @@ And then run:
380 cmdkit.BoolOption("pin", "Pin this object when adding."),
381 cmdkit.BoolOption("quiet", "q", "Write minimal output."),
382 },
441 - Run: func(req oldcmds.Request, res oldcmds.Response) {
442 - api, err := req.InvocContext().GetApi()
383 + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
384 + api, err := cmdenv.GetApi(env)
385 if err != nil {
444 - res.SetError(err, cmdkit.ErrNormal)
445 - return
386 + return err
387 }
388
448 - input, err := req.Files().NextFile()
389 + input, err := req.Files.NextFile()
390 if err != nil && err != io.EOF {
450 - res.SetError(err, cmdkit.ErrNormal)
451 - return
391 + return err
392 }
393
454 - inputenc, _, err := req.Option("inputenc").String()
394 + inputenc, _ := req.Options["inputenc"].(string)
395 if err != nil {
456 - res.SetError(err, cmdkit.ErrNormal)
457 - return
396 + return err
397 }
398
460 - datafieldenc, _, err := req.Option("datafieldenc").String()
399 + datafieldenc, _ := req.Options["datafieldenc"].(string)
400 if err != nil {
462 - res.SetError(err, cmdkit.ErrNormal)
463 - return
401 + return err
402 }
403
466 - dopin, _, err := req.Option("pin").Bool()
404 + dopin, _ := req.Options["pin"].(bool)
405 if err != nil {
468 - res.SetError(err, cmdkit.ErrNormal)
469 - return
406 + return err
407 }
408
472 - p, err := api.Object().Put(req.Context(), input,
409 + p, err := api.Object().Put(req.Context, input,
410 options.Object.DataType(datafieldenc),
411 options.Object.InputEnc(inputenc),
412 options.Object.Pin(dopin))
413 if err != nil {
477 - res.SetError(err, cmdkit.ErrNormal)
478 - return
414 + return err
415 }
416
481 - res.SetOutput(&Object{Hash: p.Cid().String()})
417 + return res.Emit(&Object{Hash: p.Cid().String()})
418 },
483 - Marshalers: oldcmds.MarshalerMap{
484 - oldcmds.Text: func(res oldcmds.Response) (io.Reader, error) {
485 - quiet, _, _ := res.Request().Option("quiet").Bool()
419 + Encoders: cmds.EncoderMap{
420 + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *Object) error {
421 + quiet, _ := req.Options["quiet"].(bool)
422
487 - v, err := unwrapOutput(res.Output())
488 - if err != nil {
489 - return nil, err
490 - }
491 - obj, ok := v.(*Object)
492 - if !ok {
493 - return nil, e.TypeErr(obj, v)
494 - }
495 -
496 - out := obj.Hash + "\n"
423 + o := out.Hash
424 if !quiet {
498 - out = "added " + out
425 + o = "added " + o
426 }
427
501 - return strings.NewReader(out), nil
502 - },
428 + fmt.Fprintln(w, o)
429 +
430 + return nil
431 + }),
432 },
433 Type: Object{},
434 }
435
507 -var ObjectNewCmd = &oldcmds.Command{
436 +var ObjectNewCmd = &cmds.Command{
437 Helptext: cmdkit.HelpText{
438 Tagline: "Create a new object from an ipfs template.",
439 ShortDescription: `
@@ -523,40 +452,29 @@ Available templates:
452 Arguments: []cmdkit.Argument{
453 cmdkit.StringArg("template", false, false, "Template to use. Optional."),
454 },
526 - Run: func(req oldcmds.Request, res oldcmds.Response) {
527 - api, err := req.InvocContext().GetApi()
455 + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
456 + api, err := cmdenv.GetApi(env)
457 if err != nil {
529 - res.SetError(err, cmdkit.ErrNormal)
530 - return
458 + return err
459 }
460
461 template := "empty"
534 - if len(req.Arguments()) == 1 {
535 - template = req.Arguments()[0]
462 + if len(req.Arguments) == 1 {
463 + template = req.Arguments[0]
464 }
465
538 - nd, err := api.Object().New(req.Context(), options.Object.Type(template))
466 + nd, err := api.Object().New(req.Context, options.Object.Type(template))
467 if err != nil && err != io.EOF {
540 - res.SetError(err, cmdkit.ErrNormal)
541 - return
468 + return err
469 }
470
544 - res.SetOutput(&Object{Hash: nd.Cid().String()})
471 + return res.Emit(&Object{Hash: nd.Cid().String()})
472 },
546 - Marshalers: oldcmds.MarshalerMap{
547 - oldcmds.Text: func(res oldcmds.Response) (io.Reader, error) {
548 - v, err := unwrapOutput(res.Output())
549 - if err != nil {
550 - return nil, err
551 - }
552 -
553 - obj, ok := v.(*Object)
554 - if !ok {
555 - return nil, e.TypeErr(obj, v)
556 - }
557 -
558 - return strings.NewReader(obj.Hash + "\n"), nil
559 - },
473 + Encoders: cmds.EncoderMap{
474 + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *Object) error {
475 + fmt.Fprintln(w, out.Hash)
476 + return nil
477 + }),
478 },
479 Type: Object{},
480 }
@@ -594,20 +512,6 @@ func deserializeNode(nd *Node, dataFieldEncoding string) (*dag.ProtoNode, error)
512 return dagnode, nil
513 }
514
597 -// copy+pasted from ../commands.go
598 -func unwrapOutput(i interface{}) (interface{}, error) {
599 - var (
600 - ch <-chan interface{}
601 - ok bool
602 - )
603 -
604 - if ch, ok = i.(<-chan interface{}); !ok {
605 - return nil, e.TypeErr(ch, i)
606 - }
607 -
608 - return <-ch, nil
609 -}
610 -
515 func encodeData(data []byte, encoding string) (string, error) {
516 switch encoding {
517 case "text":
core/commands/object/patch.go
+55 -72
@@ -3,12 +3,8 @@ package objectcmd
3 import (
4 "fmt"
5 "io"
6 - "strings"
6
8 - oldcmds "github.com/ipfs/go-ipfs/commands"
9 - lgc "github.com/ipfs/go-ipfs/commands/legacy"
7 cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
11 - e "github.com/ipfs/go-ipfs/core/commands/e"
8 coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
9 "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
10
@@ -28,26 +24,12 @@ result. This is the Merkle-DAG version of modifying an object.
24 Arguments: []cmdkit.Argument{},
25 Subcommands: map[string]*cmds.Command{
26 "append-data": patchAppendDataCmd,
31 - "add-link": lgc.NewCommand(patchAddLinkCmd),
32 - "rm-link": lgc.NewCommand(patchRmLinkCmd),
33 - "set-data": lgc.NewCommand(patchSetDataCmd),
27 + "add-link": patchAddLinkCmd,
28 + "rm-link": patchRmLinkCmd,
29 + "set-data": patchSetDataCmd,
30 },
31 }
32
37 -func objectMarshaler(res oldcmds.Response) (io.Reader, error) {
38 - v, err := unwrapOutput(res.Output())
39 - if err != nil {
40 - return nil, err
41 - }
42 -
43 - o, ok := v.(*Object)
44 - if !ok {
45 - return nil, e.TypeErr(o, v)
46 - }
47 -
48 - return strings.NewReader(o.Hash + "\n"), nil
49 -}
50 -
33 var patchAppendDataCmd = &cmds.Command{
34 Helptext: cmdkit.HelpText{
35 Tagline: "Append data to the data segment of a dag node.",
@@ -99,7 +81,7 @@ the limit will not be respected by the network.
81 },
82 }
83
102 -var patchSetDataCmd = &oldcmds.Command{
84 +var patchSetDataCmd = &cmds.Command{
85 Helptext: cmdkit.HelpText{
86 Tagline: "Set the data field of an IPFS object.",
87 ShortDescription: `
@@ -114,36 +96,39 @@ Example:
96 cmdkit.StringArg("root", true, false, "The hash of the node to modify."),
97 cmdkit.FileArg("data", true, false, "The data to set the object to.").EnableStdin(),
98 },
117 - Run: func(req oldcmds.Request, res oldcmds.Response) {
118 - api, err := req.InvocContext().GetApi()
99 + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
100 + api, err := cmdenv.GetApi(env)
101 + if err != nil {
102 + return err
103 + }
104
120 - root, err := coreiface.ParsePath(req.StringArguments()[0])
105 + root, err := coreiface.ParsePath(req.Arguments[0])
106 if err != nil {
122 - res.SetError(err, cmdkit.ErrNormal)
123 - return
107 + return err
108 }
109
126 - data, err := req.Files().NextFile()
110 + data, err := req.Files.NextFile()
111 if err != nil {
128 - res.SetError(err, cmdkit.ErrNormal)
129 - return
112 + return err
113 }
114
132 - p, err := api.Object().SetData(req.Context(), root, data)
115 + p, err := api.Object().SetData(req.Context, root, data)
116 if err != nil {
134 - res.SetError(err, cmdkit.ErrNormal)
135 - return
117 + return err
118 }
119
138 - res.SetOutput(&Object{Hash: p.Cid().String()})
120 + return res.Emit(&Object{Hash: p.Cid().String()})
121 },
122 Type: Object{},
141 - Marshalers: oldcmds.MarshalerMap{
142 - oldcmds.Text: objectMarshaler,
123 + Encoders: cmds.EncoderMap{
124 + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *Object) error {
125 + fmt.Fprintln(w, out.Hash)
126 + return nil
127 + }),
128 },
129 }
130
146 -var patchRmLinkCmd = &oldcmds.Command{
131 +var patchRmLinkCmd = &cmds.Command{
132 Helptext: cmdkit.HelpText{
133 Tagline: "Remove a link from a given object.",
134 ShortDescription: `
@@ -154,35 +139,35 @@ Remove a Merkle-link from the given object and return the hash of the result.
139 cmdkit.StringArg("root", true, false, "The hash of the node to modify."),
140 cmdkit.StringArg("name", true, false, "Name of the link to remove."),
141 },
157 - Run: func(req oldcmds.Request, res oldcmds.Response) {
158 - api, err := req.InvocContext().GetApi()
142 + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
143 + api, err := cmdenv.GetApi(env)
144 if err != nil {
160 - res.SetError(err, cmdkit.ErrNormal)
161 - return
145 + return err
146 }
147
164 - root, err := coreiface.ParsePath(req.Arguments()[0])
148 + root, err := coreiface.ParsePath(req.Arguments[0])
149 if err != nil {
166 - res.SetError(err, cmdkit.ErrNormal)
167 - return
150 + return err
151 }
152
170 - name := req.Arguments()[1]
171 - p, err := api.Object().RmLink(req.Context(), root, name)
153 + name := req.Arguments[1]
154 + p, err := api.Object().RmLink(req.Context, root, name)
155 if err != nil {
173 - res.SetError(err, cmdkit.ErrNormal)
174 - return
156 + return err
157 }
158
177 - res.SetOutput(&Object{Hash: p.Cid().String()})
159 + return res.Emit(&Object{Hash: p.Cid().String()})
160 },
161 Type: Object{},
180 - Marshalers: oldcmds.MarshalerMap{
181 - oldcmds.Text: objectMarshaler,
162 + Encoders: cmds.EncoderMap{
163 + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *Object) error {
164 + fmt.Fprintln(w, out.Hash)
165 + return nil
166 + }),
167 },
168 }
169
185 -var patchAddLinkCmd = &oldcmds.Command{
170 +var patchAddLinkCmd = &cmds.Command{
171 Helptext: cmdkit.HelpText{
172 Tagline: "Add a link to a given object.",
173 ShortDescription: `
@@ -206,44 +191,42 @@ to a file containing 'bar', and returns the hash of the new object.
191 Options: []cmdkit.Option{
192 cmdkit.BoolOption("create", "p", "Create intermediary nodes."),
193 },
209 - Run: func(req oldcmds.Request, res oldcmds.Response) {
210 - api, err := req.InvocContext().GetApi()
194 + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
195 + api, err := cmdenv.GetApi(env)
196 if err != nil {
212 - res.SetError(err, cmdkit.ErrNormal)
213 - return
197 + return err
198 }
199
216 - root, err := coreiface.ParsePath(req.Arguments()[0])
200 + root, err := coreiface.ParsePath(req.Arguments[0])
201 if err != nil {
218 - res.SetError(err, cmdkit.ErrNormal)
219 - return
202 + return err
203 }
204
222 - name := req.Arguments()[1]
205 + name := req.Arguments[1]
206
224 - child, err := coreiface.ParsePath(req.Arguments()[2])
207 + child, err := coreiface.ParsePath(req.Arguments[2])
208 if err != nil {
226 - res.SetError(err, cmdkit.ErrNormal)
227 - return
209 + return err
210 }
211
230 - create, _, err := req.Option("create").Bool()
212 + create, _ := req.Options["create"].(bool)
213 if err != nil {
232 - res.SetError(err, cmdkit.ErrNormal)
233 - return
214 + return err
215 }
216
236 - p, err := api.Object().AddLink(req.Context(), root, name, child,
217 + p, err := api.Object().AddLink(req.Context, root, name, child,
218 options.Object.Create(create))
219 if err != nil {
239 - res.SetError(err, cmdkit.ErrNormal)
240 - return
220 + return err
221 }
222
243 - res.SetOutput(&Object{Hash: p.Cid().String()})
223 + return res.Emit(&Object{Hash: p.Cid().String()})
224 },
225 Type: Object{},
246 - Marshalers: oldcmds.MarshalerMap{
247 - oldcmds.Text: objectMarshaler,
226 + Encoders: cmds.EncoderMap{
227 + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *Object) error {
228 + fmt.Fprintln(w, out.Hash)
229 + return nil
230 + }),
231 },
232 }
core/commands/root.go
+2 -2
@@ -174,8 +174,8 @@ var rootROSubcommands = map[string]*cmds.Command{
174 "resolve": name.IpnsCmd,
175 },
176 },
177 - "object": lgc.NewCommand(&oldcmds.Command{
178 - Subcommands: map[string]*oldcmds.Command{
177 + "object": {
178 + Subcommands: map[string]*cmds.Command{
179 "data": ocmd.ObjectDataCmd,
180 "links": ocmd.ObjectLinksCmd,
181 "get": ocmd.ObjectGetCmd,