Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

beautify 'ipfs ls' and 'ipfs object links' #833

Merged
merged 4 commits into from Mar 1, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
45 changes: 32 additions & 13 deletions core/commands/ls.go
@@ -1,18 +1,22 @@
package commands

import (
"bytes"
"fmt"
"io"
"strings"
"text/tabwriter"

cmds "github.com/jbenet/go-ipfs/commands"
merkledag "github.com/jbenet/go-ipfs/merkledag"
path "github.com/jbenet/go-ipfs/path"
"github.com/jbenet/go-ipfs/unixfs"
unixfspb "github.com/jbenet/go-ipfs/unixfs/pb"
)

type Link struct {
Name, Hash string
Size uint64
IsDir bool
}

type Object struct {
Expand Down Expand Up @@ -64,10 +68,21 @@ it contains, with the following format:
Links: make([]Link, len(dagnode.Links)),
}
for j, link := range dagnode.Links {
link.Node, err = link.GetNode(node.DAG)
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
d, err := unixfs.FromBytes(link.Node.Data)
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
output[i].Links[j] = Link{
Name: link.Name,
Hash: link.Hash.B58String(),
Size: link.Size,
Name: link.Name,
Hash: link.Hash.B58String(),
Size: link.Size,
IsDir: d.GetType() == unixfspb.Data_Directory,
}
}
}
Expand All @@ -76,28 +91,32 @@ it contains, with the following format:
},
Marshalers: cmds.MarshalerMap{
cmds.Text: func(res cmds.Response) (io.Reader, error) {
s := ""
output := res.Output().(*LsOutput).Objects

var buf bytes.Buffer
w := tabwriter.NewWriter(&buf, 1, 2, 1, ' ', 0)
for _, object := range output {
if len(output) > 1 {
s += fmt.Sprintf("%s:\n", object.Hash)
fmt.Fprintf(w, "%s:\n", object.Hash)
}
s += marshalLinks(object.Links)
marshalLinks(w, object.Links)
if len(output) > 1 {
s += "\n"
fmt.Fprintln(w)
}
}
w.Flush()

return strings.NewReader(s), nil
return &buf, nil
},
},
Type: LsOutput{},
}

func marshalLinks(links []Link) (s string) {
func marshalLinks(w io.Writer, links []Link) {
fmt.Fprintln(w, "Hash\tSize\tName\t")
for _, link := range links {
s += fmt.Sprintf("%s %v %s\n", link.Hash, link.Size, link.Name)
if link.IsDir {
link.Name += "/"
}
fmt.Fprintf(w, "%s\t%v\t%s\t\n", link.Hash, link.Size, link.Name)
}
return s
}
10 changes: 7 additions & 3 deletions core/commands/object.go
Expand Up @@ -8,6 +8,7 @@ import (
"io"
"io/ioutil"
"strings"
"text/tabwriter"

mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"

Expand Down Expand Up @@ -120,8 +121,11 @@ multihash.
Marshalers: cmds.MarshalerMap{
cmds.Text: func(res cmds.Response) (io.Reader, error) {
object := res.Output().(*Object)
marshalled := marshalLinks(object.Links)
return strings.NewReader(marshalled), nil
var buf bytes.Buffer
w := tabwriter.NewWriter(&buf, 1, 2, 1, ' ', 0)
marshalLinks(w, object.Links)
w.Flush()
return &buf, nil
},
},
Type: Object{},
Expand Down Expand Up @@ -246,7 +250,7 @@ var objectStatCmd = &cmds.Command{

var buf bytes.Buffer
w := func(s string, n int) {
buf.Write([]byte(fmt.Sprintf("%s: %d\n", s, n)))
fmt.Fprintf(&buf, "%s: %d\n", s, n)
}
w("NumLinks", ns.NumLinks)
w("BlockSize", ns.BlockSize)
Expand Down
66 changes: 66 additions & 0 deletions test/sharness/t0045-ls.sh
@@ -0,0 +1,66 @@
#!/bin/sh
#
# Copyright (c) 2014 Christian Couder
# MIT Licensed; see the LICENSE file in this repository.
#

test_description="Test ls command"

. lib/test-lib.sh

test_init_ipfs

test_expect_success "'ipfs add -r testData' succeeds" '
mkdir testData testData/d1 testData/d2 && \
echo "test" > testData/f1 && \
echo "data" > testData/f2 && \
echo "hello" > testData/d1/a && \
random 128 42 > testData/d1/128 && \
echo "world" > testData/d2/a && \
random 1024 42 > testData/d2/1024 && \
ipfs add -r testData > actual_add
'

test_expect_success "'ipfs add' output looks good" '
cat << EOF > expected_add
added QmQNd6ubRXaNG6Prov8o6vk3bn6eWsj9FxLGrAVDUAGkGe testData/d1/128
added QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN testData/d1/a
added QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss testData/d1
added QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd testData/d2/1024
added QmaRGe7bVmVaLmxbrMiVNXqW4pRNNp3xq7hFtyRKA3mtJL testData/d2/a
added QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy testData/d2
added QmeomffUNfmQy76CQGy9NdmqEnnHU9soCexBnGU3ezPHVH testData/f1
added QmNtocSs7MoDkJMc1RkyisCSKvLadujPsfJfSdJ3e1eA1M testData/f2
added QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj testData
EOF
test $(diff actual_add expected_add | wc -l) -eq 0
'

test_expect_success "'ipfs ls <three dir hashes>' succeeds" '
ipfs ls QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss > actual_ls
'

test_expect_success "'ipfs ls <three dir hashes>' output looks good" '
cat << EOF > expected_ls
QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj:
Hash Size Name
QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss 246 d1/
QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy 1143 d2/
QmeomffUNfmQy76CQGy9NdmqEnnHU9soCexBnGU3ezPHVH 13 f1
QmNtocSs7MoDkJMc1RkyisCSKvLadujPsfJfSdJ3e1eA1M 13 f2

QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy:
Hash Size Name
QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd 1035 1024
QmaRGe7bVmVaLmxbrMiVNXqW4pRNNp3xq7hFtyRKA3mtJL 14 a

QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss:
Hash Size Name
QmQNd6ubRXaNG6Prov8o6vk3bn6eWsj9FxLGrAVDUAGkGe 139 128
QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN 14 a

EOF
test $(diff actual_ls expected_ls | wc -l) -eq 0
'

test_done