Skip to content

Commit

Permalink
Allow mfs files.write command to create parent directories
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
achingbrain committed Aug 13, 2018
1 parent 4bca53e commit 5c0c918
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 6 deletions.
34 changes: 29 additions & 5 deletions core/commands/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,19 @@ import (
"sort"
"strings"

oldcmds "github.com/ipfs/go-ipfs/commands"
lgc "github.com/ipfs/go-ipfs/commands/legacy"
core "github.com/ipfs/go-ipfs/core"
e "github.com/ipfs/go-ipfs/core/commands/e"
mfs "github.com/ipfs/go-ipfs/mfs"
bservice "gx/ipfs/QmNqRBAhovtf4jVd5cF7YvHaFSsQHHZBaUFwGQWPM2CV7R/go-blockservice"
dag "gx/ipfs/QmRy4Qk9hbgFX9NGJRm8rBThrA8PZhNCitMgeRYyZ67s59/go-merkledag"
ft "gx/ipfs/QmSaz8Qg77gGqvDvLKeSAY7ivDEnramSWF6T7TcRwFpHtP/go-unixfs"
uio "gx/ipfs/QmSaz8Qg77gGqvDvLKeSAY7ivDEnramSWF6T7TcRwFpHtP/go-unixfs/io"
path "gx/ipfs/QmYKNMEUK7nCVAefgXF1LVtZEZg3uRmBqiae4FJRXDNAyJ/go-path"
resolver "gx/ipfs/QmYKNMEUK7nCVAefgXF1LVtZEZg3uRmBqiae4FJRXDNAyJ/go-path/resolver"

oldcmds "github.com/ipfs/go-ipfs/commands"
lgc "github.com/ipfs/go-ipfs/commands/legacy"
core "github.com/ipfs/go-ipfs/core"
e "github.com/ipfs/go-ipfs/core/commands/e"
mfs "github.com/ipfs/go-ipfs/mfs"

cmds "gx/ipfs/QmNueRyPRQiV7PUEpnP4GgGLuK1rKQLaRW7sfPvUetYig1/go-ipfs-cmds"
humanize "gx/ipfs/QmPSBJL4momYnE7DcUyk2DVhD6rH488ZmHBGLbxNdhU44K/go-humanize"
mh "gx/ipfs/QmPnFwZ2JXKnXgMw8CdBPxn7FWh6LLdjUjxV1fKHuJnkr8/go-multihash"
Expand Down Expand Up @@ -721,6 +722,7 @@ stat' on the file or any of its ancestors.
Options: []cmdkit.Option{
cmdkit.IntOption("offset", "o", "Byte offset to begin writing at."),
cmdkit.BoolOption("create", "e", "Create the file if it does not exist."),
cmdkit.BoolOption("parents", "p", "Make parent directories as needed."),
cmdkit.BoolOption("truncate", "t", "Truncate the file to size zero before writing."),
cmdkit.IntOption("count", "n", "Maximum number of bytes to read."),
cmdkit.BoolOption("raw-leaves", "Use raw blocks for newly created leaf nodes. (experimental)"),
Expand All @@ -735,6 +737,7 @@ stat' on the file or any of its ancestors.
}

create, _ := req.Options["create"].(bool)
mkParents, _ := req.Options["parents"].(bool)
trunc, _ := req.Options["truncate"].(bool)
flush, _ := req.Options["flush"].(bool)
rawLeaves, rawLeavesDef := req.Options["raw-leaves"].(bool)
Expand All @@ -757,6 +760,14 @@ stat' on the file or any of its ancestors.
return
}

if mkParents {
err := ensureContainingDirectoryExists(nd.FilesRoot, path, prefix)
if err != nil {
re.SetError(err, cmdkit.ErrNormal)
return
}
}

fi, err := getFileHandle(nd.FilesRoot, path, create, prefix)
if err != nil {
re.SetError(err, cmdkit.ErrNormal)
Expand Down Expand Up @@ -1146,6 +1157,19 @@ func getPrefix(req oldcmds.Request) (*cid.Prefix, error) {
return &prefix, nil
}

func ensureContainingDirectoryExists(r *mfs.Root, path string, prefix *cid.Prefix) error {
dirtomake := gopath.Dir(path)

if dirtomake == "/" {
return nil
}

return mfs.Mkdir(r, dirtomake, mfs.MkdirOpts{
Mkparents: true,
Prefix: prefix,
})
}

func getFileHandle(r *mfs.Root, path string, create bool, prefix *cid.Prefix) (*mfs.File, error) {
target, err := mfs.Lookup(r, path)
switch err {
Expand Down
17 changes: 16 additions & 1 deletion test/sharness/t0250-files-api.sh
Original file line number Diff line number Diff line change
Expand Up @@ -597,9 +597,24 @@ test_files_api() {
ipfs files ls /adir | grep foobar
'

test_expect_failure "should fail to write file and create intermediate directories with no --parents flag set $EXTRA" '
echo "ipfs rocks" | ipfs files write --create /parents/foo/ipfs.txt
'

test_expect_success "can write file and create intermediate directories $EXTRA" '
echo "ipfs rocks" | ipfs files write --create --parents /parents/foo/bar/baz/ipfs.txt &&
ipfs files stat "/parents/foo/bar/baz/ipfs.txt" | grep -q "^Type: file"
'

test_expect_success "can write file and create intermediate directories with short flags $EXTRA" '
echo "ipfs rocks" | ipfs files write -e -p /parents/foo/bar/baz/qux/quux/garply/ipfs.txt &&
ipfs files stat "/parents/foo/bar/baz/qux/quux/garply/ipfs.txt" | grep -q "^Type: file"
'

test_expect_success "clean up $EXTRA" '
ipfs files rm -r /foobar &&
ipfs files rm -r /adir
ipfs files rm -r /adir &&
ipfs files rm -r /parents
'

test_expect_success "root mfs entry is empty $EXTRA" '
Expand Down

0 comments on commit 5c0c918

Please sign in to comment.