allow patch to optionally create intermediate dirs
License: MIT Signed-off-by: Jeromy <jeromyj@gmail.com>
Jeromy committed
Jul 21, 2015 at 12:38 UTC
870df2431a19da8c07961b506b4fc20f4fee35c4
2 files changed
+38
-17
core/commands/object.go
+28
-17
@@ -453,7 +453,9 @@ This removes the link named foo from the hash in $FOO_BAR and returns the
453
resulting object hash.
454
`,
455
},
456
- Options: []cmds.Option{},
456
+ Options: []cmds.Option{
457
+ cmds.BoolOption("create", "p", "create intermediate directories on add-link"),
458
+ },
459
Arguments: []cmds.Argument{
460
cmds.StringArg("root", true, false, "the hash of the node to modify"),
461
cmds.StringArg("command", true, false, "the operation to perform"),
@@ -610,7 +612,12 @@ func addLinkCaller(req cmds.Request, root *dag.Node) (key.Key, error) {
612
613
parts := strings.Split(path, "/")
614
613
- nnode, err := insertNodeAtPath(req.Context(), nd.DAG, root, parts, childk)
615
+ create, _, err := req.Option("create").Bool()
616
+ if err != nil {
617
+ return "", err
618
+ }
619
+
620
+ nnode, err := insertNodeAtPath(req.Context(), nd.DAG, root, parts, childk, create)
621
if err != nil {
622
return "", err
623
}
@@ -619,12 +626,14 @@ func addLinkCaller(req cmds.Request, root *dag.Node) (key.Key, error) {
626
627
func addLink(ctx context.Context, ds dag.DAGService, root *dag.Node, childname string, childk key.Key) (*dag.Node, error) {
628
ctx, cancel := context.WithTimeout(ctx, time.Second*30)
629
+ defer cancel()
630
childnd, err := ds.Get(ctx, childk)
631
if err != nil {
624
- cancel()
632
return nil, err
633
}
627
- cancel()
634
+
635
+ // ensure no link with that name already exists
636
+ _ = root.RemoveNodeLink(childname) // ignore error, only option is ErrNotFound
637
638
err = root.AddNodeLinkClean(childname, childnd)
639
if err != nil {
@@ -638,31 +647,33 @@ func addLink(ctx context.Context, ds dag.DAGService, root *dag.Node, childname s
647
return root, nil
648
}
649
641
-func insertNodeAtPath(ctx context.Context, ds dag.DAGService, root *dag.Node, path []string, toinsert key.Key) (*dag.Node, error) {
650
+func insertNodeAtPath(ctx context.Context, ds dag.DAGService, root *dag.Node, path []string, toinsert key.Key, create bool) (*dag.Node, error) {
651
if len(path) == 1 {
652
return addLink(ctx, ds, root, path[0], toinsert)
653
}
654
655
+ var nd *dag.Node
656
child, err := root.GetNodeLink(path[0])
657
if err != nil {
648
- return nil, err
649
- }
650
-
651
- nd, err := child.GetNode(ctx, ds)
652
- if err != nil {
653
- return nil, err
654
- }
655
-
656
- ndprime, err := insertNodeAtPath(ctx, ds, nd, path[1:], toinsert)
657
- if err != nil {
658
- return nil, err
658
+ // if 'create' is true, we create directories on the way down as needed
659
+ if err == dag.ErrNotFound && create {
660
+ nd = &dag.Node{Data: ft.FolderPBData()}
661
+ } else {
662
+ return nil, err
663
+ }
664
+ } else {
665
+ nd, err = child.GetNode(ctx, ds)
666
+ if err != nil {
667
+ return nil, err
668
+ }
669
}
670
661
- err = root.RemoveNodeLink(path[0])
671
+ ndprime, err := insertNodeAtPath(ctx, ds, nd, path[1:], toinsert, create)
672
if err != nil {
673
return nil, err
674
}
675
676
+ _ = root.RemoveNodeLink(path[0])
677
err = root.AddNodeLinkClean(path[0], ndprime)
678
if err != nil {
679
return nil, err
test/sharness/t0051-object.sh
+10
@@ -145,6 +145,16 @@ test_object_cmd() {
145
echo QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn > rmlink_exp &&
146
test_cmp rmlink_exp rmlink_output
147
'
148
+
149
+ test_expect_success "object patch --create works" '
150
+ OUT=$(ipfs object patch --create $EMPTY add-link a/b/c $FILE)
151
+ '
152
+
153
+ test_expect_success "result looks good" '
154
+ ipfs cat $OUT/a/b/c > p2_hwfile &&
155
+ test_cmp hwfile p2_hwfile
156
+ '
157
+
158
}
159
160
# should work offline