Commit 6f716463 authored by Jeromy Johnson's avatar Jeromy Johnson

Merge pull request #2706 from ipfs/feature/MFSStatsHashOnly

Add --format option to mfs stat command
parents 2482dc8f fea0b940
...@@ -53,6 +53,8 @@ on the files in question, then data may be lost. This also applies to running ...@@ -53,6 +53,8 @@ on the files in question, then data may be lost. This also applies to running
}, },
} }
var formatError = errors.New("Format was set by multiple options. Only one format option is allowed")
var FilesStatCmd = &cmds.Command{ var FilesStatCmd = &cmds.Command{
Helptext: cmds.HelpText{ Helptext: cmds.HelpText{
Tagline: "Display file status.", Tagline: "Display file status.",
...@@ -61,7 +63,24 @@ var FilesStatCmd = &cmds.Command{ ...@@ -61,7 +63,24 @@ var FilesStatCmd = &cmds.Command{
Arguments: []cmds.Argument{ Arguments: []cmds.Argument{
cmds.StringArg("path", true, false, "Path to node to stat."), cmds.StringArg("path", true, false, "Path to node to stat."),
}, },
Options: []cmds.Option{
cmds.StringOption("format", "Print statistics in given format. Allowed tokens: "+
"<hash> <size> <cumulsize> <type> <childs>. Conflicts with other format options.").Default(
`<hash>
Size: <size>
CumulativeSize: <cumulsize>
ChildBlocks: <childs>
Type: <type>`),
cmds.BoolOption("hash", "Print only hash. Implies '--format=<hash>. Conflicts with other format options.").Default(false),
cmds.BoolOption("size", "Print only size. Implies '--format=<cumulsize>. Conflicts with other format options.").Default(false),
},
Run: func(req cmds.Request, res cmds.Response) { Run: func(req cmds.Request, res cmds.Response) {
_, err := statGetFormatOptions(req)
if err != nil {
res.SetError(err, cmds.ErrClient)
}
node, err := req.InvocContext().GetNode() node, err := req.InvocContext().GetNode()
if err != nil { if err != nil {
res.SetError(err, cmds.ErrNormal) res.SetError(err, cmds.ErrNormal)
...@@ -90,19 +109,47 @@ var FilesStatCmd = &cmds.Command{ ...@@ -90,19 +109,47 @@ var FilesStatCmd = &cmds.Command{
}, },
Marshalers: cmds.MarshalerMap{ Marshalers: cmds.MarshalerMap{
cmds.Text: func(res cmds.Response) (io.Reader, error) { cmds.Text: func(res cmds.Response) (io.Reader, error) {
out := res.Output().(*Object) out := res.Output().(*Object)
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
fmt.Fprintln(buf, out.Hash)
fmt.Fprintf(buf, "Size: %d\n", out.Size) s, _ := statGetFormatOptions(res.Request())
fmt.Fprintf(buf, "CumulativeSize: %d\n", out.CumulativeSize) s = strings.Replace(s, "<hash>", out.Hash, -1)
fmt.Fprintf(buf, "ChildBlocks: %d\n", out.Blocks) s = strings.Replace(s, "<size>", fmt.Sprintf("%d", out.Size), -1)
fmt.Fprintf(buf, "Type: %s\n", out.Type) s = strings.Replace(s, "<cumulsize>", fmt.Sprintf("%d", out.CumulativeSize), -1)
s = strings.Replace(s, "<childs>", fmt.Sprintf("%d", out.Blocks), -1)
s = strings.Replace(s, "<type>", out.Type, -1)
fmt.Fprintln(buf, s)
return buf, nil return buf, nil
}, },
}, },
Type: Object{}, Type: Object{},
} }
func moreThanOne(a, b, c bool) bool {
return a && b || b && c || a && c
}
func statGetFormatOptions(req cmds.Request) (string, error) {
hash, _, _ := req.Option("hash").Bool()
size, _, _ := req.Option("size").Bool()
format, found, _ := req.Option("format").String()
if moreThanOne(hash, size, found) {
return "", formatError
}
if hash {
return "<hash>", nil
} else if size {
return "<cumulsize>", nil
} else {
return format, nil
}
}
func statNode(ds dag.DAGService, fsn mfs.FSNode) (*Object, error) { func statNode(ds dag.DAGService, fsn mfs.FSNode) (*Object, error) {
nd, err := fsn.GetNode() nd, err := fsn.GetNode()
if err != nil { if err != nil {
......
...@@ -64,9 +64,39 @@ test_files_api() { ...@@ -64,9 +64,39 @@ test_files_api() {
test_expect_success "directory is empty" ' test_expect_success "directory is empty" '
verify_dir_contents /cats verify_dir_contents /cats
' '
# we do verification of stat formatting now as we depend on it
test_expect_success "stat works" '
ipfs files stat / >stat
'
test_expect_success "hash is first line of stat" '
ipfs ls $(head -1 stat) | grep "cats"
'
test_expect_success "stat --hash gives only hash" '
ipfs files stat --hash / >actual &&
head -n1 stat >expected &&
test_cmp expected actual
'
test_expect_success "stat with multiple format options should fail" '
test_must_fail ipfs files stat --hash --size /
'
test_expect_success "compare hash option with format" '
ipfs files stat --hash / >expected &&
ipfs files stat --format='"'"'<hash>'"'"' / >actual &&
test_cmp expected actual
'
test_expect_success "compare size option with format" '
ipfs files stat --size / >expected &&
ipfs files stat --format='"'"'<cumulsize>'"'"' / >actual &&
test_cmp expected actual
'
test_expect_success "check root hash" ' test_expect_success "check root hash" '
ipfs files stat / | head -n1 > roothash ipfs files stat --hash / > roothash
' '
test_expect_success "cannot mkdir /" ' test_expect_success "cannot mkdir /" '
...@@ -74,7 +104,7 @@ test_files_api() { ...@@ -74,7 +104,7 @@ test_files_api() {
' '
test_expect_success "check root hash was not changed" ' test_expect_success "check root hash was not changed" '
ipfs files stat / | head -n1 > roothashafter && ipfs files stat --hash / > roothashafter &&
test_cmp roothash roothashafter test_cmp roothash roothashafter
' '
...@@ -167,7 +197,7 @@ test_files_api() { ...@@ -167,7 +197,7 @@ test_files_api() {
' '
test_expect_success "check root hash" ' test_expect_success "check root hash" '
ipfs files stat / | head -n1 > roothash ipfs files stat --hash / > roothash
' '
test_expect_success "cannot remove root" ' test_expect_success "cannot remove root" '
...@@ -175,7 +205,7 @@ test_files_api() { ...@@ -175,7 +205,7 @@ test_files_api() {
' '
test_expect_success "check root hash was not changed" ' test_expect_success "check root hash was not changed" '
ipfs files stat / | head -n1 > roothashafter && ipfs files stat --hash / > roothashafter &&
test_cmp roothash roothashafter test_cmp roothash roothashafter
' '
...@@ -273,12 +303,12 @@ test_files_api() { ...@@ -273,12 +303,12 @@ test_files_api() {
' '
test_expect_success "cant write to negative offset" ' test_expect_success "cant write to negative offset" '
ipfs files stat /cats/ipfs | head -n1 > filehash && ipfs files stat --hash /cats/ipfs > filehash &&
test_expect_code 1 ipfs files write --offset -1 /cats/ipfs < output test_expect_code 1 ipfs files write --offset -1 /cats/ipfs < output
' '
test_expect_success "verify file was not changed" ' test_expect_success "verify file was not changed" '
ipfs files stat /cats/ipfs | head -n1 > afterhash && ipfs files stat --hash /cats/ipfs > afterhash &&
test_cmp filehash afterhash test_cmp filehash afterhash
' '
...@@ -305,12 +335,12 @@ test_files_api() { ...@@ -305,12 +335,12 @@ test_files_api() {
' '
test_expect_success "cannot write to directory" ' test_expect_success "cannot write to directory" '
ipfs files stat /cats | head -n1 > dirhash && ipfs files stat --hash /cats > dirhash &&
test_expect_code 1 ipfs files write /cats < output test_expect_code 1 ipfs files write /cats < output
' '
test_expect_success "verify dir was not changed" ' test_expect_success "verify dir was not changed" '
ipfs files stat /cats | head -n1 > afterdirhash && ipfs files stat --hash /cats > afterdirhash &&
test_cmp dirhash afterdirhash test_cmp dirhash afterdirhash
' '
...@@ -333,7 +363,7 @@ test_files_api() { ...@@ -333,7 +363,7 @@ test_files_api() {
' '
test_expect_success "changes bubbled up to root on inspection" ' test_expect_success "changes bubbled up to root on inspection" '
ipfs files stat / | head -n1 > root_hash ipfs files stat --hash / > root_hash
' '
test_expect_success "root hash looks good" ' test_expect_success "root hash looks good" '
......
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