github.com/zignig/go-ipfs@v0.0.0-20141111235910-c9e5fdf55a52/core/commands2/refs.go (about) 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 Note: list all refs recursively with -r.`, 26 27 Arguments: []cmds.Argument{ 28 cmds.StringArg("ipfs-path", true, true, "Path to the object(s) to list refs from"), 29 }, 30 Options: []cmds.Option{ 31 cmds.BoolOption("unique", "u", "Omit duplicate refs from output"), 32 cmds.BoolOption("recursive", "r", "Recursively list links of child nodes"), 33 }, 34 Run: func(req cmds.Request) (interface{}, error) { 35 n := req.Context().Node 36 37 unique, _ := req.Option("unique").Bool() 38 recursive, _ := req.Option("recursive").Bool() 39 40 paths, err := internal.CastToStrings(req.Arguments()) 41 if err != nil { 42 return nil, err 43 } 44 45 return getRefs(n, paths, unique, recursive) 46 }, 47 Type: &RefsOutput{}, 48 Marshallers: map[cmds.EncodingType]cmds.Marshaller{ 49 cmds.Text: func(res cmds.Response) ([]byte, error) { 50 output := res.Output().(*RefsOutput) 51 s := "" 52 for _, ref := range output.Refs { 53 s += fmt.Sprintln(ref) 54 } 55 return []byte(s), nil 56 }, 57 }, 58 } 59 60 func getRefs(n *core.IpfsNode, paths []string, unique, recursive bool) (*RefsOutput, error) { 61 var refsSeen map[u.Key]bool 62 if unique { 63 refsSeen = make(map[u.Key]bool) 64 } 65 66 refs := make([]string, 0) 67 68 for _, path := range paths { 69 object, err := n.Resolver.ResolvePath(path) 70 if err != nil { 71 return nil, err 72 } 73 74 refs, err = addRefs(n, object, refs, refsSeen, recursive) 75 if err != nil { 76 return nil, err 77 } 78 } 79 80 return &RefsOutput{refs}, nil 81 } 82 83 func addRefs(n *core.IpfsNode, object *dag.Node, refs []string, refsSeen map[u.Key]bool, recursive bool) ([]string, error) { 84 for _, link := range object.Links { 85 var found bool 86 found, refs = addRef(link.Hash, refs, refsSeen) 87 88 if recursive && !found { 89 child, err := n.DAG.Get(u.Key(link.Hash)) 90 if err != nil { 91 return nil, fmt.Errorf("cannot retrieve %s (%s)", link.Hash.B58String(), err) 92 } 93 94 refs, err = addRefs(n, child, refs, refsSeen, recursive) 95 if err != nil { 96 return nil, err 97 } 98 } 99 } 100 101 return refs, nil 102 } 103 104 func addRef(h mh.Multihash, refs []string, refsSeen map[u.Key]bool) (bool, []string) { 105 if refsSeen != nil { 106 _, found := refsSeen[u.Key(h)] 107 if found { 108 return true, refs 109 } 110 refsSeen[u.Key(h)] = true 111 } 112 113 refs = append(refs, h.B58String()) 114 return false, refs 115 }