@cryptotaxi247 / kubo / commits / 36c6fb353

commands: switch object commands to CoreAPI

License: MIT Signed-off-by: Łukasz Magiera <magik6k@gmail.com>

Łukasz Magiera committed Feb 2, 2018 at 22:36 UTC 36c6fb3530175573c1f754f9089a95fad2104719
7 files changed +151 -358
core/commands/env.go
+11
@@ -5,6 +5,7 @@ import (
5
6 "github.com/ipfs/go-ipfs/commands"
7 "github.com/ipfs/go-ipfs/core"
8 + coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
9 "github.com/ipfs/go-ipfs/repo/config"
10 )
11
@@ -18,6 +19,16 @@ func GetNode(env interface{}) (*core.IpfsNode, error) {
19 return ctx.GetNode()
20 }
21
22 +// GetApi extracts CoreAPI instance from the environment.
23 +func GetApi(env interface{}) (coreiface.CoreAPI, error) {
24 + ctx, ok := env.(*commands.Context)
25 + if !ok {
26 + return nil, fmt.Errorf("expected env to be of type %T, got %T", ctx, env)
27 + }
28 +
29 + return ctx.GetApi()
30 +}
31 +
32 // GetConfig extracts the config from the environment.
33 func GetConfig(env interface{}) (*config.Config, error) {
34 ctx, ok := env.(*commands.Context)
core/commands/object/diff.go
+19 -21
@@ -6,10 +6,10 @@ import (
6 "io"
7
8 cmds "github.com/ipfs/go-ipfs/commands"
9 - core "github.com/ipfs/go-ipfs/core"
9 e "github.com/ipfs/go-ipfs/core/commands/e"
10 + coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
11 "github.com/ipfs/go-ipfs/dagutils"
12 - path "gx/ipfs/QmYKNMEUK7nCVAefgXF1LVtZEZg3uRmBqiae4FJRXDNAyJ/go-path"
12 +
13 cmdkit "gx/ipfs/QmdE4gMduCKCGAcczM2F5ioYDfdeKuPix138wrES1YSr7f/go-ipfs-cmdkit"
14 )
15
@@ -52,7 +52,7 @@ Example:
52 cmdkit.BoolOption("verbose", "v", "Print extra information."),
53 },
54 Run: func(req cmds.Request, res cmds.Response) {
55 - node, err := req.InvocContext().GetNode()
55 + api, err := req.InvocContext().GetApi()
56 if err != nil {
57 res.SetError(err, cmdkit.ErrNormal)
58 return
@@ -61,39 +61,37 @@ Example:
61 a := req.Arguments()[0]
62 b := req.Arguments()[1]
63
64 - pa, err := path.ParsePath(a)
64 + pa, err := coreiface.ParsePath(a)
65 if err != nil {
66 res.SetError(err, cmdkit.ErrNormal)
67 return
68 }
69
70 - pb, err := path.ParsePath(b)
70 + pb, err := coreiface.ParsePath(b)
71 if err != nil {
72 res.SetError(err, cmdkit.ErrNormal)
73 return
74 }
75
76 - ctx := req.Context()
76 + changes, err := api.Object().Diff(req.Context(), pa, pb)
77
78 - obj_a, err := core.Resolve(ctx, node.Namesys, node.Resolver, pa)
79 - if err != nil {
80 - res.SetError(err, cmdkit.ErrNormal)
81 - return
82 - }
78 + out := make([]*dagutils.Change, len(changes))
79 + for i, change := range changes {
80 + out[i] = &dagutils.Change{
81 + Type: change.Type,
82 + Path: change.Path,
83 + }
84
84 - obj_b, err := core.Resolve(ctx, node.Namesys, node.Resolver, pb)
85 - if err != nil {
86 - res.SetError(err, cmdkit.ErrNormal)
87 - return
88 - }
85 + if change.Before != nil {
86 + out[i].Before = change.Before.Cid()
87 + }
88
90 - changes, err := dagutils.Diff(ctx, node.DAG, obj_a, obj_b)
91 - if err != nil {
92 - res.SetError(err, cmdkit.ErrNormal)
93 - return
89 + if change.After != nil {
90 + out[i].After = change.After.Cid()
91 + }
92 }
93
96 - res.SetOutput(&Changes{changes})
94 + res.SetOutput(&Changes{out})
95 },
96 Type: Changes{},
97 Marshalers: cmds.MarshalerMap{
core/commands/object/object.go
+79 -196
@@ -2,10 +2,7 @@ package objectcmd
2
3 import (
4 "bytes"
5 - "context"
5 "encoding/base64"
7 - "encoding/json"
8 - "encoding/xml"
6 "errors"
7 "fmt"
8 "io"
@@ -15,14 +12,12 @@ import (
12
13 oldcmds "github.com/ipfs/go-ipfs/commands"
14 lgc "github.com/ipfs/go-ipfs/commands/legacy"
18 - core "github.com/ipfs/go-ipfs/core"
15 e "github.com/ipfs/go-ipfs/core/commands/e"
20 - pin "github.com/ipfs/go-ipfs/pin"
21 - dag "gx/ipfs/QmRy4Qk9hbgFX9NGJRm8rBThrA8PZhNCitMgeRYyZ67s59/go-merkledag"
22 - ft "gx/ipfs/QmSaz8Qg77gGqvDvLKeSAY7ivDEnramSWF6T7TcRwFpHtP/go-unixfs"
23 - path "gx/ipfs/QmYKNMEUK7nCVAefgXF1LVtZEZg3uRmBqiae4FJRXDNAyJ/go-path"
16 + coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
17 + "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
18
19 cmds "gx/ipfs/QmNueRyPRQiV7PUEpnP4GgGLuK1rKQLaRW7sfPvUetYig1/go-ipfs-cmds"
20 + dag "gx/ipfs/QmRy4Qk9hbgFX9NGJRm8rBThrA8PZhNCitMgeRYyZ67s59/go-merkledag"
21 cid "gx/ipfs/QmYVNvtQkeZ6AKSwDrjQTs432QtL6umrrK41EBq3cu7iSP/go-cid"
22 ipld "gx/ipfs/QmZtNq8dArGfnpCZfx2pUNY7UcjGhVp5qqwQ4hH6mpTMRQ/go-ipld-format"
23 cmdkit "gx/ipfs/QmdE4gMduCKCGAcczM2F5ioYDfdeKuPix138wrES1YSr7f/go-ipfs-cmdkit"
@@ -88,31 +83,25 @@ is the raw data of the object.
83 cmdkit.StringArg("key", true, false, "Key of the object to retrieve, in base58-encoded multihash format.").EnableStdin(),
84 },
85 Run: func(req oldcmds.Request, res oldcmds.Response) {
91 - n, err := req.InvocContext().GetNode()
86 + api, err := req.InvocContext().GetApi()
87 if err != nil {
88 res.SetError(err, cmdkit.ErrNormal)
89 return
90 }
91
97 - fpath, err := path.ParsePath(req.Arguments()[0])
92 + path, err := coreiface.ParsePath(req.Arguments()[0])
93 if err != nil {
94 res.SetError(err, cmdkit.ErrNormal)
95 return
96 }
97
103 - node, err := core.Resolve(req.Context(), n.Namesys, n.Resolver, fpath)
98 + data, err := api.Object().Data(req.Context(), path)
99 if err != nil {
100 res.SetError(err, cmdkit.ErrNormal)
101 return
102 }
103
109 - pbnode, ok := node.(*dag.ProtoNode)
110 - if !ok {
111 - res.SetError(dag.ErrNotProtobuf, cmdkit.ErrNormal)
112 - return
113 - }
114 -
115 - res.SetOutput(bytes.NewReader(pbnode.Data()))
104 + res.SetOutput(data)
105 },
106 }
107
@@ -133,7 +122,7 @@ multihash.
122 cmdkit.BoolOption("headers", "v", "Print table headers (Hash, Size, Name)."),
123 },
124 Run: func(req oldcmds.Request, res oldcmds.Response) {
136 - n, err := req.InvocContext().GetNode()
125 + api, err := req.InvocContext().GetApi()
126 if err != nil {
127 res.SetError(err, cmdkit.ErrNormal)
128 return
@@ -145,19 +134,39 @@ multihash.
134 return
135 }
136
148 - fpath := path.Path(req.Arguments()[0])
149 - node, err := core.Resolve(req.Context(), n.Namesys, n.Resolver, fpath)
137 + path, err := coreiface.ParsePath(req.Arguments()[0])
138 + if err != nil {
139 + res.SetError(err, cmdkit.ErrNormal)
140 + return
141 + }
142 +
143 + rp, err := api.ResolvePath(req.Context(), path)
144 if err != nil {
145 res.SetError(err, cmdkit.ErrNormal)
146 return
147 }
148
155 - output, err := getOutput(node)
149 + links, err := api.Object().Links(req.Context(), rp)
150 if err != nil {
151 res.SetError(err, cmdkit.ErrNormal)
152 return
153 }
160 - res.SetOutput(output)
154 +
155 + outLinks := make([]Link, len(links))
156 + for i, link := range links {
157 + outLinks[i] = Link{
158 + Hash: link.Cid.String(),
159 + Name: link.Name,
160 + Size: link.Size,
161 + }
162 + }
163 +
164 + out := Object{
165 + Hash: rp.Cid().String(),
166 + Links: outLinks,
167 + }
168 +
169 + res.SetOutput(out)
170 },
171 Marshalers: oldcmds.MarshalerMap{
172 oldcmds.Text: func(res oldcmds.Response) (io.Reader, error) {
@@ -222,13 +231,17 @@ Supported values are:
231 cmdkit.StringOption("data-encoding", "Encoding type of the data field, either \"text\" or \"base64\".").WithDefault("text"),
232 },
233 Run: func(req oldcmds.Request, res oldcmds.Response) {
225 - n, err := req.InvocContext().GetNode()
234 + api, err := req.InvocContext().GetApi()
235 if err != nil {
236 res.SetError(err, cmdkit.ErrNormal)
237 return
238 }
239
231 - fpath := path.Path(req.Arguments()[0])
240 + path, err := coreiface.ParsePath(req.Arguments()[0])
241 + if err != nil {
242 + res.SetError(err, cmdkit.ErrNormal)
243 + return
244 + }
245
246 datafieldenc, _, err := req.Option("data-encoding").String()
247 if err != nil {
@@ -236,30 +249,36 @@ Supported values are:
249 return
250 }
251
239 - object, err := core.Resolve(req.Context(), n.Namesys, n.Resolver, fpath)
252 + nd, err := api.Object().Get(req.Context(), path)
253 if err != nil {
254 res.SetError(err, cmdkit.ErrNormal)
255 return
256 }
257
245 - pbo, ok := object.(*dag.ProtoNode)
246 - if !ok {
247 - res.SetError(dag.ErrNotProtobuf, cmdkit.ErrNormal)
258 + r, err := api.Object().Data(req.Context(), path)
259 + if err != nil {
260 + res.SetError(err, cmdkit.ErrNormal)
261 return
262 }
263
251 - data, err := encodeData(pbo.Data(), datafieldenc)
264 + data, err := ioutil.ReadAll(r)
265 + if err != nil {
266 + res.SetError(err, cmdkit.ErrNormal)
267 + return
268 + }
269 +
270 + out, err := encodeData(data, datafieldenc)
271 if err != nil {
272 res.SetError(err, cmdkit.ErrNormal)
273 return
274 }
275
276 node := &Node{
258 - Links: make([]Link, len(object.Links())),
259 - Data: data,
277 + Links: make([]Link, len(nd.Links())),
278 + Data: out,
279 }
280
262 - for i, link := range object.Links() {
281 + for i, link := range nd.Links() {
282 node.Links[i] = Link{
283 Hash: link.Cid.String(),
284 Name: link.Name,
@@ -316,27 +335,34 @@ var ObjectStatCmd = &oldcmds.Command{
335 cmdkit.StringArg("key", true, false, "Key of the object to retrieve, in base58-encoded multihash format.").EnableStdin(),
336 },
337 Run: func(req oldcmds.Request, res oldcmds.Response) {
319 - n, err := req.InvocContext().GetNode()
338 + api, err := req.InvocContext().GetApi()
339 if err != nil {
340 res.SetError(err, cmdkit.ErrNormal)
341 return
342 }
343
325 - fpath := path.Path(req.Arguments()[0])
326 -
327 - object, err := core.Resolve(req.Context(), n.Namesys, n.Resolver, fpath)
344 + path, err := coreiface.ParsePath(req.Arguments()[0])
345 if err != nil {
346 res.SetError(err, cmdkit.ErrNormal)
347 return
348 }
349
333 - ns, err := object.Stat()
350 + ns, err := api.Object().Stat(req.Context(), path)
351 if err != nil {
352 res.SetError(err, cmdkit.ErrNormal)
353 return
354 }
355
339 - res.SetOutput(ns)
356 + oldStat := &ipld.NodeStat{
357 + Hash: ns.Cid.String(),
358 + NumLinks: ns.NumLinks,
359 + BlockSize: ns.BlockSize,
360 + LinksSize: ns.LinksSize,
361 + DataSize: ns.DataSize,
362 + CumulativeSize: ns.CumulativeSize,
363 + }
364 +
365 + res.SetOutput(oldStat)
366 },
367 Type: ipld.NodeStat{},
368 Marshalers: oldcmds.MarshalerMap{
@@ -414,7 +440,7 @@ And then run:
440 cmdkit.BoolOption("quiet", "q", "Write minimal output."),
441 },
442 Run: func(req oldcmds.Request, res oldcmds.Response) {
417 - n, err := req.InvocContext().GetNode()
443 + api, err := req.InvocContext().GetApi()
444 if err != nil {
445 res.SetError(err, cmdkit.ErrNormal)
446 return
@@ -444,30 +470,16 @@ And then run:
470 return
471 }
472
447 - if dopin {
448 - defer n.Blockstore.PinLock().Unlock()
449 - }
450 -
451 - objectCid, err := objectPut(req.Context(), n, input, inputenc, datafieldenc)
473 + p, err := api.Object().Put(req.Context(), input,
474 + options.Object.DataType(datafieldenc),
475 + options.Object.InputEnc(inputenc),
476 + options.Object.Pin(dopin))
477 if err != nil {
453 - errType := cmdkit.ErrNormal
454 - if err == ErrUnknownObjectEnc {
455 - errType = cmdkit.ErrClient
456 - }
457 - res.SetError(err, errType)
478 + res.SetError(err, cmdkit.ErrNormal)
479 return
480 }
481
461 - if dopin {
462 - n.Pinning.PinWithMode(objectCid, pin.Recursive)
463 - err = n.Pinning.Flush()
464 - if err != nil {
465 - res.SetError(err, cmdkit.ErrNormal)
466 - return
467 - }
468 - }
469 -
470 - res.SetOutput(&Object{Hash: objectCid.String()})
482 + res.SetOutput(&Object{Hash: p.Cid().String()})
483 },
484 Marshalers: oldcmds.MarshalerMap{
485 oldcmds.Text: func(res oldcmds.Response) (io.Reader, error) {
@@ -513,29 +525,24 @@ Available templates:
525 cmdkit.StringArg("template", false, false, "Template to use. Optional."),
526 },
527 Run: func(req oldcmds.Request, res oldcmds.Response) {
516 - n, err := req.InvocContext().GetNode()
528 + api, err := req.InvocContext().GetApi()
529 if err != nil {
530 res.SetError(err, cmdkit.ErrNormal)
531 return
532 }
533
522 - node := new(dag.ProtoNode)
534 + template := "empty"
535 if len(req.Arguments()) == 1 {
524 - template := req.Arguments()[0]
525 - var err error
526 - node, err = nodeFromTemplate(template)
527 - if err != nil {
528 - res.SetError(err, cmdkit.ErrNormal)
529 - return
530 - }
536 + template = req.Arguments()[0]
537 }
538
533 - err = n.DAG.Add(req.Context(), node)
534 - if err != nil {
539 + nd, err := api.Object().New(req.Context(), options.Object.Type(template))
540 + if err != nil && err != io.EOF {
541 res.SetError(err, cmdkit.ErrNormal)
542 return
543 }
538 - res.SetOutput(&Object{Hash: node.Cid().String()})
544 +
545 + res.SetOutput(&Object{Hash: nd.Cid().String()})
546 },
547 Marshalers: oldcmds.MarshalerMap{
548 oldcmds.Text: func(res oldcmds.Response) (io.Reader, error) {
@@ -555,126 +562,6 @@ Available templates:
562 Type: Object{},
563 }
564
558 -func nodeFromTemplate(template string) (*dag.ProtoNode, error) {
559 - switch template {
560 - case "unixfs-dir":
561 - return ft.EmptyDirNode(), nil
562 - default:
563 - return nil, fmt.Errorf("template '%s' not found", template)
564 - }
565 -}
566 -
567 -// ErrEmptyNode is returned when the input to 'ipfs object put' contains no data
568 -var ErrEmptyNode = errors.New("no data or links in this node")
569 -
570 -// objectPut takes a format option, serializes bytes from stdin and updates the dag with that data
571 -func objectPut(ctx context.Context, n *core.IpfsNode, input io.Reader, encoding string, dataFieldEncoding string) (*cid.Cid, error) {
572 -
573 - data, err := ioutil.ReadAll(io.LimitReader(input, inputLimit+10))
574 - if err != nil {
575 - return nil, err
576 - }
577 -
578 - if len(data) >= inputLimit {
579 - return nil, ErrObjectTooLarge
580 - }
581 -
582 - var dagnode *dag.ProtoNode
583 - switch getObjectEnc(encoding) {
584 - case objectEncodingJSON:
585 - node := new(Node)
586 - err = json.Unmarshal(data, node)
587 - if err != nil {
588 - return nil, err
589 - }
590 -
591 - // check that we have data in the Node to add
592 - // otherwise we will add the empty object without raising an error
593 - if NodeEmpty(node) {
594 - return nil, ErrEmptyNode
595 - }
596 -
597 - dagnode, err = deserializeNode(node, dataFieldEncoding)
598 - if err != nil {
599 - return nil, err
600 - }
601 -
602 - case objectEncodingProtobuf:
603 - dagnode, err = dag.DecodeProtobuf(data)
604 -
605 - case objectEncodingXML:
606 - node := new(Node)
607 - err = xml.Unmarshal(data, node)
608 - if err != nil {
609 - return nil, err
610 - }
611 -
612 - // check that we have data in the Node to add
613 - // otherwise we will add the empty object without raising an error
614 - if NodeEmpty(node) {
615 - return nil, ErrEmptyNode
616 - }
617 -
618 - dagnode, err = deserializeNode(node, dataFieldEncoding)
619 - if err != nil {
620 - return nil, err
621 - }
622 -
623 - default:
624 - return nil, ErrUnknownObjectEnc
625 - }
626 -
627 - if err != nil {
628 - return nil, err
629 - }
630 -
631 - err = n.DAG.Add(ctx, dagnode)
632 - if err != nil {
633 - return nil, err
634 - }
635 -
636 - return dagnode.Cid(), nil
637 -}
638 -
639 -// ErrUnknownObjectEnc is returned if a invalid encoding is supplied
640 -var ErrUnknownObjectEnc = errors.New("unknown object encoding")
641 -
642 -type objectEncoding string
643 -
644 -const (
645 - objectEncodingJSON objectEncoding = "json"
646 - objectEncodingProtobuf = "protobuf"
647 - objectEncodingXML = "xml"
648 -)
649 -
650 -func getObjectEnc(o interface{}) objectEncoding {
651 - v, ok := o.(string)
652 - if !ok {
653 - // chosen as default because it's human readable
654 - return objectEncodingJSON
655 - }
656 -
657 - return objectEncoding(v)
658 -}
659 -
660 -func getOutput(dagnode ipld.Node) (*Object, error) {
661 - c := dagnode.Cid()
662 - output := &Object{
663 - Hash: c.String(),
664 - Links: make([]Link, len(dagnode.Links())),
665 - }
666 -
667 - for i, link := range dagnode.Links() {
668 - output.Links[i] = Link{
669 - Name: link.Name,
670 - Hash: link.Cid.String(),
671 - Size: link.Size,
672 - }
673 - }
674 -
675 - return output, nil
676 -}
677 -
565 // converts the Node object into a real dag.ProtoNode
566 func deserializeNode(nd *Node, dataFieldEncoding string) (*dag.ProtoNode, error) {
567 dagnode := new(dag.ProtoNode)
@@ -708,10 +595,6 @@ func deserializeNode(nd *Node, dataFieldEncoding string) (*dag.ProtoNode, error)
595 return dagnode, nil
596 }
597
711 -func NodeEmpty(node *Node) bool {
712 - return node.Data == "" && len(node.Links) == 0
713 -}
714 -
598 // copy+pasted from ../commands.go
599 func unwrapOutput(i interface{}) (interface{}, error) {
600 var (
core/commands/object/patch.go
+28 -132
@@ -3,25 +3,18 @@ package objectcmd
3 import (
4 "fmt"
5 "io"
6 - "io/ioutil"
6 "strings"
7
8 oldcmds "github.com/ipfs/go-ipfs/commands"
9 lgc "github.com/ipfs/go-ipfs/commands/legacy"
11 - core "github.com/ipfs/go-ipfs/core"
10 e "github.com/ipfs/go-ipfs/core/commands/e"
13 - "github.com/ipfs/go-ipfs/dagutils"
14 - dag "gx/ipfs/QmRy4Qk9hbgFX9NGJRm8rBThrA8PZhNCitMgeRYyZ67s59/go-merkledag"
15 - ft "gx/ipfs/QmSaz8Qg77gGqvDvLKeSAY7ivDEnramSWF6T7TcRwFpHtP/go-unixfs"
16 - path "gx/ipfs/QmYKNMEUK7nCVAefgXF1LVtZEZg3uRmBqiae4FJRXDNAyJ/go-path"
11 + coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
12 + "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
13
14 cmds "gx/ipfs/QmNueRyPRQiV7PUEpnP4GgGLuK1rKQLaRW7sfPvUetYig1/go-ipfs-cmds"
19 - logging "gx/ipfs/QmcVVHfdyv15GVPk7NrxdWjh2hLVccXnoD8j2tyQShiXJb/go-log"
15 cmdkit "gx/ipfs/QmdE4gMduCKCGAcczM2F5ioYDfdeKuPix138wrES1YSr7f/go-ipfs-cmdkit"
16 )
17
23 -var log = logging.Logger("core/commands/object")
24 -
18 var ObjectPatchCmd = &cmds.Command{
19 Helptext: cmdkit.HelpText{
20 Tagline: "Create a new merkledag object based on an existing one.",
@@ -74,51 +67,31 @@ the limit will not be respected by the network.
67 cmdkit.FileArg("data", true, false, "Data to append.").EnableStdin(),
68 },
69 Run: func(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment) {
77 - nd, err := GetNode(env)
78 - if err != nil {
79 - re.SetError(err, cmdkit.ErrNormal)
80 - return
81 - }
82 -
83 - root, err := path.ParsePath(req.Arguments[0])
84 - if err != nil {
85 - re.SetError(err, cmdkit.ErrNormal)
86 - return
87 - }
88 -
89 - rootnd, err := core.Resolve(req.Context, nd.Namesys, nd.Resolver, root)
70 + api, err := GetApi(env)
71 if err != nil {
72 re.SetError(err, cmdkit.ErrNormal)
73 return
74 }
75
95 - rtpb, ok := rootnd.(*dag.ProtoNode)
96 - if !ok {
97 - re.SetError(dag.ErrNotProtobuf, cmdkit.ErrNormal)
98 - return
99 - }
100 -
101 - fi, err := req.Files.NextFile()
76 + root, err := coreiface.ParsePath(req.Arguments[0])
77 if err != nil {
78 re.SetError(err, cmdkit.ErrNormal)
79 return
80 }
81
107 - data, err := ioutil.ReadAll(fi)
82 + data, err := req.Files.NextFile()
83 if err != nil {
84 re.SetError(err, cmdkit.ErrNormal)
85 return
86 }
87
113 - rtpb.SetData(append(rtpb.Data(), data...))
114 -
115 - err = nd.DAG.Add(req.Context, rtpb)
88 + p, err := api.Object().AppendData(req.Context, root, data)
89 if err != nil {
90 re.SetError(err, cmdkit.ErrNormal)
91 return
92 }
93
121 - cmds.EmitOnce(re, &Object{Hash: rtpb.Cid().String()})
94 + cmds.EmitOnce(re, &Object{Hash: p.Cid().String()})
95 },
96 Type: Object{},
97 Encoders: cmds.EncoderMap{
@@ -145,51 +118,27 @@ Example:
118 cmdkit.FileArg("data", true, false, "The data to set the object to.").EnableStdin(),
119 },
120 Run: func(req oldcmds.Request, res oldcmds.Response) {
148 - nd, err := req.InvocContext().GetNode()
149 - if err != nil {
150 - res.SetError(err, cmdkit.ErrNormal)
151 - return
152 - }
121 + api, err := req.InvocContext().GetApi()
122
154 - rp, err := path.ParsePath(req.StringArguments()[0])
123 + root, err := coreiface.ParsePath(req.StringArguments()[0])
124 if err != nil {
125 res.SetError(err, cmdkit.ErrNormal)
126 return
127 }
128
160 - root, err := core.Resolve(req.Context(), nd.Namesys, nd.Resolver, rp)
161 - if err != nil {
162 - res.SetError(err, cmdkit.ErrNormal)
163 - return
164 - }
165 -
166 - rtpb, ok := root.(*dag.ProtoNode)
167 - if !ok {
168 - res.SetError(dag.ErrNotProtobuf, cmdkit.ErrNormal)
169 - return
170 - }
171 -
172 - fi, err := req.Files().NextFile()
129 + data, err := req.Files().NextFile()
130 if err != nil {
131 res.SetError(err, cmdkit.ErrNormal)
132 return
133 }
134
178 - data, err := ioutil.ReadAll(fi)
135 + p, err := api.Object().SetData(req.Context(), root, data)
136 if err != nil {
137 res.SetError(err, cmdkit.ErrNormal)
138 return
139 }
140
184 - rtpb.SetData(data)
185 -
186 - err = nd.DAG.Add(req.Context(), rtpb)
187 - if err != nil {
188 - res.SetError(err, cmdkit.ErrNormal)
189 - return
190 - }
191 -
192 - res.SetOutput(&Object{Hash: rtpb.Cid().String()})
141 + res.SetOutput(&Object{Hash: p.Cid().String()})
142 },
143 Type: Object{},
144 Marshalers: oldcmds.MarshalerMap{
@@ -209,49 +158,26 @@ Removes a link by the given name from root.
158 cmdkit.StringArg("link", true, false, "Name of the link to remove."),
159 },
160 Run: func(req oldcmds.Request, res oldcmds.Response) {
212 - nd, err := req.InvocContext().GetNode()
213 - if err != nil {
214 - res.SetError(err, cmdkit.ErrNormal)
215 - return
216 - }
217 -
218 - rootp, err := path.ParsePath(req.Arguments()[0])
161 + api, err := req.InvocContext().GetApi()
162 if err != nil {
163 res.SetError(err, cmdkit.ErrNormal)
164 return
165 }
166
224 - root, err := core.Resolve(req.Context(), nd.Namesys, nd.Resolver, rootp)
225 - if err != nil {
226 - res.SetError(err, cmdkit.ErrNormal)
227 - return
228 - }
229 -
230 - rtpb, ok := root.(*dag.ProtoNode)
231 - if !ok {
232 - res.SetError(dag.ErrNotProtobuf, cmdkit.ErrNormal)
233 - return
234 - }
235 -
236 - path := req.Arguments()[1]
237 -
238 - e := dagutils.NewDagEditor(rtpb, nd.DAG)
239 -
240 - err = e.RmLink(req.Context(), path)
167 + root, err := coreiface.ParsePath(req.Arguments()[0])
168 if err != nil {
169 res.SetError(err, cmdkit.ErrNormal)
170 return
171 }
172
246 - nnode, err := e.Finalize(req.Context(), nd.DAG)
173 + link := req.Arguments()[1]
174 + p, err := api.Object().RmLink(req.Context(), root, link)
175 if err != nil {
176 res.SetError(err, cmdkit.ErrNormal)
177 return
178 }
179
252 - nc := nnode.Cid()
253 -
254 - res.SetOutput(&Object{Hash: nc.String()})
180 + res.SetOutput(&Object{Hash: p.Cid().String()})
181 },
182 Type: Object{},
183 Marshalers: oldcmds.MarshalerMap{
@@ -284,32 +210,21 @@ to a file containing 'bar', and returns the hash of the new object.
210 cmdkit.BoolOption("create", "p", "Create intermediary nodes."),
211 },
212 Run: func(req oldcmds.Request, res oldcmds.Response) {
287 - nd, err := req.InvocContext().GetNode()
213 + api, err := req.InvocContext().GetApi()
214 if err != nil {
215 res.SetError(err, cmdkit.ErrNormal)
216 return
217 }
218
293 - rootp, err := path.ParsePath(req.Arguments()[0])
219 + root, err := coreiface.ParsePath(req.Arguments()[0])
220 if err != nil {
221 res.SetError(err, cmdkit.ErrNormal)
222 return
223 }
224
299 - root, err := core.Resolve(req.Context(), nd.Namesys, nd.Resolver, rootp)
300 - if err != nil {
301 - res.SetError(err, cmdkit.ErrNormal)
302 - return
303 - }
225 + name := req.Arguments()[1]
226
305 - rtpb, ok := root.(*dag.ProtoNode)
306 - if !ok {
307 - res.SetError(dag.ErrNotProtobuf, cmdkit.ErrNormal)
308 - return
309 - }
310 -
311 - npath := req.Arguments()[1]
312 - childp, err := path.ParsePath(req.Arguments()[2])
227 + child, err := coreiface.ParsePath(req.Arguments()[2])
228 if err != nil {
229 res.SetError(err, cmdkit.ErrNormal)
230 return
@@ -321,34 +236,14 @@ to a file containing 'bar', and returns the hash of the new object.
236 return
237 }
238
324 - var createfunc func() *dag.ProtoNode
325 - if create {
326 - createfunc = ft.EmptyDirNode
327 - }
328 -
329 - e := dagutils.NewDagEditor(rtpb, nd.DAG)
330 -
331 - childnd, err := core.Resolve(req.Context(), nd.Namesys, nd.Resolver, childp)
239 + p, err := api.Object().AddLink(req.Context(), root, name, child,
240 + options.Object.Create(create))
241 if err != nil {
242 res.SetError(err, cmdkit.ErrNormal)
243 return
244 }
245
337 - err = e.InsertNodeAtPath(req.Context(), npath, childnd, createfunc)
338 - if err != nil {
339 - res.SetError(err, cmdkit.ErrNormal)
340 - return
341 - }
342 -
343 - nnode, err := e.Finalize(req.Context(), nd.DAG)
344 - if err != nil {
345 - res.SetError(err, cmdkit.ErrNormal)
346 - return
347 - }
348 -
349 - nc := nnode.Cid()
350 -
351 - res.SetOutput(&Object{Hash: nc.String()})
246 + res.SetOutput(&Object{Hash: p.Cid().String()})
247 },
248 Type: Object{},
249 Marshalers: oldcmds.MarshalerMap{
@@ -356,13 +251,14 @@ to a file containing 'bar', and returns the hash of the new object.
251 },
252 }
253
254 +// TODO: fix import loop with core/commands so we don't need that
255 // COPIED FROM ONE LEVEL UP
360 -// GetNode extracts the node from the environment.
361 -func GetNode(env interface{}) (*core.IpfsNode, error) {
256 +// GetApi extracts CoreAPI instance from the environment.
257 +func GetApi(env interface{}) (coreiface.CoreAPI, error) {
258 ctx, ok := env.(*oldcmds.Context)
259 if !ok {
260 return nil, fmt.Errorf("expected env to be of type %T, got %T", ctx, env)
261 }
262
367 - return ctx.GetNode()
263 + return ctx.GetApi()
264 }
core/coreapi/interface/object.go
+2 -3
@@ -31,7 +31,6 @@ type ObjectStat struct {
31 CumulativeSize int
32 }
33
34 -
34 const (
35 // DiffAdd is a Type of ObjectChange where a link was added to the graph
36 DiffAdd = iota
@@ -57,11 +56,11 @@ type ObjectChange struct {
56
57 // Before holds the link path before the change. Note that when a link is
58 // added, this will be nil.
60 - Before Path
59 + Before ResolvedPath
60
61 // After holds the link path after the change. Note that when a link is
62 // removed, this will be nil.
64 - After Path
63 + After ResolvedPath
64 }
65
66 // ObjectAPI specifies the interface to MerkleDAG and contains useful utilities
core/coreapi/interface/options/object.go
+2 -2
@@ -105,9 +105,9 @@ func (objectOpts) DataType(t string) ObjectPutOption {
105 }
106 }
107
108 -// WithPin is an option for Object.Put which specifies whether to pin the added
108 +// Pin is an option for Object.Put which specifies whether to pin the added
109 // objects, default is false
110 -func (objectOpts) WithPin(pin bool) ObjectPutOption {
110 +func (objectOpts) Pin(pin bool) ObjectPutOption {
111 return func(settings *ObjectPutSettings) error {
112 settings.Pin = pin
113 return nil
core/coreapi/object.go
+10 -4
@@ -316,10 +316,16 @@ func (api *ObjectAPI) Diff(ctx context.Context, before coreiface.Path, after cor
316 out := make([]coreiface.ObjectChange, len(changes))
317 for i, change := range changes {
318 out[i] = coreiface.ObjectChange{
319 - Type: change.Type,
320 - Path: change.Path,
321 - Before: coreiface.IpfsPath(change.Before),
322 - After: coreiface.IpfsPath(change.After),
319 + Type: change.Type,
320 + Path: change.Path,
321 + }
322 +
323 + if change.Before != nil {
324 + out[i].Before = coreiface.IpfsPath(change.Before)
325 + }
326 +
327 + if change.After != nil {
328 + out[i].After = coreiface.IpfsPath(change.After)
329 }
330 }
331