Commit d0583768 authored by Juan Batiz-Benet's avatar Juan Batiz-Benet

Merge pull request #709 from jbenet/wrap

ipfs add -w
parents ecfae897 48885377
......@@ -10,6 +10,7 @@ import (
cmds "github.com/jbenet/go-ipfs/commands"
files "github.com/jbenet/go-ipfs/commands/files"
core "github.com/jbenet/go-ipfs/core"
coreunix "github.com/jbenet/go-ipfs/core/coreunix"
importer "github.com/jbenet/go-ipfs/importer"
"github.com/jbenet/go-ipfs/importer/chunk"
dag "github.com/jbenet/go-ipfs/merkledag"
......@@ -26,7 +27,10 @@ var ErrDepthLimitExceeded = fmt.Errorf("depth limit exceeded")
// how many bytes of progress to wait before sending a progress update message
const progressReaderIncrement = 1024 * 256
const progressOptionName = "progress"
const (
progressOptionName = "progress"
wrapOptionName = "wrap-with-directory"
)
type AddedObject struct {
Name string
......@@ -52,6 +56,7 @@ remains to be implemented.
cmds.OptionRecursivePath, // a builtin option that allows recursive paths (-r, --recursive)
cmds.BoolOption("quiet", "q", "Write minimal output"),
cmds.BoolOption(progressOptionName, "p", "Stream progress data"),
cmds.BoolOption(wrapOptionName, "w", "Wrap files with a directory object"),
},
PreRun: func(req cmds.Request) error {
if quiet, _, _ := req.Option("quiet").Bool(); quiet {
......@@ -84,6 +89,7 @@ remains to be implemented.
}
progress, _, _ := req.Option(progressOptionName).Bool()
wrap, _, _ := req.Option(wrapOptionName).Bool()
outChan := make(chan interface{})
res.SetOutput((<-chan interface{})(outChan))
......@@ -97,7 +103,7 @@ remains to be implemented.
return
}
_, err = addFile(n, file, outChan, progress)
_, err = addFile(n, file, outChan, progress, wrap)
if err != nil {
return
}
......@@ -225,7 +231,7 @@ func addNode(n *core.IpfsNode, node *dag.Node) error {
return nil
}
func addFile(n *core.IpfsNode, file files.File, out chan interface{}, progress bool) (*dag.Node, error) {
func addFile(n *core.IpfsNode, file files.File, out chan interface{}, progress bool, wrap bool) (*dag.Node, error) {
if file.IsDirectory() {
return addDir(n, file, out, progress)
}
......@@ -237,6 +243,18 @@ func addFile(n *core.IpfsNode, file files.File, out chan interface{}, progress b
reader = &progressReader{file: file, out: out}
}
if wrap {
p, dagnode, err := coreunix.AddWrapped(n, reader, path.Base(file.FileName()))
if err != nil {
return nil, err
}
out <- &AddedObject{
Hash: p,
Name: file.FileName(),
}
return dagnode, nil
}
dns, err := add(n, []io.Reader{reader})
if err != nil {
return nil, err
......@@ -263,7 +281,7 @@ func addDir(n *core.IpfsNode, dir files.File, out chan interface{}, progress boo
break
}
node, err := addFile(n, file, out, progress)
node, err := addFile(n, file, out, progress, false)
if err != nil {
return nil, err
}
......
......@@ -3,6 +3,7 @@ package coreunix
import (
"errors"
"io"
"io/ioutil"
"os"
gopath "path"
......@@ -64,6 +65,24 @@ func AddR(n *core.IpfsNode, root string) (key string, err error) {
return k.String(), nil
}
// AddWrapped adds data from a reader, and wraps it with a directory object
// to preserve the filename.
// Returns the path of the added file ("<dir hash>/filename"), the DAG node of
// the directory, and and error if any.
func AddWrapped(n *core.IpfsNode, r io.Reader, filename string) (string, *merkledag.Node, error) {
file := files.NewReaderFile(filename, ioutil.NopCloser(r), nil)
dir := files.NewSliceFile("", []files.File{file})
dagnode, err := addDir(n, dir)
if err != nil {
return "", nil, err
}
k, err := dagnode.Key()
if err != nil {
return "", nil, err
}
return gopath.Join(k.String(), filename), dagnode, nil
}
func add(n *core.IpfsNode, readers []io.Reader) ([]*merkledag.Node, error) {
mp, ok := n.Pinning.(pin.ManualPinner)
if !ok {
......
......@@ -165,6 +165,16 @@ test_expect_success FUSE,EXPENSIVE "cat ipfs/bigfile looks good" '
test_cmp sha1_expected sha1_actual
'
test_expect_success "ipfs add -w succeeds" '
ipfs add -w mountdir/hello.txt >actual
'
test_expect_success "ipfs add -w output looks good" '
HASH="QmVJfrqd4ogGZME6LWkkikAGddYgh9dBs2U14DHZZUBk7W" &&
echo "added $HASH/hello.txt mountdir/hello.txt" >expected &&
test_cmp expected actual
'
test_kill_ipfs_daemon
test_done
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment