allow patch add-link to add at a path
License: MIT Signed-off-by: Jeromy <jeromyj@gmail.com>
Jeromy committed
Jun 19, 2015 at 20:45 UTC
d585e20ebc35f64f21467b1d04198e38e80b27ec
2 files changed
+63
-10
core/commands/object.go
+49
-10
@@ -582,36 +582,75 @@ func addLinkCaller(req cmds.Request, root *dag.Node) (key.Key, error) {
582
return "", err
583
}
584
585
- name := req.Arguments()[2]
585
+ path := req.Arguments()[2]
586
childk := key.B58KeyDecode(req.Arguments()[3])
587
588
- newkey, err := addLink(req.Context().Context, nd.DAG, root, name, childk)
588
+ parts := strings.Split(path, "/")
589
+
590
+ nnode, err := insertNodeAtPath(req.Context().Context, nd.DAG, root, parts, childk)
591
if err != nil {
592
return "", err
593
}
592
-
593
- return newkey, nil
594
+ return nnode.Key()
595
}
596
596
-func addLink(ctx context.Context, ds dag.DAGService, root *dag.Node, childname string, childk key.Key) (key.Key, error) {
597
+func addLink(ctx context.Context, ds dag.DAGService, root *dag.Node, childname string, childk key.Key) (*dag.Node, error) {
598
ctx, cancel := context.WithTimeout(ctx, time.Second*30)
599
childnd, err := ds.Get(ctx, childk)
600
if err != nil {
601
cancel()
601
- return "", err
602
+ return nil, err
603
}
604
cancel()
605
606
err = root.AddNodeLinkClean(childname, childnd)
607
if err != nil {
607
- return "", err
608
+ return nil, err
609
}
610
610
- newkey, err := ds.Add(root)
611
+ _, err = ds.Add(root)
612
if err != nil {
612
- return "", err
613
+ return nil, err
614
}
614
- return newkey, nil
615
+ return root, nil
616
+}
617
+
618
+func insertNodeAtPath(ctx context.Context, ds dag.DAGService, root *dag.Node, path []string, toinsert key.Key) (*dag.Node, error) {
619
+ if len(path) == 1 {
620
+ return addLink(ctx, ds, root, path[0], toinsert)
621
+ }
622
+
623
+ child, err := root.GetNodeLink(path[0])
624
+ if err != nil {
625
+ return nil, err
626
+ }
627
+
628
+ nd, err := child.GetNode(ctx, ds)
629
+ if err != nil {
630
+ return nil, err
631
+ }
632
+
633
+ ndprime, err := insertNodeAtPath(ctx, ds, nd, path[1:], toinsert)
634
+ if err != nil {
635
+ return nil, err
636
+ }
637
+
638
+ err = root.RemoveNodeLink(path[0])
639
+ if err != nil {
640
+ return nil, err
641
+ }
642
+
643
+ err = root.AddNodeLinkClean(path[0], ndprime)
644
+ if err != nil {
645
+ return nil, err
646
+ }
647
+
648
+ _, err = ds.Add(root)
649
+ if err != nil {
650
+ return nil, err
651
+ }
652
+
653
+ return root, nil
654
}
655
656
func nodeFromTemplate(template string) (*dag.Node, error) {
test/sharness/t0051-object.sh
+14
@@ -100,6 +100,20 @@ test_object_cmd() {
100
OUTPUT=$(ipfs object patch $EMPTY_DIR add-link foo $EMPTY_DIR)
101
'
102
103
+ test_expect_success "multilayer ipfs patch works" '
104
+ echo "hello world" > hwfile &&
105
+ FILE=$(ipfs add -q hwfile) &&
106
+ EMPTY=$(ipfs object new unixfs-dir) &&
107
+ ONE=$(ipfs object patch $EMPTY add-link b $EMPTY) &&
108
+ TWO=$(ipfs object patch $EMPTY add-link a $ONE) &&
109
+ ipfs object patch $TWO add-link a/b/c $FILE > multi_patch
110
+ '
111
+
112
+ test_expect_success "output looks good" '
113
+ ipfs cat $(cat multi_patch)/a/b/c > hwfile_out &&
114
+ test_cmp hwfile hwfile_out
115
+ '
116
+
117
test_expect_success "should have created dir within a dir" '
118
ipfs ls $OUTPUT > patched_output
119
'