@cryptotaxi247 / kubo / commits / f433a9520

core/commands: Save 'get' output to disk

squash! core/commands: Save 'get' output to disk core/commands: get: Fixed PostRun signature

Matt Bell committed Jan 22, 2015 at 11:01 UTC f433a95201188ef0afb9ae15e308b34ed29a9811
1 file changed +116 -1
core/commands/get.go
+116 -1
@@ -3,8 +3,12 @@ package commands
3 import (
4 "archive/tar"
5 "bytes"
6 + "fmt"
7 "io"
8 + "os"
9 p "path"
10 + fp "path/filepath"
11 + "strings"
12 "sync"
13
14 cmds "github.com/jbenet/go-ipfs/commands"
@@ -50,6 +54,117 @@ To output a TAR archive instead of unpacked files, use '--archive' or '-a'.
54 }
55 res.SetOutput(reader)
56 },
57 + PostRun: func(req cmds.Request, res cmds.Response) {
58 + reader := res.Output().(io.Reader)
59 + res.SetOutput(nil)
60 +
61 + outPath, _, _ := res.Request().Option("output").String()
62 + if len(outPath) == 0 {
63 + outPath = res.Request().Arguments()[0]
64 + }
65 +
66 + if archive, _, _ := res.Request().Option("archive").Bool(); archive {
67 + if !strings.HasSuffix(outPath, ".tar") {
68 + outPath += ".tar"
69 + }
70 + fmt.Printf("Saving archive to %s\n", outPath)
71 +
72 + file, err := os.Create(outPath)
73 + if err != nil {
74 + res.SetError(err, cmds.ErrNormal)
75 + return
76 + }
77 + defer file.Close()
78 +
79 + _, err = io.Copy(file, reader)
80 + if err != nil {
81 + res.SetError(err, cmds.ErrNormal)
82 + return
83 + }
84 +
85 + return
86 + }
87 +
88 + fmt.Printf("Saving file(s) to %s\n", outPath)
89 +
90 + preexisting := true
91 + pathIsDir := false
92 + if stat, err := os.Stat(outPath); err != nil && os.IsNotExist(err) {
93 + preexisting = false
94 + } else if err != nil {
95 + res.SetError(err, cmds.ErrNormal)
96 + return
97 + } else if stat.IsDir() {
98 + pathIsDir = true
99 + }
100 +
101 + tarReader := tar.NewReader(reader)
102 +
103 + for i := 0; ; i++ {
104 + header, err := tarReader.Next()
105 + if err != nil && err != io.EOF {
106 + res.SetError(err, cmds.ErrNormal)
107 + return
108 + }
109 + if header == nil || err == io.EOF {
110 + break
111 + }
112 +
113 + if header.Typeflag == tar.TypeDir {
114 + pathElements := strings.Split(header.Name, "/")
115 + if !preexisting {
116 + pathElements = pathElements[1:]
117 + }
118 + path := fp.Join(pathElements...)
119 + path = fp.Join(outPath, path)
120 + if i == 0 {
121 + outPath = path
122 + }
123 +
124 + err = os.MkdirAll(path, 0755)
125 + if err != nil {
126 + res.SetError(err, cmds.ErrNormal)
127 + return
128 + }
129 + continue
130 + }
131 +
132 + var path string
133 + if i == 0 {
134 + if preexisting {
135 + if !pathIsDir {
136 + res.SetError(os.ErrExist, cmds.ErrNormal)
137 + return
138 + }
139 + path = fp.Join(outPath, header.Name)
140 + } else {
141 + path = outPath
142 + }
143 + } else {
144 + pathElements := strings.Split(header.Name, "/")[1:]
145 + path = fp.Join(pathElements...)
146 + path = fp.Join(outPath, path)
147 + }
148 +
149 + file, err := os.Create(path)
150 + if err != nil {
151 + res.SetError(err, cmds.ErrNormal)
152 + return
153 + }
154 +
155 + _, err = io.Copy(file, tarReader)
156 + if err != nil {
157 + res.SetError(err, cmds.ErrNormal)
158 + return
159 + }
160 +
161 + err = file.Close()
162 + if err != nil {
163 + res.SetError(err, cmds.ErrNormal)
164 + return
165 + }
166 + }
167 + },
168 }
169
170 func get(node *core.IpfsNode, path string) (io.Reader, error) {
@@ -74,7 +189,7 @@ func copyFilesAsTar(node *core.IpfsNode, buf *bufReadWriter, path string) error
189 return err
190 }
191
77 - err = writer.Flush()
192 + err = writer.Close()
193 if err != nil {
194 return err
195 }