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
}