Skip to content

Commit

Permalink
tar bzip2
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchellh committed Jan 12, 2016
1 parent 192638c commit 428c092
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 5 deletions.
9 changes: 6 additions & 3 deletions decompress.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,14 @@ type Decompressor interface {
var Decompressors map[string]Decompressor

func init() {
tbzDecompressor := new(TarBzip2Decompressor)
tgzDecompressor := new(TarGzipDecompressor)

Decompressors = map[string]Decompressor{
"tar.gz": tgzDecompressor,
"tgz": tgzDecompressor,
"zip": new(ZipDecompressor),
"tar.bz2": tbzDecompressor,
"tar.gz": tgzDecompressor,
"tbz2": tbzDecompressor,
"tgz": tgzDecompressor,
"zip": new(ZipDecompressor),
}
}
95 changes: 95 additions & 0 deletions decompress_tbz2.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package getter

import (
"archive/tar"
"compress/bzip2"
"fmt"
"io"
"os"
"path/filepath"
)

// TarBzip2Decompressor is an implementation of Decompressor that can
// decompress tar.bz2 files.
type TarBzip2Decompressor struct{}

func (d *TarBzip2Decompressor) Decompress(dst, src string, dir bool) error {
// If we're going into a directory we should make that first
mkdir := dst
if !dir {
mkdir = filepath.Dir(dst)
}
if err := os.MkdirAll(mkdir, 0755); err != nil {
return err
}

// File first
f, err := os.Open(src)
if err != nil {
return err
}
defer f.Close()

// Bzip2 compression is second
bzipR := bzip2.NewReader(f)

// Once bzip decompressed we have a tar format
tarR := tar.NewReader(bzipR)
done := false
for {
hdr, err := tarR.Next()
if err == io.EOF {
if !done {
// Empty archive
return fmt.Errorf("empty archive: %s", src)
}

return nil
}
if err != nil {
return err
}

path := dst
if dir {
path = filepath.Join(path, hdr.Name)
}

if hdr.FileInfo().IsDir() {
if dir {
return fmt.Errorf("expected a single file: %s", src)
}

// A directory, just make the directory and continue unarchiving...
if err := os.MkdirAll(path, 0755); err != nil {
return err
}

continue
}

// We have a file. If we already decoded, then it is an error
if !dir && done {
return fmt.Errorf("expected a single file, got multiple: %s", src)
}

// Mark that we're done so future in single file mode errors
done = true

// Open the file for writing
dstF, err := os.Create(path)
if err != nil {
return err
}
_, err = io.Copy(dstF, tarR)
dstF.Close()
if err != nil {
return err
}

// Chmod the file
if err := os.Chmod(path, hdr.FileInfo().Mode()); err != nil {
return err
}
}
}
56 changes: 56 additions & 0 deletions decompress_tbz2_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package getter

import (
"path/filepath"
"testing"
)

func TestTarBzip2Decompressor(t *testing.T) {
cases := []TestDecompressCase{
{
"empty.tar.bz2",
false,
true,
nil,
"",
},

{
"single.tar.bz2",
false,
false,
nil,
"d3b07384d113edec49eaa6238ad5ff00",
},

{
"single.tar.bz2",
true,
false,
[]string{"file"},
"",
},

{
"multiple.tar.bz2",
true,
false,
[]string{"file1", "file2"},
"",
},

{
"multiple.tar.bz2",
false,
true,
nil,
"",
},
}

for i, tc := range cases {
cases[i].Input = filepath.Join("./test-fixtures", "decompress-tbz2", tc.Input)
}

TestDecompressor(t, new(TarBzip2Decompressor), cases)
}
4 changes: 2 additions & 2 deletions decompress_tgz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ func TestTarGzipDecompressor(t *testing.T) {
},
}

for _, tc := range cases {
tc.Input = filepath.Join("./test-fixtures", "decompress-tgz", tc.Input)
for i, tc := range cases {
cases[i].Input = filepath.Join("./test-fixtures", "decompress-tgz", tc.Input)
}

TestDecompressor(t, new(TarGzipDecompressor), cases)
Expand Down
Binary file added test-fixtures/decompress-tbz2/empty.tar.bz2
Binary file not shown.
Binary file added test-fixtures/decompress-tbz2/multiple.tar.bz2
Binary file not shown.
Binary file added test-fixtures/decompress-tbz2/single.tar.bz2
Binary file not shown.

0 comments on commit 428c092

Please sign in to comment.