Commit 6bb02a59 authored by Łukasz Magiera's avatar Łukasz Magiera Committed by Steven Allen

ls: option to report real file size

License: MIT
Signed-off-by: default avatarŁukasz Magiera <magik6k@gmail.com>
parent c8a2078e
...@@ -44,6 +44,7 @@ type LsOutput struct { ...@@ -44,6 +44,7 @@ type LsOutput struct {
const ( const (
lsHeadersOptionNameTime = "headers" lsHeadersOptionNameTime = "headers"
lsResolveTypeOptionName = "resolve-type" lsResolveTypeOptionName = "resolve-type"
lsResolveSizeOptionName = "resolve-size"
lsStreamOptionName = "stream" lsStreamOptionName = "stream"
) )
...@@ -66,6 +67,7 @@ The JSON output contains type information. ...@@ -66,6 +67,7 @@ The JSON output contains type information.
Options: []cmdkit.Option{ Options: []cmdkit.Option{
cmdkit.BoolOption(lsHeadersOptionNameTime, "v", "Print table headers (Hash, Size, Name)."), cmdkit.BoolOption(lsHeadersOptionNameTime, "v", "Print table headers (Hash, Size, Name)."),
cmdkit.BoolOption(lsResolveTypeOptionName, "Resolve linked objects to find out their types.").WithDefault(true), cmdkit.BoolOption(lsResolveTypeOptionName, "Resolve linked objects to find out their types.").WithDefault(true),
cmdkit.BoolOption(lsResolveSizeOptionName, "Resolve linked objects to find out their file size.").WithDefault(false),
cmdkit.BoolOption(lsStreamOptionName, "s", "Enable exprimental streaming of directory entries as they are traversed."), cmdkit.BoolOption(lsStreamOptionName, "s", "Enable exprimental streaming of directory entries as they are traversed."),
}, },
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
...@@ -79,9 +81,10 @@ The JSON output contains type information. ...@@ -79,9 +81,10 @@ The JSON output contains type information.
return err return err
} }
resolve, _ := req.Options[lsResolveTypeOptionName].(bool) resolveType, _ := req.Options[lsResolveTypeOptionName].(bool)
resolveSize, _ := req.Options[lsResolveSizeOptionName].(bool)
dserv := nd.DAG dserv := nd.DAG
if !resolve { if !resolveType && !resolveSize {
offlineexch := offline.Exchange(nd.Blockstore) offlineexch := offline.Exchange(nd.Blockstore)
bserv := blockservice.New(nd.Blockstore, offlineexch) bserv := blockservice.New(nd.Blockstore, offlineexch)
dserv = merkledag.NewDAGService(bserv) dserv = merkledag.NewDAGService(bserv)
...@@ -131,7 +134,7 @@ The JSON output contains type information. ...@@ -131,7 +134,7 @@ The JSON output contains type information.
} }
outputLinks := make([]LsLink, len(links)) outputLinks := make([]LsLink, len(links))
for j, link := range links { for j, link := range links {
lsLink, err := makeLsLink(req, dserv, resolve, link) lsLink, err := makeLsLink(req, dserv, resolveType, resolveSize, link)
if err != nil { if err != nil {
return err return err
} }
...@@ -165,7 +168,7 @@ The JSON output contains type information. ...@@ -165,7 +168,7 @@ The JSON output contains type information.
return linkResult.Err return linkResult.Err
} }
link := linkResult.Link link := linkResult.Link
lsLink, err := makeLsLink(req, dserv, resolve, link) lsLink, err := makeLsLink(req, dserv, resolveType, resolveSize, link)
if err != nil { if err != nil {
return err return err
} }
...@@ -224,8 +227,9 @@ func makeDagNodeLinkResults(req *cmds.Request, dagnode ipld.Node) <-chan unixfs. ...@@ -224,8 +227,9 @@ func makeDagNodeLinkResults(req *cmds.Request, dagnode ipld.Node) <-chan unixfs.
return linkResults return linkResults
} }
func makeLsLink(req *cmds.Request, dserv ipld.DAGService, resolve bool, link *ipld.Link) (*LsLink, error) { func makeLsLink(req *cmds.Request, dserv ipld.DAGService, resolveType bool, resolveSize bool, link *ipld.Link) (*LsLink, error) {
t := unixfspb.Data_DataType(-1) t := unixfspb.Data_DataType(-1)
size := link.Size
switch link.Cid.Type() { switch link.Cid.Type() {
case cid.Raw: case cid.Raw:
...@@ -233,7 +237,7 @@ func makeLsLink(req *cmds.Request, dserv ipld.DAGService, resolve bool, link *ip ...@@ -233,7 +237,7 @@ func makeLsLink(req *cmds.Request, dserv ipld.DAGService, resolve bool, link *ip
t = unixfs.TFile t = unixfs.TFile
case cid.DagProtobuf: case cid.DagProtobuf:
linkNode, err := link.GetNode(req.Context, dserv) linkNode, err := link.GetNode(req.Context, dserv)
if err == ipld.ErrNotFound && !resolve { if err == ipld.ErrNotFound && !resolveType && !resolveSize {
// not an error // not an error
linkNode = nil linkNode = nil
} else if err != nil { } else if err != nil {
...@@ -245,13 +249,18 @@ func makeLsLink(req *cmds.Request, dserv ipld.DAGService, resolve bool, link *ip ...@@ -245,13 +249,18 @@ func makeLsLink(req *cmds.Request, dserv ipld.DAGService, resolve bool, link *ip
if err != nil { if err != nil {
return nil, err return nil, err
} }
t = d.Type() if resolveType {
t = d.Type()
}
if d.Type() == unixfs.TFile && resolveSize {
size = d.FileSize()
}
} }
} }
return &LsLink{ return &LsLink{
Name: link.Name, Name: link.Name,
Hash: link.Cid.String(), Hash: link.Cid.String(),
Size: link.Size, Size: size,
Type: t, Type: t,
}, nil }, nil
} }
......
...@@ -61,6 +61,29 @@ EOF ...@@ -61,6 +61,29 @@ EOF
test_cmp expected_ls actual_ls test_cmp expected_ls actual_ls
' '
test_expect_success "'ipfs ls --resolve-size <three dir hashes>' succeeds" '
ipfs ls --resolve-size QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss >actual_ls
'
test_expect_success "'ipfs ls <three dir hashes>' output looks good" '
cat <<-\EOF >expected_ls &&
QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj:
QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss 246 d1/
QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy 1143 d2/
QmeomffUNfmQy76CQGy9NdmqEnnHU9soCexBnGU3ezPHVH 5 f1
QmNtocSs7MoDkJMc1RkyisCSKvLadujPsfJfSdJ3e1eA1M 5 f2
QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy:
QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd 1024 1024
QmaRGe7bVmVaLmxbrMiVNXqW4pRNNp3xq7hFtyRKA3mtJL 6 a
QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss:
QmQNd6ubRXaNG6Prov8o6vk3bn6eWsj9FxLGrAVDUAGkGe 128 128
QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN 6 a
EOF
test_cmp expected_ls actual_ls
'
test_expect_success "'ipfs ls --headers <three dir hashes>' succeeds" ' test_expect_success "'ipfs ls --headers <three dir hashes>' succeeds" '
ipfs ls --headers QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss >actual_ls_headers ipfs ls --headers QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss >actual_ls_headers
' '
...@@ -140,6 +163,29 @@ EOF ...@@ -140,6 +163,29 @@ EOF
test_cmp expected_ls_stream actual_ls_stream test_cmp expected_ls_stream actual_ls_stream
' '
test_expect_success "'ipfs ls --resolve-size --stream <three dir hashes>' succeeds" '
ipfs ls --resolve-size --stream QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss >actual_ls_stream
'
test_expect_success "'ipfs ls --stream <three dir hashes>' output looks good" '
cat <<-\EOF >expected_ls_stream &&
QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj:
QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss 246 d1/
QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy 1143 d2/
QmeomffUNfmQy76CQGy9NdmqEnnHU9soCexBnGU3ezPHVH 5 f1
QmNtocSs7MoDkJMc1RkyisCSKvLadujPsfJfSdJ3e1eA1M 5 f2
QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy:
QmbQBUSRL9raZtNXfpTDeaxQapibJEG6qEY8WqAN22aUzd 1024 1024
QmaRGe7bVmVaLmxbrMiVNXqW4pRNNp3xq7hFtyRKA3mtJL 6 a
QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss:
QmQNd6ubRXaNG6Prov8o6vk3bn6eWsj9FxLGrAVDUAGkGe 128 128
QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN 6 a
EOF
test_cmp expected_ls_stream actual_ls_stream
'
test_expect_success "'ipfs ls --stream --headers <three dir hashes>' succeeds" ' test_expect_success "'ipfs ls --stream --headers <three dir hashes>' succeeds" '
ipfs ls --stream --headers QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss >actual_ls_stream_headers ipfs ls --stream --headers QmfNy183bXiRVyrhyWtq3TwHn79yHEkiAGFr18P7YNzESj QmR3jhV4XpxxPjPT3Y8vNnWvWNvakdcT3H6vqpRBsX1MLy QmSix55yz8CzWXf5ZVM9vgEvijnEeeXiTSarVtsqiiCJss >actual_ls_stream_headers
' '
...@@ -172,7 +218,7 @@ test_ls_cmd_raw_leaves() { ...@@ -172,7 +218,7 @@ test_ls_cmd_raw_leaves() {
mkdir -p somedir && mkdir -p somedir &&
echo bar > somedir/foo && echo bar > somedir/foo &&
ipfs add --raw-leaves -r somedir/ > /dev/null && ipfs add --raw-leaves -r somedir/ > /dev/null &&
ipfs ls QmThNTdtKaVoCVrYmM5EBS6U3S5vfKFue2TxbxxAxRcKKE > ls-actual ipfs ls '$1' QmThNTdtKaVoCVrYmM5EBS6U3S5vfKFue2TxbxxAxRcKKE > ls-actual
echo "zb2rhf6GzX4ckKZtjy8yy8iyq1KttCrRyqDedD6xubhY3sw2F 4 foo" > ls-expect echo "zb2rhf6GzX4ckKZtjy8yy8iyq1KttCrRyqDedD6xubhY3sw2F 4 foo" > ls-expect
test_cmp ls-actual ls-expect test_cmp ls-actual ls-expect
' '
...@@ -187,12 +233,22 @@ test_ls_object() { ...@@ -187,12 +233,22 @@ test_ls_object() {
ipfs ls $HASH > ls-actual && ipfs ls $HASH > ls-actual &&
test_cmp ls-actual ls-expect test_cmp ls-actual ls-expect
' '
test_expect_success "ipfs add medium size file then 'ipfs ls --resolve-size' works as expected" '
random 500000 2 > somefile &&
HASH=$(ipfs add somefile -q) &&
echo "QmPrM8S5T7Q3M8DQvQMS7m41m3Aq4jBjzAzvky5fH3xfr4 262144 " > ls-expect &&
echo "QmdaAntAzQqqVMo4B8V69nkQd5d918YjHXUe2oF6hr72ri 237856 " >> ls-expect &&
ipfs ls --resolve-size $HASH > ls-actual &&
test_cmp ls-actual ls-expect
'
} }
# should work offline # should work offline
test_ls_cmd test_ls_cmd
test_ls_cmd_streaming test_ls_cmd_streaming
test_ls_cmd_raw_leaves test_ls_cmd_raw_leaves
test_ls_cmd_raw_leaves --resolve-size
test_ls_object test_ls_object
# should work online # should work online
...@@ -200,6 +256,7 @@ test_launch_ipfs_daemon ...@@ -200,6 +256,7 @@ test_launch_ipfs_daemon
test_ls_cmd test_ls_cmd
test_ls_cmd_streaming test_ls_cmd_streaming
test_ls_cmd_raw_leaves test_ls_cmd_raw_leaves
test_ls_cmd_raw_leaves --resolve-size
test_kill_ipfs_daemon test_kill_ipfs_daemon
test_ls_object test_ls_object
...@@ -233,6 +290,10 @@ test_expect_success "'ipfs ls' fails" ' ...@@ -233,6 +290,10 @@ test_expect_success "'ipfs ls' fails" '
test_must_fail ipfs ls $DIR test_must_fail ipfs ls $DIR
' '
test_expect_success "'ipfs ls --resolve-type=false --resolve-size=true' fails" '
test_must_fail ipfs ls --resolve-type=false --resolve-size=true $DIR
'
test_launch_ipfs_daemon --offline test_launch_ipfs_daemon --offline
test_expect_success "'ipfs ls --resolve-type=false' ok" ' test_expect_success "'ipfs ls --resolve-type=false' ok" '
...@@ -243,6 +304,10 @@ test_expect_success "'ipfs ls' fails" ' ...@@ -243,6 +304,10 @@ test_expect_success "'ipfs ls' fails" '
test_must_fail ipfs ls $DIR test_must_fail ipfs ls $DIR
' '
test_expect_success "'ipfs ls --resolve-type=false --resolve-size=true' fails" '
test_must_fail ipfs ls --resolve-type=false --resolve-size=true $DIR
'
test_kill_ipfs_daemon test_kill_ipfs_daemon
test_launch_ipfs_daemon test_launch_ipfs_daemon
......
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