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  }