- package Archive
-
- import (
- "archive/tar"
- "bufio"
- "bytes"
- "compress/gzip"
- "io"
- "io/fs"
- "os"
- "path/filepath"
- )
-
- func ExtractArchive(source, target string) error {
- var (
- inFile *os.File
- gzipReader *gzip.Reader
- tarReader *tar.Reader
- e error
- )
-
- inFile, e = os.Open(source)
- if e != nil {
- return e
- }
- defer inFile.Close()
-
- gzipReader, e = gzip.NewReader(inFile)
- defer gzipReader.Close()
- tarReader = tar.NewReader(gzipReader)
-
- return extractFromArchive(tarReader, target)
- }
-
- func extractFromArchive(tarReader *tar.Reader, target string) error {
- var (
- header *tar.Header
- info fs.FileInfo
- file *os.File
- path, basePath string
- e error
- )
-
- for {
- header, e = tarReader.Next()
- if e == io.EOF {
- break
- }
- if e != nil {
- return e
- }
-
- path = filepath.Join(target, header.Name)
-
- info = header.FileInfo()
- if filepath.Base(info.Name()) == "manifest.yml" {
- continue
- }
-
- if info.IsDir() {
- e = os.MkdirAll(path, info.Mode())
- if e != nil {
- return e
- }
- continue
- }
-
- basePath, e = filepath.Abs(filepath.Dir(path))
- if e != nil {
- return e
- }
-
- _, e = os.Stat(basePath)
- if os.IsNotExist(e) {
- e = os.MkdirAll(basePath, info.Mode())
- if e != nil {
- return e
- }
- }
-
- file, e = os.OpenFile(path, os.O_CREATE|os.O_RDWR, info.Mode())
- if e != nil {
- return e
- }
-
- defer file.Close()
-
- _, e = io.Copy(file, tarReader)
- if e != nil {
- return e
- }
- }
-
- return nil
-
- }
-
- func ExtractManifestFile(source string) (string, error) {
- var (
- inFile *os.File
- gzipReader *gzip.Reader
- tarReader *tar.Reader
- e error
- )
-
- inFile, e = os.Open(source)
- if e != nil {
- return "", e
- }
- defer inFile.Close()
-
- gzipReader, e = gzip.NewReader(inFile)
- defer gzipReader.Close()
- tarReader = tar.NewReader(gzipReader)
-
- return extractManifestFromArchive(tarReader)
- }
-
- func extractManifestFromArchive(tarReader *tar.Reader) (string, error) {
- var (
- header *tar.Header
- info fs.FileInfo
- manifestWriter *bufio.Writer
- manifestBytes bytes.Buffer
- e error
- )
-
- for {
- header, e = tarReader.Next()
- if e == io.EOF {
- break
- }
- if e != nil {
- return manifestBytes.String(), e
- }
-
- info = header.FileInfo()
- if filepath.Base(info.Name()) != "manifest.yml" {
- continue
- }
-
- manifestWriter = bufio.NewWriter(&manifestBytes)
-
- _, e = io.Copy(manifestWriter, tarReader)
- if e != nil {
- return manifestBytes.String(), e
- }
- }
-
- return manifestBytes.String(), nil
- }
|