Skip to content

Commit e756c7d

Browse files
committed
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 <[email protected]>
1 parent 4bca53e commit e756c7d

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

core/commands/files.go

+24
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,7 @@ stat' on the file or any of its ancestors.
721721
Options: []cmdkit.Option{
722722
cmdkit.IntOption("offset", "o", "Byte offset to begin writing at."),
723723
cmdkit.BoolOption("create", "e", "Create the file if it does not exist."),
724+
cmdkit.BoolOption("parents", "p", "Make parent directories as needed."),
724725
cmdkit.BoolOption("truncate", "t", "Truncate the file to size zero before writing."),
725726
cmdkit.IntOption("count", "n", "Maximum number of bytes to read."),
726727
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.
735736
}
736737

737738
create, _ := req.Options["create"].(bool)
739+
mkParents, _ := req.Options["parents"].(bool)
738740
trunc, _ := req.Options["truncate"].(bool)
739741
flush, _ := req.Options["flush"].(bool)
740742
rawLeaves, rawLeavesDef := req.Options["raw-leaves"].(bool)
@@ -757,6 +759,14 @@ stat' on the file or any of its ancestors.
757759
return
758760
}
759761

762+
if mkParents {
763+
err := ensureContainingDirectoryExists(nd.FilesRoot, path, flush, prefix)
764+
if err != nil {
765+
re.SetError(err, cmdkit.ErrNormal)
766+
return
767+
}
768+
}
769+
760770
fi, err := getFileHandle(nd.FilesRoot, path, create, prefix)
761771
if err != nil {
762772
re.SetError(err, cmdkit.ErrNormal)
@@ -1146,6 +1156,20 @@ func getPrefix(req oldcmds.Request) (*cid.Prefix, error) {
11461156
return &prefix, nil
11471157
}
11481158

1159+
func ensureContainingDirectoryExists(r *mfs.Root, path string, flush bool, prefix *cid.Prefix) 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+
Flush: flush,
1169+
Prefix: prefix,
1170+
})
1171+
}
1172+
11491173
func getFileHandle(r *mfs.Root, path string, create bool, prefix *cid.Prefix) (*mfs.File, error) {
11501174
target, err := mfs.Lookup(r, path)
11511175
switch err {

test/sharness/t0250-files-api.sh

+16-1
Original file line numberDiff line numberDiff line change
@@ -597,9 +597,24 @@ test_files_api() {
597597
ipfs files ls /adir | grep foobar
598598
'
599599

600+
test_expect_failure "should fail to write file and create intermediate directories with no --parents flag set $EXTRA" '
601+
echo "ipfs rocks" | 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+
600614
test_expect_success "clean up $EXTRA" '
601615
ipfs files rm -r /foobar &&
602-
ipfs files rm -r /adir
616+
ipfs files rm -r /adir &&
617+
ipfs files rm -r /parents
603618
'
604619

605620
test_expect_success "root mfs entry is empty $EXTRA" '

0 commit comments

Comments
 (0)