tar.go 2.84 KB
Newer Older
Jeromy's avatar
Jeromy committed
1 2 3 4 5 6 7 8
package commands

import (
	"io"
	"strings"

	cmds "github.com/ipfs/go-ipfs/commands"
	core "github.com/ipfs/go-ipfs/core"
Jan Winkelmann's avatar
Jan Winkelmann committed
9
	e "github.com/ipfs/go-ipfs/core/commands/e"
10
	"github.com/ipfs/go-ipfs/core/coreunix"
Jeromy's avatar
Jeromy committed
11
	tar "github.com/ipfs/go-ipfs/tar"
Steven Allen's avatar
Steven Allen committed
12 13
	dag "gx/ipfs/QmcBoNcAP6qDjgRBew7yjvCqHq7p5jMstE44jPUBWBxzsV/go-merkledag"
	path "gx/ipfs/QmcjwUb36Z16NJkvDX6ccXPqsFswo6AsRXynyXcLLCphV2/go-path"
Jan Winkelmann's avatar
Jan Winkelmann committed
14

15
	"gx/ipfs/QmSP88ryZkHSRn1fnngAaV2Vcn63WUJzAavnRM9CVdU1Ky/go-ipfs-cmdkit"
Jeromy's avatar
Jeromy committed
16 17 18
)

var TarCmd = &cmds.Command{
Jan Winkelmann's avatar
Jan Winkelmann committed
19
	Helptext: cmdkit.HelpText{
20
		Tagline: "Utility functions for tar files in ipfs.",
Jeromy's avatar
Jeromy committed
21 22 23 24 25 26 27 28 29
	},

	Subcommands: map[string]*cmds.Command{
		"add": tarAddCmd,
		"cat": tarCatCmd,
	},
}

var tarAddCmd = &cmds.Command{
Jan Winkelmann's avatar
Jan Winkelmann committed
30
	Helptext: cmdkit.HelpText{
rht's avatar
rht committed
31
		Tagline: "Import a tar file into ipfs.",
Jeromy's avatar
Jeromy committed
32
		ShortDescription: `
33 34
'ipfs tar add' will parse a tar file and create a merkledag structure to
represent it.
Jeromy's avatar
Jeromy committed
35 36 37
`,
	},

Jan Winkelmann's avatar
Jan Winkelmann committed
38 39
	Arguments: []cmdkit.Argument{
		cmdkit.FileArg("file", true, false, "Tar file to add.").EnableStdin(),
Jeromy's avatar
Jeromy committed
40 41 42 43
	},
	Run: func(req cmds.Request, res cmds.Response) {
		nd, err := req.InvocContext().GetNode()
		if err != nil {
Jan Winkelmann's avatar
Jan Winkelmann committed
44
			res.SetError(err, cmdkit.ErrNormal)
Jeromy's avatar
Jeromy committed
45 46 47 48 49
			return
		}

		fi, err := req.Files().NextFile()
		if err != nil {
Jan Winkelmann's avatar
Jan Winkelmann committed
50
			res.SetError(err, cmdkit.ErrNormal)
Jeromy's avatar
Jeromy committed
51 52 53
			return
		}

54
		node, err := tar.ImportTar(req.Context(), fi, nd.DAG)
Jeromy's avatar
Jeromy committed
55
		if err != nil {
Jan Winkelmann's avatar
Jan Winkelmann committed
56
			res.SetError(err, cmdkit.ErrNormal)
Jeromy's avatar
Jeromy committed
57 58 59
			return
		}

Jeromy's avatar
Jeromy committed
60
		c := node.Cid()
Jeromy's avatar
Jeromy committed
61 62

		fi.FileName()
63
		res.SetOutput(&coreunix.AddedObject{
Jeromy's avatar
Jeromy committed
64
			Name: fi.FileName(),
Jeromy's avatar
Jeromy committed
65
			Hash: c.String(),
Jeromy's avatar
Jeromy committed
66 67
		})
	},
68
	Type: coreunix.AddedObject{},
Jeromy's avatar
Jeromy committed
69 70
	Marshalers: cmds.MarshalerMap{
		cmds.Text: func(res cmds.Response) (io.Reader, error) {
Jan Winkelmann's avatar
Jan Winkelmann committed
71 72 73 74 75 76 77 78 79
			v, err := unwrapOutput(res.Output())
			if err != nil {
				return nil, err
			}

			o, ok := v.(*coreunix.AddedObject)
			if !ok {
				return nil, e.TypeErr(o, v)
			}
80
			return strings.NewReader(o.Hash + "\n"), nil
Jeromy's avatar
Jeromy committed
81 82 83 84 85
		},
	},
}

var tarCatCmd = &cmds.Command{
Jan Winkelmann's avatar
Jan Winkelmann committed
86
	Helptext: cmdkit.HelpText{
Richard Littauer's avatar
Richard Littauer committed
87
		Tagline: "Export a tar file from IPFS.",
Jeromy's avatar
Jeromy committed
88
		ShortDescription: `
Richard Littauer's avatar
Richard Littauer committed
89
'ipfs tar cat' will export a tar file from a previously imported one in IPFS.
Jeromy's avatar
Jeromy committed
90 91 92
`,
	},

Jan Winkelmann's avatar
Jan Winkelmann committed
93 94
	Arguments: []cmdkit.Argument{
		cmdkit.StringArg("path", true, false, "ipfs path of archive to export.").EnableStdin(),
Jeromy's avatar
Jeromy committed
95 96 97 98
	},
	Run: func(req cmds.Request, res cmds.Response) {
		nd, err := req.InvocContext().GetNode()
		if err != nil {
Jan Winkelmann's avatar
Jan Winkelmann committed
99
			res.SetError(err, cmdkit.ErrNormal)
Jeromy's avatar
Jeromy committed
100 101 102 103 104
			return
		}

		p, err := path.ParsePath(req.Arguments()[0])
		if err != nil {
Jan Winkelmann's avatar
Jan Winkelmann committed
105
			res.SetError(err, cmdkit.ErrNormal)
Jeromy's avatar
Jeromy committed
106 107 108
			return
		}

109
		root, err := core.Resolve(req.Context(), nd.Namesys, nd.Resolver, p)
Jeromy's avatar
Jeromy committed
110
		if err != nil {
Jan Winkelmann's avatar
Jan Winkelmann committed
111
			res.SetError(err, cmdkit.ErrNormal)
Jeromy's avatar
Jeromy committed
112 113 114
			return
		}

115 116
		rootpb, ok := root.(*dag.ProtoNode)
		if !ok {
Jan Winkelmann's avatar
Jan Winkelmann committed
117
			res.SetError(dag.ErrNotProtobuf, cmdkit.ErrNormal)
118 119 120 121
			return
		}

		r, err := tar.ExportTar(req.Context(), rootpb, nd.DAG)
Jeromy's avatar
Jeromy committed
122
		if err != nil {
Jan Winkelmann's avatar
Jan Winkelmann committed
123
			res.SetError(err, cmdkit.ErrNormal)
Jeromy's avatar
Jeromy committed
124 125 126 127 128 129
			return
		}

		res.SetOutput(r)
	},
}