diff --git a/core/commands/repo.go b/core/commands/repo.go index 7054ae9821ba..e135ee88ff53 100644 --- a/core/commands/repo.go +++ b/core/commands/repo.go @@ -3,22 +3,12 @@ package commands import ( "bytes" "fmt" - "io" - "strings" - - humanize "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/dustin/go-humanize" cmds "github.com/ipfs/go-ipfs/commands" corerepo "github.com/ipfs/go-ipfs/core/corerepo" - fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo" u "gx/ipfs/QmZNVWh8LLjAavuQ2JXuFmuYH3C11xo988vSgp7UQrTRj1/go-ipfs-util" + "io" ) -type RepoStat struct { - repoPath string - repoSize uint64 // size in bytes - numBlocks uint64 -} - var RepoCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Manipulate the IPFS repo.", @@ -108,59 +98,44 @@ order to reclaim hard disk space. var repoStatCmd = &cmds.Command{ Helptext: cmds.HelpText{ - Tagline: "Print status of the local repo.", - ShortDescription: ``, + 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 that the repo is currently taking +RepoPath string the path to the repo being currently used +`, }, Run: func(req cmds.Request, res cmds.Response) { - ctx := req.Context() n, err := req.InvocContext().GetNode() if err != nil { res.SetError(err, cmds.ErrNormal) return } - usage, err := n.Repo.GetStorageUsage() - if err != nil { - res.SetError(err, cmds.ErrNormal) - return - } - - allKeys, err := n.Blockstore.AllKeysChan(ctx) - if err != nil { - res.SetError(err, cmds.ErrNormal) - return - } - - count := uint64(0) - for range allKeys { - count++ - } - - path, err := fsrepo.BestKnownPath() + stat, err := corerepo.RepoStat(n, req.Context()) if err != nil { res.SetError(err, cmds.ErrNormal) return } - res.SetOutput(&RepoStat{ - repoPath: path, - repoSize: usage, - numBlocks: count, - }) + res.SetOutput(stat) }, - Type: RepoStat{}, + Type: corerepo.Stat{}, Marshalers: cmds.MarshalerMap{ cmds.Text: func(res cmds.Response) (io.Reader, error) { - stat, ok := res.Output().(*RepoStat) + stat, ok := res.Output().(*corerepo.Stat) if !ok { return nil, u.ErrCast() } - out := fmt.Sprintf( - "Path: %s\nSize: %s\nBlocks: %d\n", - stat.repoPath, humanize.Bytes(stat.repoSize), stat.numBlocks) + buf := new(bytes.Buffer) + fmt.Fprintf(buf, "NumObjects \t %d\n", stat.NumObjects) + fmt.Fprintf(buf, "RepoSize \t %d\n", stat.RepoSize) + fmt.Fprintf(buf, "RepoPath \t %s\n", stat.RepoPath) - return strings.NewReader(out), nil + return buf, nil }, }, } diff --git a/core/corerepo/stat.go b/core/corerepo/stat.go new file mode 100644 index 000000000000..65abf2efd42f --- /dev/null +++ b/core/corerepo/stat.go @@ -0,0 +1,43 @@ +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 +} diff --git a/test/sharness/t0080-repo.sh b/test/sharness/t0080-repo.sh index 01ef79b0ab35..c7ad6c8e1afe 100755 --- a/test/sharness/t0080-repo.sh +++ b/test/sharness/t0080-repo.sh @@ -219,6 +219,26 @@ 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 && + cat stats | wc -l > repo-stats.counter && + echo "3" > repo-stats.counter.expected && + test_cmp repo-stats.counter repo-stats.counter.expected && + grep "RepoPath" repo-stats && + grep "RepoSize" repo-stats && + grep "NumObjects" repo-stats && + ipfs add repo-stats && + ipfs repo stat > repo-stats-2 && + test $(get_field_num "RepoSize" repo-stats) -ge $(get_field_num "RepoSize" repo-stats-2) +' + test_kill_ipfs_daemon test_done