From e6d6e9fed61357ffa3660f2d4318a507ed84b7ee Mon Sep 17 00:00:00 2001 From: Matt Bell Date: Sat, 24 Jan 2015 13:18:03 -0800 Subject: [PATCH 01/10] core/commands: Added 'get' to root command helptext --- core/commands/root.go | 1 + 1 file changed, 1 insertion(+) diff --git a/core/commands/root.go b/core/commands/root.go index 15781c52c..e0cd8481d 100644 --- a/core/commands/root.go +++ b/core/commands/root.go @@ -27,6 +27,7 @@ Basic commands: init Initialize ipfs local configuration add Add an object to ipfs cat Show ipfs object data + get Download ipfs objects ls List links from an object refs List hashes of links from an object From 41d5c822d70f5748e70ff78fabfd3f2d50d02273 Mon Sep 17 00:00:00 2001 From: Matt Bell Date: Sat, 24 Jan 2015 13:46:08 -0800 Subject: [PATCH 02/10] core/commands: get: Place files at root of TAR when using a multi-element ipfs path --- core/commands/get.go | 3 ++- unixfs/tar/reader.go | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/core/commands/get.go b/core/commands/get.go index 08e64975b..9aca5750f 100644 --- a/core/commands/get.go +++ b/core/commands/get.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "os" + p "path" "strings" cmds "github.com/jbenet/go-ipfs/commands" @@ -76,7 +77,7 @@ may also specify the level of compression by specifying '-l=<1-9>'. outPath, _, _ := req.Option("output").String() if len(outPath) == 0 { - outPath = req.Arguments()[0] + _, outPath = p.Split(req.Arguments()[0]) } cmplvl, err := getCompressOptions(req) diff --git a/unixfs/tar/reader.go b/unixfs/tar/reader.go index 081d816a2..6ec333928 100644 --- a/unixfs/tar/reader.go +++ b/unixfs/tar/reader.go @@ -51,7 +51,8 @@ func NewReader(path string, dag mdag.DAGService, resolver *path.Resolver, compre // writeToBuf will write the data to the buffer, and will signal when there // is new data to read - go reader.writeToBuf(dagnode, path, 0) + _, filename := p.Split(path) + go reader.writeToBuf(dagnode, filename, 0) return reader, nil } From 23f810e187416262b158eebfc8a3817a973b5d34 Mon Sep 17 00:00:00 2001 From: Matt Bell Date: Sat, 24 Jan 2015 14:28:07 -0800 Subject: [PATCH 03/10] test/sharness: Fixed get gzip archive test --- test/sharness/t0090-get.sh | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/test/sharness/t0090-get.sh b/test/sharness/t0090-get.sh index 85cde28a7..450109ff9 100755 --- a/test/sharness/t0090-get.sh +++ b/test/sharness/t0090-get.sh @@ -54,7 +54,7 @@ test_expect_success "ipfs get -a output looks good" ' test_expect_success "ipfs get -a archive output is valid" ' tar -xf "$HASH".tar && test_cmp $HASH data && - rm $HASH.tar && + rm "$HASH".tar && rm $HASH ' @@ -68,10 +68,8 @@ test_expect_success "ipfs get -a -C output looks good" ' test_cmp expected actual ' -# TODO(mappum): fix this test. On osx I get: -# tar: Error opening archive: (Empty error message) test_expect_failure "gzipped tar archive output is valid" ' - tar -xf "$HASH".tar.gz && + tar -zxf $HASH.tar.gz && test_cmp $HASH data && rm "$HASH".tar.gz && rm $HASH @@ -108,12 +106,8 @@ test_expect_success "ipfs get -a -C output looks good (directory)" ' test_cmp expected actual ' -# TODO(mappum): fix this test. failing on travis: -# gzip: stdin: unexpected end of file -# tar: Child returned status 1 -# tar: Error is not recoverable: exiting now -test_expect_failure "gzipped tar archive output is valid (directory)" ' - tar -xf "$HASH2".tar.gz && +test_expect_success "gzipped tar archive output is valid (directory)" ' + tar -zxf "$HASH2".tar.gz && test_cmp dir/a "$HASH2"/a && test_cmp dir/b/c "$HASH2"/b/c && rm -r $HASH2 From 2f2efc8463b89bea50b5435dca5d9a3399974f54 Mon Sep 17 00:00:00 2001 From: Matt Bell Date: Sat, 24 Jan 2015 14:52:41 -0800 Subject: [PATCH 04/10] cmd/ipfs: On command ClientError, suggest checking helptext instead of showing short helptext. Resovles #630 --- cmd/ipfs/main.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/cmd/ipfs/main.go b/cmd/ipfs/main.go index f3169b590..5a057a52f 100644 --- a/cmd/ipfs/main.go +++ b/cmd/ipfs/main.go @@ -9,6 +9,7 @@ import ( "os/signal" "runtime" "runtime/pprof" + "strings" "syscall" "time" @@ -78,6 +79,12 @@ func main() { helpFunc("ipfs", Root, invoc.path, w) } + // this is a message to tell the user how to get the help text + printMetaHelp := func(w io.Writer) { + cmdPath := strings.Join(invoc.path, " ") + fmt.Fprintf(w, "Use 'ipfs %s --help' for information about this command\n", cmdPath) + } + // parse the commandline into a command invocation parseErr := invoc.Parse(ctx, os.Args[1:]) @@ -112,7 +119,7 @@ func main() { if invoc.cmd != nil { // we need a newline space. fmt.Fprintf(os.Stderr, "\n") - printHelp(false, os.Stderr) + printMetaHelp(os.Stderr) } os.Exit(1) } @@ -124,7 +131,7 @@ func main() { // if this error was a client error, print short help too. if isClientError(err) { - printHelp(false, os.Stderr) + printMetaHelp(os.Stderr) } os.Exit(1) } From 6c854ce897922e6aacc336d4370ac3f9ca853578 Mon Sep 17 00:00:00 2001 From: Matt Bell Date: Sat, 24 Jan 2015 15:04:54 -0800 Subject: [PATCH 05/10] unixfs/tar: Ignore /ipfs/ in path --- unixfs/tar/reader.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/unixfs/tar/reader.go b/unixfs/tar/reader.go index 6ec333928..a64a963eb 100644 --- a/unixfs/tar/reader.go +++ b/unixfs/tar/reader.go @@ -6,6 +6,7 @@ import ( "compress/gzip" "io" p "path" + "strings" mdag "github.com/jbenet/go-ipfs/merkledag" path "github.com/jbenet/go-ipfs/path" @@ -27,6 +28,10 @@ type Reader struct { } func NewReader(path string, dag mdag.DAGService, resolver *path.Resolver, compression int) (*Reader, error) { + if strings.HasPrefix(path, "/ipfs/") { + path = path[6:] + } + reader := &Reader{ signalChan: make(chan struct{}), dag: dag, From 3799ad9023d87284d26958a8582f34d27ed00e2e Mon Sep 17 00:00:00 2001 From: Matt Bell Date: Mon, 26 Jan 2015 14:24:33 -0800 Subject: [PATCH 06/10] core/commands: log tail: Return from goroutine when request context closes, resolves #659 --- core/commands/log.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/core/commands/log.go b/core/commands/log.go index 34e33730e..3e27899de 100644 --- a/core/commands/log.go +++ b/core/commands/log.go @@ -99,7 +99,16 @@ var logTailCmd = &cmds.Command{ } defer t.Stop() + done := req.Context().Context.Done() + for line := range t.Lines { + // return when context closes + select { + case <-done: + return + default: + } + if line.Err != nil { fmt.Println(err.Error()) return From 5a60b7b2e70349bf87aa8c797d25f9db11f14193 Mon Sep 17 00:00:00 2001 From: Matt Bell Date: Mon, 26 Jan 2015 16:57:55 -0800 Subject: [PATCH 07/10] unixfs/tar: Use current date for file timestamps --- unixfs/tar/reader.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/unixfs/tar/reader.go b/unixfs/tar/reader.go index a64a963eb..193f50333 100644 --- a/unixfs/tar/reader.go +++ b/unixfs/tar/reader.go @@ -7,6 +7,7 @@ import ( "io" p "path" "strings" + "time" mdag "github.com/jbenet/go-ipfs/merkledag" path "github.com/jbenet/go-ipfs/path" @@ -79,6 +80,7 @@ func (i *Reader) writeToBuf(dagnode *mdag.Node, path string, depth int) { Name: path, Typeflag: tar.TypeDir, Mode: 0777, + ModTime: time.Now(), // TODO: set mode, dates, etc. when added to unixFS }) if err != nil { @@ -103,6 +105,7 @@ func (i *Reader) writeToBuf(dagnode *mdag.Node, path string, depth int) { Size: int64(pb.GetFilesize()), Typeflag: tar.TypeReg, Mode: 0644, + ModTime: time.Now(), // TODO: set mode, dates, etc. when added to unixFS }) if err != nil { From 45ed27e27333c22dbca0cead5cdeffc92d52f6a8 Mon Sep 17 00:00:00 2001 From: Matt Bell Date: Mon, 26 Jan 2015 17:00:40 -0800 Subject: [PATCH 08/10] test/sharness: get: Quote variables --- test/sharness/t0090-get.sh | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/test/sharness/t0090-get.sh b/test/sharness/t0090-get.sh index 450109ff9..3de839ead 100755 --- a/test/sharness/t0090-get.sh +++ b/test/sharness/t0090-get.sh @@ -23,56 +23,56 @@ test_expect_success "'ipfs get --help' output looks good" ' test_expect_success "ipfs get succeeds" ' echo "Hello Worlds!" > data && HASH=`ipfs add -q data` && - ipfs get $HASH > actual + ipfs get "$HASH" > actual ' test_expect_success "ipfs get output looks good" ' - echo "Saving file(s) to $HASH + echo "Saving file(s) to "$HASH" " > expected && test_cmp expected actual ' test_expect_success "ipfs get file output looks good" ' - test_cmp $HASH data + test_cmp "$HASH" data ' test_expect_success "ipfs get errors when trying to overwrite a file" ' - test_must_fail ipfs get $HASH > actual && - rm $HASH + test_must_fail ipfs get "$HASH" > actual && + rm "$HASH" ' test_expect_success "ipfs get -a succeeds" ' - ipfs get $HASH -a > actual + ipfs get "$HASH" -a > actual ' test_expect_success "ipfs get -a output looks good" ' - echo "Saving archive to $HASH.tar + echo "Saving archive to "$HASH".tar " > expected && test_cmp expected actual ' test_expect_success "ipfs get -a archive output is valid" ' tar -xf "$HASH".tar && - test_cmp $HASH data && + test_cmp "$HASH" data && rm "$HASH".tar && - rm $HASH + rm "$HASH" ' test_expect_success "ipfs get -a -C succeeds" ' - ipfs get $HASH -a -C > actual + ipfs get "$HASH" -a -C > actual ' test_expect_success "ipfs get -a -C output looks good" ' - echo "Saving archive to $HASH.tar.gz + echo "Saving archive to "$HASH".tar.gz " > expected && test_cmp expected actual ' test_expect_failure "gzipped tar archive output is valid" ' - tar -zxf $HASH.tar.gz && - test_cmp $HASH data && + tar -zxf "$HASH".tar.gz && + test_cmp "$HASH" data && rm "$HASH".tar.gz && - rm $HASH + rm "$HASH" ' test_expect_success "ipfs get succeeds (directory)" ' @@ -81,11 +81,11 @@ test_expect_success "ipfs get succeeds (directory)" ' mkdir dir/b && echo "Hello, Worlds!" > dir/b/c && HASH2=`ipfs add -r -q dir | tail -n 1` && - ipfs get $HASH2 > actual + ipfs get "$HASH2" > actual ' test_expect_success "ipfs get output looks good (directory)" ' - echo "Saving file(s) to $HASH2 + echo "Saving file(s) to "$HASH2" " > expected && test_cmp expected actual ' @@ -93,11 +93,11 @@ test_expect_success "ipfs get output looks good (directory)" ' test_expect_success "ipfs get output is valid (directory)" ' test_cmp dir/a "$HASH2"/a && test_cmp dir/b/c "$HASH2"/b/c && - rm -r $HASH2 + rm -r "$HASH2" ' test_expect_success "ipfs get -a -C succeeds (directory)" ' - ipfs get $HASH2 -a -C > actual + ipfs get "$HASH2" -a -C > actual ' test_expect_success "ipfs get -a -C output looks good (directory)" ' @@ -110,7 +110,7 @@ test_expect_success "gzipped tar archive output is valid (directory)" ' tar -zxf "$HASH2".tar.gz && test_cmp dir/a "$HASH2"/a && test_cmp dir/b/c "$HASH2"/b/c && - rm -r $HASH2 + rm -r "$HASH2" ' test_kill_ipfs_daemon From 5292617290446095800f7ff4bc8fae4d0d70d378 Mon Sep 17 00:00:00 2001 From: Matt Bell Date: Mon, 26 Jan 2015 17:02:48 -0800 Subject: [PATCH 09/10] unixfs/tar: Rename p to gopath --- unixfs/tar/reader.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/unixfs/tar/reader.go b/unixfs/tar/reader.go index 193f50333..de4589f94 100644 --- a/unixfs/tar/reader.go +++ b/unixfs/tar/reader.go @@ -5,7 +5,7 @@ import ( "bytes" "compress/gzip" "io" - p "path" + gopath "path" "strings" "time" @@ -57,7 +57,7 @@ func NewReader(path string, dag mdag.DAGService, resolver *path.Resolver, compre // writeToBuf will write the data to the buffer, and will signal when there // is new data to read - _, filename := p.Split(path) + _, filename := gopath.Split(path) go reader.writeToBuf(dagnode, filename, 0) return reader, nil @@ -95,7 +95,7 @@ func (i *Reader) writeToBuf(dagnode *mdag.Node, path string, depth int) { i.emitError(err) return } - i.writeToBuf(childNode, p.Join(path, link.Name), depth+1) + i.writeToBuf(childNode, gopath.Join(path, link.Name), depth+1) } return } From d666155a0a61f9614247ccb79b8095db7a17adba Mon Sep 17 00:00:00 2001 From: Matt Bell Date: Mon, 26 Jan 2015 17:07:30 -0800 Subject: [PATCH 10/10] core/commands: get: Clean output path --- core/commands/get.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/core/commands/get.go b/core/commands/get.go index 9aca5750f..b4f66680b 100644 --- a/core/commands/get.go +++ b/core/commands/get.go @@ -6,7 +6,7 @@ import ( "fmt" "io" "os" - p "path" + "path" "strings" cmds "github.com/jbenet/go-ipfs/commands" @@ -77,7 +77,8 @@ may also specify the level of compression by specifying '-l=<1-9>'. outPath, _, _ := req.Option("output").String() if len(outPath) == 0 { - _, outPath = p.Split(req.Arguments()[0]) + _, outPath = path.Split(req.Arguments()[0]) + outPath = path.Clean(outPath) } cmplvl, err := getCompressOptions(req) @@ -163,6 +164,6 @@ func getCompressOptions(req cmds.Request) (int, error) { return gzip.NoCompression, nil } -func get(node *core.IpfsNode, path string, compression int) (io.Reader, error) { - return utar.NewReader(path, node.DAG, node.Resolver, compression) +func get(node *core.IpfsNode, p string, compression int) (io.Reader, error) { + return utar.NewReader(p, node.DAG, node.Resolver, compression) }