- 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
- err error
- )
-
- inFile, err = os.Open(source)
- if err != nil {
- return err
- }
- defer inFile.Close()
-
- gzipReader, err = gzip.NewReader(inFile)
- if err != nil {
- return err
- }
- 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
- err error
- )
-
- for {
- header, err = tarReader.Next()
- if err == io.EOF {
- break
- }
- if err != nil {
- return err
- }
-
- path = filepath.Join(target, header.Name)
-
- info = header.FileInfo()
- if filepath.Base(info.Name()) == "manifest.yml" {
- continue
- }
-
- if info.IsDir() {
- err = os.MkdirAll(path, info.Mode())
- if err != nil {
- return err
- }
- continue
- }
-
- basePath, err = filepath.Abs(filepath.Dir(path))
- if err != nil {
- return err
- }
-
- _, err = os.Stat(basePath)
- if os.IsNotExist(err) {
- err = os.MkdirAll(basePath, info.Mode())
- if err != nil {
- return err
- }
- }
-
- file, err = os.OpenFile(path, os.O_CREATE|os.O_RDWR, info.Mode())
- if err != nil {
- return err
- }
-
- _, err = io.Copy(file, tarReader)
- if err != nil {
- return err
- }
-
- file.Close()
- }
-
- return nil
-
- }
-
- func ExtractManifestFile(source string) (string, error) {
- var (
- inFile *os.File
- gzipReader *gzip.Reader
- tarReader *tar.Reader
- err error
- )
-
- inFile, err = os.Open(source)
- if err != nil {
- return "", err
- }
- defer inFile.Close()
-
- gzipReader, err = gzip.NewReader(inFile)
- if err != nil {
- return "", err
- }
- 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
- err error
- )
-
- for {
- header, err = tarReader.Next()
- if err == io.EOF {
- break
- }
- if err != nil {
- return manifestBytes.String(), err
- }
-
- info = header.FileInfo()
- if filepath.Base(info.Name()) != "manifest.yml" {
- continue
- }
-
- manifestWriter = bufio.NewWriter(&manifestBytes)
-
- _, err = io.Copy(manifestWriter, tarReader)
- if err != nil {
- return manifestBytes.String(), err
- }
- }
-
- return manifestBytes.String(), nil
- }
-
- func GetPackageFilePaths(source string) ([]string, error) {
- var (
- inFile *os.File
- gzipReader *gzip.Reader
- tarReader *tar.Reader
- info os.FileInfo
- header *tar.Header
- pkgFiles []string
- err error
- )
-
- inFile, err = os.Open(source)
- if err != nil {
- return pkgFiles, err
- }
- defer inFile.Close()
-
- gzipReader, err = gzip.NewReader(inFile)
- if err != nil {
- return pkgFiles, err
- }
- defer gzipReader.Close()
-
- tarReader = tar.NewReader(gzipReader)
-
- for {
- header, err = tarReader.Next()
- if err == io.EOF {
- break
- }
- if err != nil {
- return pkgFiles, err
- }
-
- info = header.FileInfo()
- if filepath.Base(info.Name()) == "manifest.yml" {
- continue
- }
-
- pkgFiles = append(pkgFiles, header.Name)
- }
-
- return pkgFiles, nil
- }
|