package archive import ( "archive/tar" fp "path/filepath" "compress/gzip" "io" "os" "strings" ) // Extracts a tar arcive to the current working directory // This will overwrite everything. So be careful func UnTarFromFile(InputFile, compressionType string) error { r, err := os.Open(InputFile) if err != nil { return err } defer r.Close() return UnTar(r, compressionType) } func UnTar(r io.Reader, compressionType string) error { var treader *tar.Reader switch compressionType { case "gz": gzreader, err := gzip.NewReader(r) if err != nil { return err } // Read from the gzip reader instead of the file treader = tar.NewReader(gzreader) default: // Read from the file directly treader = tar.NewReader(r) } for { hdr, err := treader.Next() if err == io.EOF { // We've reached the end! Whoee break } if err != nil { return err } // Fix windows slashes... fileName := strings.Replace(hdr.Name, "\\", "/", -1) info := hdr.FileInfo() if info.IsDir() { // I don't like hard-coded permissions but it // it helps with overall platform compatibility if err = os.MkdirAll(fileName, 0775); err != nil { return err } continue } if err = os.MkdirAll(fp.Dir(fileName), 0775); err != nil { return err } // Create a file handle to work with // f, err := os.Create(fileName) f, err := os.OpenFile(fileName, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0664) if err != nil { return err } defer f.Close() if _, err := io.Copy(f, treader); err != nil { return err } } return nil }