cat.go 1.67 KB
Newer Older
1 2 3 4 5
package commands

import (
	"io"

6 7
	cmds "github.com/ipfs/go-ipfs/commands"
	core "github.com/ipfs/go-ipfs/core"
rht's avatar
rht committed
8
	coreunix "github.com/ipfs/go-ipfs/core/coreunix"
9

10
	context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
11 12
)

13 14
const progressBarMinSize = 1024 * 1024 * 8 // show progress bar for outputs > 8MiB

15
var CatCmd = &cmds.Command{
16 17 18
	Helptext: cmds.HelpText{
		Tagline: "Show IPFS object data",
		ShortDescription: `
19
Retrieves the object named by <ipfs-or-ipns-path> and outputs the data
20
it contains.
21 22
`,
	},
23 24

	Arguments: []cmds.Argument{
25
		cmds.StringArg("ipfs-path", true, true, "The path to the IPFS object(s) to be outputted").EnableStdin(),
26
	},
27
	Run: func(req cmds.Request, res cmds.Response) {
Jeromy's avatar
Jeromy committed
28
		node, err := req.InvocContext().GetNode()
29
		if err != nil {
30 31
			res.SetError(err, cmds.ErrNormal)
			return
32 33
		}

Jeromy's avatar
Jeromy committed
34
		readers, length, err := cat(req.Context(), node, req.Arguments())
35
		if err != nil {
36 37
			res.SetError(err, cmds.ErrNormal)
			return
38
		}
Matt Bell's avatar
Matt Bell committed
39

40 41
		res.SetLength(length)

Matt Bell's avatar
Matt Bell committed
42
		reader := io.MultiReader(readers...)
43
		res.SetOutput(reader)
Matt Bell's avatar
Matt Bell committed
44
	},
45
	PostRun: func(req cmds.Request, res cmds.Response) {
46 47 48 49
		if res.Length() < progressBarMinSize {
			return
		}

50
		bar, reader := progressBarForReader(res.Stderr(), res.Output().(io.Reader), int64(res.Length()))
51 52
		bar.Start()

53
		res.SetOutput(reader)
54
	},
55
}
56

57
func cat(ctx context.Context, node *core.IpfsNode, paths []string) ([]io.Reader, uint64, error) {
58
	readers := make([]io.Reader, 0, len(paths))
59
	length := uint64(0)
Jeromy's avatar
Jeromy committed
60
	for _, fpath := range paths {
rht's avatar
rht committed
61
		read, err := coreunix.Cat(ctx, node, fpath)
62
		if err != nil {
63
			return nil, 0, err
64 65
		}
		readers = append(readers, read)
66
		length += uint64(read.Size())
67
	}
68
	return readers, length, nil
69
}