@cryptotaxi247 / kubo / commits / c10e329b7

repo-stat

License: MIT Signed-off-by: David Dias <daviddias.p@gmail.com>

David Dias committed Mar 2, 2016 at 08:48 UTC c10e329b789b931fa384d4cf83ad1d23d5cf1a57
3 files changed +99 -43
core/commands/repo.go
+31 -43
@@ -3,22 +3,12 @@ package commands
3 import (
4 "bytes"
5 "fmt"
6 - "io"
7 - "strings"
8 -
9 - humanize "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/dustin/go-humanize"
6 cmds "github.com/ipfs/go-ipfs/commands"
7 corerepo "github.com/ipfs/go-ipfs/core/corerepo"
12 - fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo"
8 u "gx/ipfs/QmZNVWh8LLjAavuQ2JXuFmuYH3C11xo988vSgp7UQrTRj1/go-ipfs-util"
9 + "io"
10 )
11
16 -type RepoStat struct {
17 - repoPath string
18 - repoSize uint64 // size in bytes
19 - numBlocks uint64
20 -}
21 -
12 var RepoCmd = &cmds.Command{
13 Helptext: cmds.HelpText{
14 Tagline: "Manipulate the IPFS repo.",
@@ -108,59 +98,57 @@ order to reclaim hard disk space.
98
99 var repoStatCmd = &cmds.Command{
100 Helptext: cmds.HelpText{
111 - Tagline: "Print status of the local repo.",
112 - ShortDescription: ``,
101 + Tagline: "Get stats for the currently used repo.",
102 + ShortDescription: `
103 +'ipfs repo stat' is a plumbing command that will scan the local
104 +set of stored objects and print repo statistics. It outputs to stdout:
105 +NumObjects int number of objects in the local repo
106 +RepoSize int size in bytes that the repo is currently taking
107 +RepoPath string the path to the repo being currently used
108 +`,
109 },
110 Run: func(req cmds.Request, res cmds.Response) {
115 - ctx := req.Context()
111 n, err := req.InvocContext().GetNode()
112 if err != nil {
113 res.SetError(err, cmds.ErrNormal)
114 return
115 }
116
122 - usage, err := n.Repo.GetStorageUsage()
123 - if err != nil {
124 - res.SetError(err, cmds.ErrNormal)
125 - return
126 - }
127 -
128 - allKeys, err := n.Blockstore.AllKeysChan(ctx)
129 - if err != nil {
130 - res.SetError(err, cmds.ErrNormal)
131 - return
132 - }
133 -
134 - count := uint64(0)
135 - for range allKeys {
136 - count++
137 - }
138 -
139 - path, err := fsrepo.BestKnownPath()
117 + stat, err := corerepo.RepoStat(n, req.Context())
118 if err != nil {
119 res.SetError(err, cmds.ErrNormal)
120 return
121 }
122
145 - res.SetOutput(&RepoStat{
146 - repoPath: path,
147 - repoSize: usage,
148 - numBlocks: count,
149 - })
123 + res.SetOutput(stat)
124 },
151 - Type: RepoStat{},
125 + Options: []cmds.Option{
126 + cmds.BoolOption("human", "Output RepoSize in MiB."),
127 + },
128 + Type: corerepo.Stat{},
129 Marshalers: cmds.MarshalerMap{
130 cmds.Text: func(res cmds.Response) (io.Reader, error) {
154 - stat, ok := res.Output().(*RepoStat)
131 + stat, ok := res.Output().(*corerepo.Stat)
132 if !ok {
133 return nil, u.ErrCast()
134 }
135
159 - out := fmt.Sprintf(
160 - "Path: %s\nSize: %s\nBlocks: %d\n",
161 - stat.repoPath, humanize.Bytes(stat.repoSize), stat.numBlocks)
136 + human, _, err := res.Request().Option("human").Bool()
137 + if err != nil {
138 + return nil, err
139 + }
140 +
141 + buf := new(bytes.Buffer)
142 + fmt.Fprintf(buf, "NumObjects \t %d\n", stat.NumObjects)
143 + sizeInMiB := stat.RepoSize / (1024 * 1024)
144 + if human && sizeInMiB > 0 {
145 + fmt.Fprintf(buf, "RepoSize (MiB) \t %d\n", sizeInMiB)
146 + } else {
147 + fmt.Fprintf(buf, "RepoSize \t %d\n", stat.RepoSize)
148 + }
149 + fmt.Fprintf(buf, "RepoPath \t %s\n", stat.RepoPath)
150
163 - return strings.NewReader(out), nil
151 + return buf, nil
152 },
153 },
154 }
core/corerepo/stat.go new
+43
@@ -0,0 +1,43 @@
1 +package corerepo
2 +
3 +import (
4 + "github.com/ipfs/go-ipfs/core"
5 + fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo"
6 + context "gx/ipfs/QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt/go-net/context"
7 +)
8 +
9 +type Stat struct {
10 + NumObjects uint64
11 + RepoSize uint64 // size in bytes
12 + RepoPath string
13 +}
14 +
15 +func RepoStat(n *core.IpfsNode, ctx context.Context) (*Stat, error) {
16 + r := n.Repo
17 +
18 + usage, err := r.GetStorageUsage()
19 + if err != nil {
20 + return nil, err
21 + }
22 +
23 + allKeys, err := n.Blockstore.AllKeysChan(ctx)
24 + if err != nil {
25 + return nil, err
26 + }
27 +
28 + count := uint64(0)
29 + for range allKeys {
30 + count++
31 + }
32 +
33 + path, err := fsrepo.BestKnownPath()
34 + if err != nil {
35 + return nil, err
36 + }
37 +
38 + return &Stat{
39 + NumObjects: count,
40 + RepoSize: usage,
41 + RepoPath: path,
42 + }, nil
43 +}
test/sharness/t0080-repo.sh
+25
@@ -219,6 +219,31 @@ test_expect_success "'ipfs refs --unique --recursive (bigger)'" '
219 test_sort_cmp expected actual || test_fsh cat refs_output
220 '
221
222 +get_field_num() {
223 + field=$1
224 + file=$2
225 + num=$(grep "$field" "$file" | awk '{ print $2 }')
226 + echo $num
227 +}
228 +
229 +test_expect_success "'ipfs repo stat' succeeds" '
230 + ipfs repo stat > repo-stats
231 +'
232 +test_expect_success "repo stats came out correct" '
233 + grep "RepoPath" repo-stats &&
234 + grep "RepoSize" repo-stats &&
235 + grep "NumObjects" repo-stats
236 +'
237 +
238 +test_expect_success "'ipfs repo stat' after adding a file" '
239 + ipfs add repo-stats &&
240 + ipfs repo stat > repo-stats-2
241 +'
242 +
243 +test_expect_success "repo stats are updated correctly" '
244 + test $(get_field_num "RepoSize" repo-stats-2) -ge $(get_field_num "RepoSize" repo-stats)
245 +'
246 +
247 test_kill_ipfs_daemon
248
249 test_done