12 // TarGzipDecompressor is an implementation of Decompressor that can
13 // decompress tar.gzip files.
14 type TarGzipDecompressor struct{}
16 func (d *TarGzipDecompressor) Decompress(dst, src string, dir bool) error {
17 // If we're going into a directory we should make that first
20 mkdir = filepath.Dir(dst)
22 if err := os.MkdirAll(mkdir, 0755); err != nil {
27 f, err := os.Open(src)
33 // Gzip compression is second
34 gzipR, err := gzip.NewReader(f)
36 return fmt.Errorf("Error opening a gzip reader for %s: %s", src, err)
40 // Once gzip decompressed we have a tar format
41 tarR := tar.NewReader(gzipR)
44 hdr, err := tarR.Next()
48 return fmt.Errorf("empty archive: %s", src)
59 path = filepath.Join(path, hdr.Name)
62 if hdr.FileInfo().IsDir() {
64 return fmt.Errorf("expected a single file: %s", src)
67 // A directory, just make the directory and continue unarchiving...
68 if err := os.MkdirAll(path, 0755); err != nil {
75 // We have a file. If we already decoded, then it is an error
77 return fmt.Errorf("expected a single file, got multiple: %s", src)
80 // Mark that we're done so future in single file mode errors
83 // Open the file for writing
84 dstF, err := os.Create(path)
88 _, err = io.Copy(dstF, tarR)
95 if err := os.Chmod(path, hdr.FileInfo().Mode()); err != nil {