github.com/keltia/go-ipfs@v0.3.8-0.20150909044612-210793031c63/core/commands/ls.go (about) 1 package commands 2 3 import ( 4 "bytes" 5 "fmt" 6 "io" 7 "text/tabwriter" 8 9 cmds "github.com/ipfs/go-ipfs/commands" 10 core "github.com/ipfs/go-ipfs/core" 11 merkledag "github.com/ipfs/go-ipfs/merkledag" 12 path "github.com/ipfs/go-ipfs/path" 13 unixfs "github.com/ipfs/go-ipfs/unixfs" 14 unixfspb "github.com/ipfs/go-ipfs/unixfs/pb" 15 ) 16 17 type LsLink struct { 18 Name, Hash string 19 Size uint64 20 Type unixfspb.Data_DataType 21 } 22 23 type LsObject struct { 24 Hash string 25 Links []LsLink 26 } 27 28 type LsOutput struct { 29 Objects []LsObject 30 } 31 32 var LsCmd = &cmds.Command{ 33 Helptext: cmds.HelpText{ 34 Tagline: "List links from an object.", 35 ShortDescription: ` 36 Retrieves the object named by <ipfs-or-ipns-path> and displays the links 37 it contains, with the following format: 38 39 <link base58 hash> <link size in bytes> <link name> 40 `, 41 }, 42 43 Arguments: []cmds.Argument{ 44 cmds.StringArg("ipfs-path", true, true, "The path to the IPFS object(s) to list links from").EnableStdin(), 45 }, 46 Options: []cmds.Option{ 47 cmds.BoolOption("headers", "", "Print table headers (Hash, Name, Size)"), 48 }, 49 Run: func(req cmds.Request, res cmds.Response) { 50 node, err := req.InvocContext().GetNode() 51 if err != nil { 52 res.SetError(err, cmds.ErrNormal) 53 return 54 } 55 56 // get options early -> exit early in case of error 57 if _, _, err := req.Option("headers").Bool(); err != nil { 58 res.SetError(err, cmds.ErrNormal) 59 return 60 } 61 62 paths := req.Arguments() 63 64 var dagnodes []*merkledag.Node 65 for _, fpath := range paths { 66 dagnode, err := core.Resolve(req.Context(), node, path.Path(fpath)) 67 if err != nil { 68 res.SetError(err, cmds.ErrNormal) 69 return 70 } 71 dagnodes = append(dagnodes, dagnode) 72 } 73 74 output := make([]LsObject, len(req.Arguments())) 75 for i, dagnode := range dagnodes { 76 output[i] = LsObject{ 77 Hash: paths[i], 78 Links: make([]LsLink, len(dagnode.Links)), 79 } 80 for j, link := range dagnode.Links { 81 link.Node, err = link.GetNode(req.Context(), node.DAG) 82 if err != nil { 83 res.SetError(err, cmds.ErrNormal) 84 return 85 } 86 d, err := unixfs.FromBytes(link.Node.Data) 87 if err != nil { 88 res.SetError(err, cmds.ErrNormal) 89 return 90 } 91 output[i].Links[j] = LsLink{ 92 Name: link.Name, 93 Hash: link.Hash.B58String(), 94 Size: link.Size, 95 Type: d.GetType(), 96 } 97 } 98 } 99 100 res.SetOutput(&LsOutput{output}) 101 }, 102 Marshalers: cmds.MarshalerMap{ 103 cmds.Text: func(res cmds.Response) (io.Reader, error) { 104 105 headers, _, _ := res.Request().Option("headers").Bool() 106 output := res.Output().(*LsOutput) 107 buf := new(bytes.Buffer) 108 w := tabwriter.NewWriter(buf, 1, 2, 1, ' ', 0) 109 for _, object := range output.Objects { 110 if len(output.Objects) > 1 { 111 fmt.Fprintf(w, "%s:\n", object.Hash) 112 } 113 if headers { 114 fmt.Fprintln(w, "Hash\tSize\tName") 115 } 116 for _, link := range object.Links { 117 if link.Type == unixfspb.Data_Directory { 118 link.Name += "/" 119 } 120 fmt.Fprintf(w, "%s\t%v\t%s\n", link.Hash, link.Size, link.Name) 121 } 122 if len(output.Objects) > 1 { 123 fmt.Fprintln(w) 124 } 125 } 126 w.Flush() 127 128 return buf, nil 129 }, 130 }, 131 Type: LsOutput{}, 132 }