- 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
- }
|