PackageManager just because
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

192 lines
3.2 KiB

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
}
func GetPackageFilePaths(source string) ([]string, error) {
var (
inFile *os.File
gzipReader *gzip.Reader
tarReader *tar.Reader
info os.FileInfo
header *tar.Header
pkgFiles []string
e error
)
inFile, e = os.Open(source)
if e != nil {
return pkgFiles, e
}
defer inFile.Close()
gzipReader, e = gzip.NewReader(inFile)
defer gzipReader.Close()
tarReader = tar.NewReader(gzipReader)
for {
header, e = tarReader.Next()
if e == io.EOF {
break
}
if e != nil {
return pkgFiles, e
}
info = header.FileInfo()
if filepath.Base(info.Name()) == "manifest.yml" {
continue
}
pkgFiles = append(pkgFiles, header.Name)
}
return pkgFiles, nil
}