@cryptotaxi247 / kubo / commits / 3406ee0ef

core/commands2: Added 'refs' command

Matt Bell committed Nov 9, 2014 at 19:22 UTC 3406ee0ef4ee8549621a658c4a08392519380ee0
2 files changed +133
core/commands2/refs.go new
+132
@@ -0,0 +1,132 @@
1 +package commands
2 +
3 +import (
4 + "fmt"
5 +
6 + mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
7 + cmds "github.com/jbenet/go-ipfs/commands"
8 + "github.com/jbenet/go-ipfs/core"
9 + "github.com/jbenet/go-ipfs/core/commands2/internal"
10 + dag "github.com/jbenet/go-ipfs/merkledag"
11 + u "github.com/jbenet/go-ipfs/util"
12 +)
13 +
14 +type RefsOutput struct {
15 + Refs []string
16 +}
17 +
18 +var refsCmd = &cmds.Command{
19 + Description: "Lists link hashes from an object",
20 + Help: `Retrieves the object named by <ipfs-path> and displays the link
21 + hashes it contains, with the following format:
22 +
23 + <link base58 hash>`,
24 +
25 + Arguments: []cmds.Argument{
26 + cmds.Argument{"ipfs-path", cmds.ArgString, true, true,
27 + "Path to the object(s) to list refs from"},
28 + },
29 + Options: []cmds.Option{
30 + cmds.Option{[]string{"unique", "u"}, cmds.Bool,
31 + "Omit duplicate refs from output"},
32 + cmds.Option{[]string{"recursive", "r"}, cmds.Bool,
33 + "Recursively list links of child nodes"},
34 + },
35 + Run: func(res cmds.Response, req cmds.Request) {
36 + n := req.Context().Node
37 +
38 + opt, found := req.Option("unique")
39 + unique, ok := opt.(bool)
40 + if !ok && found {
41 + unique = false
42 + }
43 +
44 + opt, found = req.Option("recursive")
45 + recursive, ok := opt.(bool)
46 + if !ok && found {
47 + recursive = false
48 + }
49 +
50 + paths, err := internal.CastToStrings(req.Arguments())
51 + if err != nil {
52 + res.SetError(err, cmds.ErrNormal)
53 + return
54 + }
55 +
56 + output, err := getRefs(n, paths, unique, recursive)
57 + if err != nil {
58 + res.SetError(err, cmds.ErrNormal)
59 + return
60 + }
61 +
62 + res.SetOutput(output)
63 + },
64 + Type: &RefsOutput{},
65 + Marshallers: map[cmds.EncodingType]cmds.Marshaller{
66 + cmds.Text: func(res cmds.Response) ([]byte, error) {
67 + output := res.Output().(*RefsOutput)
68 + s := ""
69 + for _, ref := range output.Refs {
70 + s += fmt.Sprintln(ref)
71 + }
72 + return []byte(s), nil
73 + },
74 + },
75 +}
76 +
77 +func getRefs(n *core.IpfsNode, paths []string, unique, recursive bool) (*RefsOutput, error) {
78 + var refsSeen map[u.Key]bool
79 + if unique {
80 + refsSeen = make(map[u.Key]bool)
81 + }
82 +
83 + refs := make([]string, 0)
84 +
85 + for _, path := range paths {
86 + object, err := n.Resolver.ResolvePath(path)
87 + if err != nil {
88 + return nil, err
89 + }
90 +
91 + refs, err = addRefs(n, object, refs, refsSeen, recursive)
92 + if err != nil {
93 + return nil, err
94 + }
95 + }
96 +
97 + return &RefsOutput{refs}, nil
98 +}
99 +
100 +func addRefs(n *core.IpfsNode, object *dag.Node, refs []string, refsSeen map[u.Key]bool, recursive bool) ([]string, error) {
101 + for _, link := range object.Links {
102 + var found bool
103 + found, refs = addRef(link.Hash, refs, refsSeen)
104 +
105 + if recursive && !found {
106 + child, err := n.DAG.Get(u.Key(link.Hash))
107 + if err != nil {
108 + return nil, fmt.Errorf("cannot retrieve %s (%s)", link.Hash.B58String(), err)
109 + }
110 +
111 + refs, err = addRefs(n, child, refs, refsSeen, recursive)
112 + if err != nil {
113 + return nil, err
114 + }
115 + }
116 + }
117 +
118 + return refs, nil
119 +}
120 +
121 +func addRef(h mh.Multihash, refs []string, refsSeen map[u.Key]bool) (bool, []string) {
122 + if refsSeen != nil {
123 + _, found := refsSeen[u.Key(h)]
124 + if found {
125 + return true, refs
126 + }
127 + refsSeen[u.Key(h)] = true
128 + }
129 +
130 + refs = append(refs, h.B58String())
131 + return false, refs
132 +}
core/commands2/root.go
+1
@@ -71,6 +71,7 @@ var rootSubcommands = map[string]*cmds.Command{
71 "block": blockCmd,
72 "update": updateCmd,
73 "object": objectCmd,
74 + "refs": refsCmd,
75 }
76
77 func init() {