110 lines
2.4 KiB
Go
110 lines
2.4 KiB
Go
|
package util
|
||
|
|
||
|
import (
|
||
|
"archive/tar"
|
||
|
"io"
|
||
|
"io/fs"
|
||
|
"os"
|
||
|
"path/filepath"
|
||
|
|
||
|
"github.com/lbryio/lbry.go/v2/extras/errors"
|
||
|
)
|
||
|
|
||
|
func CreateTarball(tarballFilePath string, filePaths []string) error {
|
||
|
file, err := os.Create(tarballFilePath)
|
||
|
if err != nil {
|
||
|
return errors.Err("Could not create tarball file '%s', got error '%s'", tarballFilePath, err.Error())
|
||
|
}
|
||
|
defer file.Close()
|
||
|
|
||
|
tarWriter := tar.NewWriter(file)
|
||
|
defer tarWriter.Close()
|
||
|
|
||
|
for _, filePath := range filePaths {
|
||
|
err := addFileToTarWriter(filePath, tarWriter)
|
||
|
if err != nil {
|
||
|
return errors.Err("Could not add file '%s', to tarball, got error '%s'", filePath, err.Error())
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func addFileToTarWriter(filePath string, tarWriter *tar.Writer) error {
|
||
|
file, err := os.Open(filePath)
|
||
|
if err != nil {
|
||
|
return errors.Err("Could not open file '%s', got error '%s'", filePath, err.Error())
|
||
|
}
|
||
|
defer file.Close()
|
||
|
|
||
|
stat, err := file.Stat()
|
||
|
if err != nil {
|
||
|
return errors.Err("Could not get stat for file '%s', got error '%s'", filePath, err.Error())
|
||
|
}
|
||
|
|
||
|
header := &tar.Header{
|
||
|
Name: stat.Name(),
|
||
|
Size: stat.Size(),
|
||
|
Mode: int64(stat.Mode()),
|
||
|
ModTime: stat.ModTime(),
|
||
|
}
|
||
|
|
||
|
err = tarWriter.WriteHeader(header)
|
||
|
if err != nil {
|
||
|
return errors.Err("Could not write header for file '%s', got error '%s'", filePath, err.Error())
|
||
|
}
|
||
|
|
||
|
_, err = io.Copy(tarWriter, file)
|
||
|
if err != nil {
|
||
|
return errors.Err("Could not copy the file '%s' data to the tarball, got error '%s'", filePath, err.Error())
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func Untar(tarball, target string) error {
|
||
|
reader, err := os.Open(tarball)
|
||
|
if err != nil {
|
||
|
return errors.Err(err)
|
||
|
}
|
||
|
defer reader.Close()
|
||
|
tarReader := tar.NewReader(reader)
|
||
|
|
||
|
for {
|
||
|
header, err := tarReader.Next()
|
||
|
if err == io.EOF {
|
||
|
break
|
||
|
} else if err != nil {
|
||
|
return errors.Err(err)
|
||
|
}
|
||
|
|
||
|
path := filepath.Join(target, header.Name)
|
||
|
info := header.FileInfo()
|
||
|
if info.IsDir() {
|
||
|
if err = os.MkdirAll(path, info.Mode()); err != nil {
|
||
|
return errors.Err(err)
|
||
|
}
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
err = extractFile(path, info, tarReader)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func extractFile(path string, info fs.FileInfo, tarReader *tar.Reader) error {
|
||
|
file, err := os.OpenFile(path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, info.Mode())
|
||
|
if err != nil {
|
||
|
return errors.Err(err)
|
||
|
}
|
||
|
defer file.Close()
|
||
|
_, err = io.Copy(file, tarReader)
|
||
|
if err != nil {
|
||
|
return errors.Err(err)
|
||
|
}
|
||
|
return nil
|
||
|
}
|