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) } diff --git a/core/commands/get.go b/core/commands/get.go index 08e64975b..b4f66680b 100644 --- a/core/commands/get.go +++ b/core/commands/get.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "os" + "path" "strings" cmds "github.com/jbenet/go-ipfs/commands" @@ -76,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 = req.Arguments()[0] + _, outPath = path.Split(req.Arguments()[0]) + outPath = path.Clean(outPath) } cmplvl, err := getCompressOptions(req) @@ -162,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) } 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 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 diff --git a/test/sharness/t0090-get.sh b/test/sharness/t0090-get.sh index 85cde28a7..3de839ead 100755 --- a/test/sharness/t0090-get.sh +++ b/test/sharness/t0090-get.sh @@ -23,58 +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 && - rm $HASH.tar && - rm $HASH + test_cmp "$HASH" data && + rm "$HASH".tar && + 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 ' -# 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 && - 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)" ' @@ -83,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 ' @@ -95,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)" ' @@ -108,15 +106,11 @@ 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 + rm -r "$HASH2" ' test_kill_ipfs_daemon diff --git a/unixfs/tar/reader.go b/unixfs/tar/reader.go index 081d816a2..de4589f94 100644 --- a/unixfs/tar/reader.go +++ b/unixfs/tar/reader.go @@ -5,7 +5,9 @@ import ( "bytes" "compress/gzip" "io" - p "path" + gopath "path" + "strings" + "time" mdag "github.com/jbenet/go-ipfs/merkledag" path "github.com/jbenet/go-ipfs/path" @@ -27,6 +29,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, @@ -51,7 +57,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 := gopath.Split(path) + go reader.writeToBuf(dagnode, filename, 0) return reader, nil } @@ -73,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 { @@ -87,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 } @@ -97,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 {