提交 286a5968 作者: Jeromy Johnson

Merge pull request #2430 from diasdavid/feat/repo-stat

Feature: `ipfs repo stat`
......@@ -3,11 +3,10 @@ package commands
import (
"bytes"
"fmt"
"io"
cmds "github.com/ipfs/go-ipfs/commands"
corerepo "github.com/ipfs/go-ipfs/core/corerepo"
u "gx/ipfs/QmZNVWh8LLjAavuQ2JXuFmuYH3C11xo988vSgp7UQrTRj1/go-ipfs-util"
"io"
)
var RepoCmd = &cmds.Command{
......@@ -19,7 +18,8 @@ var RepoCmd = &cmds.Command{
},
Subcommands: map[string]*cmds.Command{
"gc": repoGcCmd,
"gc": repoGcCmd,
"stat": repoStatCmd,
},
}
......@@ -95,3 +95,60 @@ order to reclaim hard disk space.
},
},
}
var repoStatCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Get stats for the currently used repo.",
ShortDescription: `
'ipfs repo stat' is a plumbing command that will scan the local
set of stored objects and print repo statistics. It outputs to stdout:
NumObjects int number of objects in the local repo
RepoSize int size in bytes that the repo is currently taking
RepoPath string the path to the repo being currently used
`,
},
Run: func(req cmds.Request, res cmds.Response) {
n, err := req.InvocContext().GetNode()
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
stat, err := corerepo.RepoStat(n, req.Context())
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
res.SetOutput(stat)
},
Options: []cmds.Option{
cmds.BoolOption("human", "Output RepoSize in MiB."),
},
Type: corerepo.Stat{},
Marshalers: cmds.MarshalerMap{
cmds.Text: func(res cmds.Response) (io.Reader, error) {
stat, ok := res.Output().(*corerepo.Stat)
if !ok {
return nil, u.ErrCast()
}
human, _, err := res.Request().Option("human").Bool()
if err != nil {
return nil, err
}
buf := new(bytes.Buffer)
fmt.Fprintf(buf, "NumObjects \t %d\n", stat.NumObjects)
sizeInMiB := stat.RepoSize / (1024 * 1024)
if human && sizeInMiB > 0 {
fmt.Fprintf(buf, "RepoSize (MiB) \t %d\n", sizeInMiB)
} else {
fmt.Fprintf(buf, "RepoSize \t %d\n", stat.RepoSize)
}
fmt.Fprintf(buf, "RepoPath \t %s\n", stat.RepoPath)
return buf, nil
},
},
}
package corerepo
import (
"github.com/ipfs/go-ipfs/core"
fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo"
context "gx/ipfs/QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt/go-net/context"
)
type Stat struct {
NumObjects uint64
RepoSize uint64 // size in bytes
RepoPath string
}
func RepoStat(n *core.IpfsNode, ctx context.Context) (*Stat, error) {
r := n.Repo
usage, err := r.GetStorageUsage()
if err != nil {
return nil, err
}
allKeys, err := n.Blockstore.AllKeysChan(ctx)
if err != nil {
return nil, err
}
count := uint64(0)
for range allKeys {
count++
}
path, err := fsrepo.BestKnownPath()
if err != nil {
return nil, err
}
return &Stat{
NumObjects: count,
RepoSize: usage,
RepoPath: path,
}, nil
}
......@@ -219,6 +219,31 @@ test_expect_success "'ipfs refs --unique --recursive (bigger)'" '
test_sort_cmp expected actual || test_fsh cat refs_output
'
get_field_num() {
field=$1
file=$2
num=$(grep "$field" "$file" | awk '{ print $2 }')
echo $num
}
test_expect_success "'ipfs repo stat' succeeds" '
ipfs repo stat > repo-stats
'
test_expect_success "repo stats came out correct" '
grep "RepoPath" repo-stats &&
grep "RepoSize" repo-stats &&
grep "NumObjects" repo-stats
'
test_expect_success "'ipfs repo stat' after adding a file" '
ipfs add repo-stats &&
ipfs repo stat > repo-stats-2
'
test_expect_success "repo stats are updated correctly" '
test $(get_field_num "RepoSize" repo-stats-2) -ge $(get_field_num "RepoSize" repo-stats)
'
test_kill_ipfs_daemon
test_done
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论