diff --git a/vendor/github.com/hashicorp/go-getter/decompress.go b/vendor/github.com/hashicorp/go-getter/decompress.go new file mode 100644 index 000000000..d18174cc3 --- /dev/null +++ b/vendor/github.com/hashicorp/go-getter/decompress.go @@ -0,0 +1,29 @@ +package getter + +// Decompressor defines the interface that must be implemented to add +// support for decompressing a type. +type Decompressor interface { + // Decompress should decompress src to dst. dir specifies whether dst + // is a directory or single file. src is guaranteed to be a single file + // that exists. dst is not guaranteed to exist already. + Decompress(dst, src string, dir bool) error +} + +// Decompressors is the mapping of extension to the Decompressor implementation +// that will decompress that extension/type. +var Decompressors map[string]Decompressor + +func init() { + tbzDecompressor := new(TarBzip2Decompressor) + tgzDecompressor := new(TarGzipDecompressor) + + Decompressors = map[string]Decompressor{ + "bz2": new(Bzip2Decompressor), + "gz": new(GzipDecompressor), + "tar.bz2": tbzDecompressor, + "tar.gz": tgzDecompressor, + "tbz2": tbzDecompressor, + "tgz": tgzDecompressor, + "zip": new(ZipDecompressor), + } +} diff --git a/vendor/github.com/hashicorp/go-getter/decompress_bzip2.go b/vendor/github.com/hashicorp/go-getter/decompress_bzip2.go new file mode 100644 index 000000000..339f4cf7a --- /dev/null +++ b/vendor/github.com/hashicorp/go-getter/decompress_bzip2.go @@ -0,0 +1,45 @@ +package getter + +import ( + "compress/bzip2" + "fmt" + "io" + "os" + "path/filepath" +) + +// Bzip2Decompressor is an implementation of Decompressor that can +// decompress bz2 files. +type Bzip2Decompressor struct{} + +func (d *Bzip2Decompressor) Decompress(dst, src string, dir bool) error { + // Directory isn't supported at all + if dir { + return fmt.Errorf("bzip2-compressed files can only unarchive to a single file") + } + + // If we're going into a directory we should make that first + if err := os.MkdirAll(filepath.Dir(dst), 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) + + // Copy it out + dstF, err := os.Create(dst) + if err != nil { + return err + } + defer dstF.Close() + + _, err = io.Copy(dstF, bzipR) + return err +} diff --git a/vendor/github.com/hashicorp/go-getter/decompress_gzip.go b/vendor/github.com/hashicorp/go-getter/decompress_gzip.go new file mode 100644 index 000000000..20010540e --- /dev/null +++ b/vendor/github.com/hashicorp/go-getter/decompress_gzip.go @@ -0,0 +1,49 @@ +package getter + +import ( + "compress/gzip" + "fmt" + "io" + "os" + "path/filepath" +) + +// GzipDecompressor is an implementation of Decompressor that can +// decompress bz2 files. +type GzipDecompressor struct{} + +func (d *GzipDecompressor) Decompress(dst, src string, dir bool) error { + // Directory isn't supported at all + if dir { + return fmt.Errorf("gzip-compressed files can only unarchive to a single file") + } + + // If we're going into a directory we should make that first + if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil { + return err + } + + // File first + f, err := os.Open(src) + if err != nil { + return err + } + defer f.Close() + + // gzip compression is second + gzipR, err := gzip.NewReader(f) + if err != nil { + return err + } + defer gzipR.Close() + + // Copy it out + dstF, err := os.Create(dst) + if err != nil { + return err + } + defer dstF.Close() + + _, err = io.Copy(dstF, gzipR) + return err +} diff --git a/vendor/github.com/hashicorp/go-getter/decompress_tbz2.go b/vendor/github.com/hashicorp/go-getter/decompress_tbz2.go new file mode 100644 index 000000000..c46ed4453 --- /dev/null +++ b/vendor/github.com/hashicorp/go-getter/decompress_tbz2.go @@ -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 + } + } +} diff --git a/vendor/github.com/hashicorp/go-getter/decompress_testing.go b/vendor/github.com/hashicorp/go-getter/decompress_testing.go new file mode 100644 index 000000000..5821ed66e --- /dev/null +++ b/vendor/github.com/hashicorp/go-getter/decompress_testing.go @@ -0,0 +1,121 @@ +package getter + +import ( + "crypto/md5" + "encoding/hex" + "io" + "io/ioutil" + "os" + "path/filepath" + "reflect" + "sort" + "strings" + "testing" +) + +// TestDecompressCase is a single test case for testing decompressors +type TestDecompressCase struct { + Input string // Input is the complete path to the input file + Dir bool // Dir is whether or not we're testing directory mode + Err bool // Err is whether we expect an error or not + DirList []string // DirList is the list of files for Dir mode + FileMD5 string // FileMD5 is the expected MD5 for a single file +} + +// TestDecompressor is a helper function for testing generic decompressors. +func TestDecompressor(t *testing.T, d Decompressor, cases []TestDecompressCase) { + for _, tc := range cases { + t.Logf("Testing: %s", tc.Input) + + // Temporary dir to store stuff + td, err := ioutil.TempDir("", "getter") + if err != nil { + t.Fatalf("err: %s", err) + } + + // Destination is always joining result so that we have a new path + dst := filepath.Join(td, "subdir", "result") + + // We use a function so defers work + func() { + defer os.RemoveAll(td) + + // Decompress + err := d.Decompress(dst, tc.Input, tc.Dir) + if (err != nil) != tc.Err { + t.Fatalf("err %s: %s", tc.Input, err) + } + if tc.Err { + return + } + + // If it isn't a directory, then check for a single file + if !tc.Dir { + fi, err := os.Stat(dst) + if err != nil { + t.Fatalf("err %s: %s", tc.Input, err) + } + if fi.IsDir() { + t.Fatalf("err %s: expected file, got directory", tc.Input) + } + if tc.FileMD5 != "" { + actual := testMD5(t, dst) + expected := tc.FileMD5 + if actual != expected { + t.Fatalf("err %s: expected MD5 %s, got %s", tc.Input, expected, actual) + } + } + + return + } + + // Directory, check for the correct contents + actual := testListDir(t, dst) + expected := tc.DirList + if !reflect.DeepEqual(actual, expected) { + t.Fatalf("bad %s\n\n%#v\n\n%#v", tc.Input, actual, expected) + } + }() + } +} + +func testListDir(t *testing.T, path string) []string { + var result []string + err := filepath.Walk(path, func(sub string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + sub = strings.TrimPrefix(sub, path) + if sub == "" { + return nil + } + sub = sub[1:] // Trim the leading path sep. + + result = append(result, sub) + return nil + }) + if err != nil { + t.Fatalf("err: %s", err) + } + + sort.Strings(result) + return result +} + +func testMD5(t *testing.T, path string) string { + f, err := os.Open(path) + if err != nil { + t.Fatalf("err: %s", err) + } + defer f.Close() + + h := md5.New() + _, err = io.Copy(h, f) + if err != nil { + t.Fatalf("err: %s", err) + } + + result := h.Sum(nil) + return hex.EncodeToString(result) +} diff --git a/vendor/github.com/hashicorp/go-getter/decompress_tgz.go b/vendor/github.com/hashicorp/go-getter/decompress_tgz.go new file mode 100644 index 000000000..391bbc0ad --- /dev/null +++ b/vendor/github.com/hashicorp/go-getter/decompress_tgz.go @@ -0,0 +1,99 @@ +package getter + +import ( + "archive/tar" + "compress/gzip" + "fmt" + "io" + "os" + "path/filepath" +) + +// TarGzipDecompressor is an implementation of Decompressor that can +// decompress tar.gzip files. +type TarGzipDecompressor struct{} + +func (d *TarGzipDecompressor) 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() + + // Gzip compression is second + gzipR, err := gzip.NewReader(f) + if err != nil { + return fmt.Errorf("Error opening a gzip reader for %s: %s", src, err) + } + defer gzipR.Close() + + // Once gzip decompressed we have a tar format + tarR := tar.NewReader(gzipR) + 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 + } + } +} diff --git a/vendor/github.com/hashicorp/go-getter/decompress_zip.go b/vendor/github.com/hashicorp/go-getter/decompress_zip.go new file mode 100644 index 000000000..0e4f6d739 --- /dev/null +++ b/vendor/github.com/hashicorp/go-getter/decompress_zip.go @@ -0,0 +1,87 @@ +package getter + +import ( + "archive/zip" + "fmt" + "io" + "os" + "path/filepath" +) + +// ZipDecompressor is an implementation of Decompressor that can +// decompress tar.gzip files. +type ZipDecompressor struct{} + +func (d *ZipDecompressor) 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 + } + + // Open the zip + zipR, err := zip.OpenReader(src) + if err != nil { + return err + } + defer zipR.Close() + + // Check the zip integrity + if len(zipR.File) == 0 { + // Empty archive + return fmt.Errorf("empty archive: %s", src) + } + if !dir && len(zipR.File) > 1 { + return fmt.Errorf("expected a single file: %s", src) + } + + // Go through and unarchive + for _, f := range zipR.File { + path := dst + if dir { + path = filepath.Join(path, f.Name) + } + + if f.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 + } + + // Open the file for reading + srcF, err := f.Open() + if err != nil { + return err + } + + // Open the file for writing + dstF, err := os.Create(path) + if err != nil { + srcF.Close() + return err + } + _, err = io.Copy(dstF, srcF) + srcF.Close() + dstF.Close() + if err != nil { + return err + } + + // Chmod the file + if err := os.Chmod(path, f.Mode()); err != nil { + return err + } + } + + return nil +} diff --git a/vendor/github.com/hashicorp/go-getter/test-fixtures/archive.tar.gz b/vendor/github.com/hashicorp/go-getter/test-fixtures/archive.tar.gz new file mode 100644 index 000000000..999e5fc9d Binary files /dev/null and b/vendor/github.com/hashicorp/go-getter/test-fixtures/archive.tar.gz differ diff --git a/vendor/github.com/hashicorp/go-getter/test-fixtures/basic-file-archive/archive.tar.gz b/vendor/github.com/hashicorp/go-getter/test-fixtures/basic-file-archive/archive.tar.gz new file mode 100644 index 000000000..23133d887 Binary files /dev/null and b/vendor/github.com/hashicorp/go-getter/test-fixtures/basic-file-archive/archive.tar.gz differ diff --git a/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-bz2/single.bz2 b/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-bz2/single.bz2 new file mode 100644 index 000000000..63d21a073 Binary files /dev/null and b/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-bz2/single.bz2 differ diff --git a/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-gz/single.gz b/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-gz/single.gz new file mode 100644 index 000000000..00754d02d Binary files /dev/null and b/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-gz/single.gz differ diff --git a/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-tbz2/empty.tar.bz2 b/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-tbz2/empty.tar.bz2 new file mode 100644 index 000000000..a70463740 Binary files /dev/null and b/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-tbz2/empty.tar.bz2 differ diff --git a/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-tbz2/multiple.tar.bz2 b/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-tbz2/multiple.tar.bz2 new file mode 100644 index 000000000..1d59e6ad2 Binary files /dev/null and b/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-tbz2/multiple.tar.bz2 differ diff --git a/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-tbz2/single.tar.bz2 b/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-tbz2/single.tar.bz2 new file mode 100644 index 000000000..115f9a4ae Binary files /dev/null and b/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-tbz2/single.tar.bz2 differ diff --git a/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-tgz/empty.tar.gz b/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-tgz/empty.tar.gz new file mode 100644 index 000000000..ad184e904 Binary files /dev/null and b/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-tgz/empty.tar.gz differ diff --git a/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-tgz/multiple.tar.gz b/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-tgz/multiple.tar.gz new file mode 100644 index 000000000..400123957 Binary files /dev/null and b/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-tgz/multiple.tar.gz differ diff --git a/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-tgz/single.tar.gz b/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-tgz/single.tar.gz new file mode 100644 index 000000000..921bdacc6 Binary files /dev/null and b/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-tgz/single.tar.gz differ diff --git a/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-zip/empty.zip b/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-zip/empty.zip new file mode 100644 index 000000000..15cb0ecb3 Binary files /dev/null and b/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-zip/empty.zip differ diff --git a/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-zip/multiple.zip b/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-zip/multiple.zip new file mode 100644 index 000000000..a032181d4 Binary files /dev/null and b/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-zip/multiple.zip differ diff --git a/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-zip/single.zip b/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-zip/single.zip new file mode 100644 index 000000000..90687fde1 Binary files /dev/null and b/vendor/github.com/hashicorp/go-getter/test-fixtures/decompress-zip/single.zip differ