@cryptotaxi247 / kubo / commits / c97c44e8a

Allow mfs files.write command to create parent directories

Adds support for a `-p/--parents` flag to the `files.write` command similar to the one supported by the `files.mkdir` command. If this is true and the directory for the file is not `"/"`, try to create the containing directory before writing to the file. License: MIT Signed-off-by: Alex Potsides <alex@achingbrain.net>

achingbrain committed Aug 9, 2018 at 12:09 UTC c97c44e8a41734dbbc6890a34f892a29458e0f5d
2 files changed +44 -1
core/commands/files.go
+23
@@ -721,6 +721,7 @@ stat' on the file or any of its ancestors.
721 Options: []cmdkit.Option{
722 cmdkit.IntOption("offset", "o", "Byte offset to begin writing at."),
723 cmdkit.BoolOption("create", "e", "Create the file if it does not exist."),
724 + cmdkit.BoolOption("parents", "p", "Make parent directories as needed."),
725 cmdkit.BoolOption("truncate", "t", "Truncate the file to size zero before writing."),
726 cmdkit.IntOption("count", "n", "Maximum number of bytes to read."),
727 cmdkit.BoolOption("raw-leaves", "Use raw blocks for newly created leaf nodes. (experimental)"),
@@ -735,6 +736,7 @@ stat' on the file or any of its ancestors.
736 }
737
738 create, _ := req.Options["create"].(bool)
739 + mkParents, _ := req.Options["parents"].(bool)
740 trunc, _ := req.Options["truncate"].(bool)
741 flush, _ := req.Options["flush"].(bool)
742 rawLeaves, rawLeavesDef := req.Options["raw-leaves"].(bool)
@@ -757,6 +759,14 @@ stat' on the file or any of its ancestors.
759 return
760 }
761
762 + if mkParents {
763 + err := ensureContainingDirectoryExists(nd.FilesRoot, path, prefix)
764 + if err != nil {
765 + re.SetError(err, cmdkit.ErrNormal)
766 + return
767 + }
768 + }
769 +
770 fi, err := getFileHandle(nd.FilesRoot, path, create, prefix)
771 if err != nil {
772 re.SetError(err, cmdkit.ErrNormal)
@@ -1146,6 +1156,19 @@ func getPrefix(req oldcmds.Request) (cid.Builder, error) {
1156 return &prefix, nil
1157 }
1158
1159 +func ensureContainingDirectoryExists(r *mfs.Root, path string, builder cid.Builder) error {
1160 + dirtomake := gopath.Dir(path)
1161 +
1162 + if dirtomake == "/" {
1163 + return nil
1164 + }
1165 +
1166 + return mfs.Mkdir(r, dirtomake, mfs.MkdirOpts{
1167 + Mkparents: true,
1168 + CidBuilder: builder,
1169 + })
1170 +}
1171 +
1172 func getFileHandle(r *mfs.Root, path string, create bool, builder cid.Builder) (*mfs.File, error) {
1173 target, err := mfs.Lookup(r, path)
1174 switch err {
test/sharness/t0250-files-api.sh
+21 -1
@@ -597,9 +597,29 @@ test_files_api() {
597 ipfs files ls /adir | grep foobar
598 '
599
600 + test_expect_success "should fail to write file and create intermediate directories with no --parents flag set $EXTRA" '
601 + echo "ipfs rocks" | test_must_fail ipfs files write --create /parents/foo/ipfs.txt
602 + '
603 +
604 + test_expect_success "can write file and create intermediate directories $EXTRA" '
605 + echo "ipfs rocks" | ipfs files write --create --parents /parents/foo/bar/baz/ipfs.txt &&
606 + ipfs files stat "/parents/foo/bar/baz/ipfs.txt" | grep -q "^Type: file"
607 + '
608 +
609 + test_expect_success "can write file and create intermediate directories with short flags $EXTRA" '
610 + echo "ipfs rocks" | ipfs files write -e -p /parents/foo/bar/baz/qux/quux/garply/ipfs.txt &&
611 + ipfs files stat "/parents/foo/bar/baz/qux/quux/garply/ipfs.txt" | grep -q "^Type: file"
612 + '
613 +
614 + test_expect_success "can write another file in the same directory with -e -p $EXTRA" '
615 + echo "ipfs rocks" | ipfs files write -e -p /parents/foo/bar/baz/qux/quux/garply/ipfs2.txt &&
616 + ipfs files stat "/parents/foo/bar/baz/qux/quux/garply/ipfs2.txt" | grep -q "^Type: file"
617 + '
618 +
619 test_expect_success "clean up $EXTRA" '
620 ipfs files rm -r /foobar &&
602 - ipfs files rm -r /adir
621 + ipfs files rm -r /adir &&
622 + ipfs files rm -r /parents
623 '
624
625 test_expect_success "root mfs entry is empty $EXTRA" '