forked from heroku/cli
/
tar.go
47 lines (44 loc) · 935 Bytes
/
tar.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package main
import (
"archive/tar"
"io"
"os"
"path/filepath"
)
func extractTar(f io.Reader, path string) error {
archive := tar.NewReader(f)
for {
hdr, err := archive.Next()
if err == io.EOF {
return nil
}
if err != nil {
return err
}
path := filepath.Join(path, hdr.Name)
switch {
case hdr.FileInfo().IsDir():
if err := os.MkdirAll(path, hdr.FileInfo().Mode()); err != nil {
return err
}
case hdr.Linkname != "":
os.Symlink(hdr.Linkname, path)
default:
if err := extractFile(archive, hdr, path); err != nil {
return err
}
}
}
}
func extractFile(archive io.Reader, hdr *tar.Header, path string) error {
if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
return err
}
file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, hdr.FileInfo().Mode())
if err != nil {
return err
}
defer file.Close()
_, err = io.Copy(file, archive)
return err
}