package Archive
|
|
|
|
import (
|
|
"PackageManager/Variables"
|
|
"archive/tar"
|
|
"compress/gzip"
|
|
"io"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
func CreateArchive(files []string, target string) error {
|
|
var (
|
|
outFile *os.File
|
|
gzipWriter *gzip.Writer
|
|
tarWriter *tar.Writer
|
|
file string
|
|
err error
|
|
)
|
|
|
|
// Create output file
|
|
outFile, err = os.Create(target)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer outFile.Close()
|
|
|
|
gzipWriter = gzip.NewWriter(outFile)
|
|
defer gzipWriter.Close()
|
|
tarWriter = tar.NewWriter(gzipWriter)
|
|
defer tarWriter.Close()
|
|
|
|
// Iterate over files and add them to the tar archive
|
|
|
|
for _, file = range files {
|
|
err = addToArchive(tarWriter, file)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func addToArchive(tarWriter *tar.Writer, filename string) error {
|
|
var (
|
|
file *os.File
|
|
info os.FileInfo
|
|
header *tar.Header
|
|
err error
|
|
)
|
|
|
|
// Get FileInfo about our file providing file size, mode, etc.
|
|
info, err = os.Lstat(filename)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Create a tar Header from the FileInfo data
|
|
header, err = tar.FileInfoHeader(info, info.Name())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
isSymlink := info.Mode()&os.ModeSymlink != 0
|
|
if isSymlink {
|
|
header.Typeflag = tar.TypeSymlink
|
|
}
|
|
|
|
// Use full path as name (FileInfoHeader only takes the basename)
|
|
// If we don't do this the directory strucuture would
|
|
// not be preserved
|
|
// https://golang.org/src/archive/tar/common.go?#L626
|
|
header.Name = strings.TrimPrefix(
|
|
strings.TrimPrefix(
|
|
filename,
|
|
Variables.RootDir,
|
|
),
|
|
"/",
|
|
)
|
|
|
|
// Write file header to the tar archive
|
|
err = tarWriter.WriteHeader(header)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Do not write file if it is a symlink
|
|
if isSymlink {
|
|
return nil
|
|
}
|
|
|
|
// Open the file which will be written into the archive
|
|
file, err = os.Open(filename)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer file.Close()
|
|
|
|
// Copy file content to tar archive
|
|
_, err = io.Copy(tarWriter, file)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|